diff --git a/docker/rocm/Dockerfile b/docker/rocm/Dockerfile index 42447a26b..846037b31 100644 --- a/docker/rocm/Dockerfile +++ b/docker/rocm/Dockerfile @@ -2,7 +2,7 @@ # https://askubuntu.com/questions/972516/debian-frontend-environment-variable ARG DEBIAN_FRONTEND=noninteractive -ARG ROCM=1 +ARG ROCM ARG HSA_OVERRIDE_GFX_VERSION ARG HSA_OVERRIDE @@ -11,60 +11,104 @@ FROM wget AS rocm ARG ROCM -RUN apt update -qq && \ - apt install -y wget gpg && \ - wget -O rocm.deb https://repo.radeon.com/amdgpu-install/7.2/ubuntu/jammy/amdgpu-install_7.2.70200-1_all.deb && \ - apt install -y ./rocm.deb && \ - apt update && \ - apt install -qq -y rocm +# Install ROCm using repository +RUN apt update && apt install -qq -y wget gpg +RUN mkdir -p --mode=0755 /etc/apt/keyrings && \ + wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | gpg --dearmor | tee /etc/apt/keyrings/rocm.gpg > /dev/null +RUN echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/rocm/apt/$(echo "$ROCM" | sed -E 's/^([0-9]+\.[0-9]+)\.0$/\1/') jammy main" > /etc/apt/sources.list.d/rocm-$ROCM.list +RUN printf "Package: *\nPin: release o=repo.radeon.com\nPin-Priority: 600" > /etc/apt/preferences.d/rocm-pin-600 +# Install ROCm libraries +RUN apt update && \ + apt install -qq -y --no-install-recommends hipfft rocm-libs rocprofiler roctracer hip-dev + +# Install migraphx built with gfx900 included as a target +WORKDIR /tmp +RUN wget https://github.com/garymathews/AMDMIGraphX/releases/download/v7.2.0/migraphx-v7.2.0.tar.gz && \ + tar -xvzf migraphx-*.tar.gz -C /opt/rocm-$ROCM + +# Copy rocBLAS libraries for gfx900 from ROCm 6.3.4 (last version with gfx900 support) +WORKDIR /tmp +RUN apt install -qq -y --no-install-recommends rsync && \ + wget https://repo.radeon.com/rocm/apt/6.3.4/pool/main/r/rocblas/rocblas_4.3.0.60304-76~22.04_amd64.deb && \ + mkdir rocblas && \ + dpkg-deb -x rocblas_*.deb rocblas && \ + rsync -av \ + --include='*gfx900*' \ + --exclude='*' \ + rocblas/opt/rocm-*/lib/rocblas/library/ \ + /opt/rocm-$ROCM/lib/rocblas/library/ + +# Copy ROCm libraries RUN mkdir -p /opt/rocm-dist/opt/rocm-$ROCM/lib -RUN cd /opt/rocm-$ROCM/lib && \ - cp -dpr libMIOpen*.so* libamd*.so* libhip*.so* libhsa*.so* libmigraphx*.so* librocm*.so* librocblas*.so* libroctracer*.so* librocsolver*.so* librocfft*.so* librocprofiler*.so* libroctx*.so* librocroller.so* /opt/rocm-dist/opt/rocm-$ROCM/lib/ && \ - mkdir -p /opt/rocm-dist/opt/rocm-$ROCM/lib/migraphx/lib && \ - cp -dpr migraphx/lib/* /opt/rocm-dist/opt/rocm-$ROCM/lib/migraphx/lib -RUN cd /opt/rocm-dist/opt/ && ln -s rocm-$ROCM rocm +RUN cd /opt/rocm-$ROCM/lib && cp -dpr \ + libMIOpen*.so* \ + libamd*.so* \ + libhip*.so* \ + libhsa*.so* \ + librocblas*.so* \ + librocfft*.so* \ + librocm*.so* \ + librocprofiler*.so* \ + librocsolver*.so* \ + libroctracer*.so* \ + libroctx*.so* \ + libmigraphx*.so* \ + # NOTE: Include migraphx directory (only ROCm 6.2+) + migraphx \ + # NOTE: Include rocRoller library (only ROCm 7.0+) + librocroller*.so* \ + /opt/rocm-dist/opt/rocm-$ROCM/lib/ + +# Copy ROCm HIP include (only ROCm 7.2+) +RUN mkdir -p /opt/rocm-dist/opt/rocm-$ROCM/include +RUN cd /opt/rocm-$ROCM/include && cp -dpr \ + hip \ + /opt/rocm-dist/opt/rocm-$ROCM/include + +# Create symlink to /opt/rocm +RUN cd /opt/rocm-dist/opt && \ + ln -s rocm-$ROCM rocm RUN mkdir -p /opt/rocm-dist/etc/ld.so.conf.d/ -RUN echo /opt/rocm/lib|tee /opt/rocm-dist/etc/ld.so.conf.d/rocm.conf +RUN printf "/opt/rocm/lib\n/opt/rocm/lib/migraphx/lib" | tee /opt/rocm-dist/etc/ld.so.conf.d/rocm.conf +RUN printf "/usr/lib/llvm-14/lib" | tee /opt/rocm-dist/etc/ld.so.conf.d/llvm.conf ####################################################################### FROM deps AS deps-prelim COPY docker/rocm/debian-backports.sources /etc/apt/sources.list.d/debian-backports.sources -RUN apt-get update && \ - apt-get install -y libnuma1 && \ - apt-get install -qq -y -t bookworm-backports mesa-va-drivers mesa-vulkan-drivers && \ +RUN apt update && \ + # Install backported MESA VA and Vulkan drivers for video decoding acceleration + apt install -qq -y -t bookworm-backports mesa-va-drivers mesa-vulkan-drivers && \ # Install C++ standard library headers for HIPRTC kernel compilation fallback - apt-get install -qq -y libstdc++-12-dev && \ + apt install -qq -y libstdc++-12-dev libnuma1 && \ rm -rf /var/lib/apt/lists/* WORKDIR /opt/frigate COPY --from=rootfs / / -RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \ - && sed -i 's/args.append("setuptools")/args.append("setuptools==77.0.3")/' get-pip.py \ - && python3 get-pip.py "pip" --break-system-packages -RUN python3 -m pip config set global.break-system-packages true - +# Install onnxruntime built with ROCm COPY docker/rocm/requirements-wheels-rocm.txt /requirements.txt -RUN pip3 uninstall -y onnxruntime \ - && pip3 install -r /requirements.txt +RUN pip3 uninstall --break-system-packages -y onnxruntime && \ + pip3 install --break-system-packages -r /requirements.txt ####################################################################### FROM scratch AS rocm-dist ARG ROCM -# Copy HIP headers required for MIOpen JIT (BuildHip) / HIPRTC at runtime -COPY --from=rocm /opt/rocm-${ROCM}/include/ /opt/rocm-${ROCM}/include/ -COPY --from=rocm /opt/rocm-$ROCM/bin/rocminfo /opt/rocm-$ROCM/bin/migraphx-driver /opt/rocm-$ROCM/bin/ -# Copy MIOpen database files for gfx10xx and gfx11xx only (RDNA2/RDNA3) -COPY --from=rocm /opt/rocm-$ROCM/share/miopen/db/*gfx10* /opt/rocm-$ROCM/share/miopen/db/ -COPY --from=rocm /opt/rocm-$ROCM/share/miopen/db/*gfx11* /opt/rocm-$ROCM/share/miopen/db/ -# Copy rocBLAS library files for gfx10xx and gfx11xx only -COPY --from=rocm /opt/rocm-$ROCM/lib/rocblas/library/*gfx10* /opt/rocm-$ROCM/lib/rocblas/library/ -COPY --from=rocm /opt/rocm-$ROCM/lib/rocblas/library/*gfx11* /opt/rocm-$ROCM/lib/rocblas/library/ +# Copy MIOpen database files +COPY --from=rocm /opt/rocm-$ROCM/share/miopen/db/ /opt/rocm-$ROCM/share/miopen/db/ + +# Copy rocBLAS library files +# NOTE: Do not filter this copy to specific gfx versions, some fallback tensile libraries are necessary. +COPY --from=rocm /opt/rocm-$ROCM/lib/rocblas/library/ /opt/rocm-$ROCM/lib/rocblas/library/ + +# Copy ROCm binary files +COPY --from=rocm /opt/rocm-$ROCM/bin/ /opt/rocm-$ROCM/bin/ + +# Copy stripped ROCm COPY --from=rocm /opt/rocm-dist/ / ####################################################################### @@ -79,11 +123,10 @@ COPY --from=rocm-dist / / RUN ldconfig ####################################################################### -FROM rocm-prelim-hsa-override0 as rocm-prelim-hsa-override1 +FROM rocm-prelim-hsa-override0 AS rocm-prelim-hsa-override1 ARG HSA_OVERRIDE_GFX_VERSION ENV HSA_OVERRIDE_GFX_VERSION=$HSA_OVERRIDE_GFX_VERSION ####################################################################### FROM rocm-prelim-hsa-override$HSA_OVERRIDE as rocm-deps - diff --git a/frigate/detectors/detector_utils.py b/frigate/detectors/detector_utils.py index d732de871..5771f4dfa 100644 --- a/frigate/detectors/detector_utils.py +++ b/frigate/detectors/detector_utils.py @@ -1,5 +1,6 @@ import logging import os +import subprocess import numpy as np @@ -72,3 +73,35 @@ def tflite_load_delegate_interpreter( ) raise + +def detect_amd_gfx_id(): + return subprocess.getoutput("unset HSA_OVERRIDE_GFX_VERSION && /opt/rocm/bin/rocminfo 2>/dev/null | grep gfx | head -1 | awk '{print $2}'") + +def apply_amd_compatibility_env_vars(): + gfx_id = detect_amd_gfx_id() + if not gfx_id: + return + + logger.info(f"Setting AMD environment variables for {gfx_id} compatibility...") + + configs = { + ("gfx902", "gfx909", "gfx90c", "gfx1035", "gfx1103"): { + "HSA_ENABLE_SDMA": "0", # Disable System Direct Memory Access for APU compatibility + "MIGRAPHX_DISABLE_MIOPEN_FUSION": "1", # Disable unsupported fusion optimization + }, + ("gfx902", "gfx909", "gfx90c"): { # Vega + "HSA_OVERRIDE_GFX_VERSION": "9.0.0", # Force compatible GFX version + }, + ("gfx1035"): { # 680M + "HSA_OVERRIDE_GFX_VERSION": "10.3.0", # Force compatible GFX version + }, + ("gfx1103"): { # 780M + "HSA_OVERRIDE_GFX_VERSION": "11.0.0", # Force compatible GFX version + } + } + for gfx_ids, vars in configs.items(): + if gfx_id in gfx_ids: + for var, value in vars.items(): + if var not in os.environ: + os.environ[var] = value + logger.info(f" - \"{var}={value}\"") diff --git a/frigate/detectors/plugins/onnx.py b/frigate/detectors/plugins/onnx.py index 6c9e510ce..c2de62caf 100644 --- a/frigate/detectors/plugins/onnx.py +++ b/frigate/detectors/plugins/onnx.py @@ -5,11 +5,12 @@ from pydantic import Field from typing_extensions import Literal from frigate.detectors.detection_api import DetectionApi -from frigate.detectors.detection_runners import get_optimized_runner from frigate.detectors.detector_config import ( BaseDetectorConfig, ModelTypeEnum, ) +from frigate.detectors.detector_utils import apply_amd_compatibility_env_vars + from frigate.util.model import ( post_process_dfine, post_process_rfdetr, @@ -33,9 +34,14 @@ class ONNXDetector(DetectionApi): def __init__(self, detector_config: ONNXDetectorConfig): super().__init__(detector_config) + apply_amd_compatibility_env_vars() + path = detector_config.model.path logger.info(f"ONNX: loading {detector_config.model.path}") + # Import get_optimized_runner AFTER setting AMD compatibility env vars + from frigate.detectors.detection_runners import get_optimized_runner + self.runner = get_optimized_runner( path, detector_config.device,