From 8aca62bf21929e5dd394090ae125b552c3929071 Mon Sep 17 00:00:00 2001 From: Mehdi GHESH Date: Sat, 13 Jul 2024 00:40:29 +0200 Subject: [PATCH] feat(ml): introduce support of onnxruntime-rocm for AMD GPU --- .github/workflows/docker.yml | 7 + docker/docker-compose.dev.yml | 4 +- docker/docker-compose.prod.yml | 4 +- docker/docker-compose.yml | 4 +- docker/hwaccel.ml.yml | 7 + .../docs/features/ml-hardware-acceleration.md | 9 +- docs/docs/guides/remote-machine-learning.md | 4 +- machine-learning/Dockerfile | 47 ++++- machine-learning/README.md | 4 +- machine-learning/app/models/constants.py | 2 +- machine-learning/app/sessions/ort.py | 2 +- machine-learning/poetry.lock | 2 +- machine-learning/pyproject.toml | 5 + machine-learning/rocm-PR19567.patch | 176 ++++++++++++++++++ 14 files changed, 261 insertions(+), 16 deletions(-) create mode 100644 machine-learning/rocm-PR19567.patch diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 659c39b029abef..5acc91ba6d773b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -38,6 +38,13 @@ jobs: device: cuda suffix: -cuda + - image: immich-machine-learning + context: machine-learning + file: machine-learning/Dockerfile + platforms: linux/amd64 + device: rocm + suffix: -rocm + - image: immich-machine-learning context: machine-learning file: machine-learning/Dockerfile diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index afe85ca4e0ab2c..303b153411b176 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -75,12 +75,12 @@ services: image: immich-machine-learning-dev:latest # extends: # file: hwaccel.ml.yml - # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference + # service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl] for accelerated inference build: context: ../machine-learning dockerfile: Dockerfile args: - - DEVICE=cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference + - DEVICE=cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl] for accelerated inference ports: - 3003:3003 volumes: diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml index 317d68e710f2dc..dc6cf791627a78 100644 --- a/docker/docker-compose.prod.yml +++ b/docker/docker-compose.prod.yml @@ -27,12 +27,12 @@ services: image: immich-machine-learning:latest # extends: # file: hwaccel.ml.yml - # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference + # service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl] for accelerated inference build: context: ../machine-learning dockerfile: Dockerfile args: - - DEVICE=cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference + - DEVICE=cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl] for accelerated inference volumes: - model-cache:/cache env_file: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index c5014a6eed33fb..c30378e169fbe5 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -29,12 +29,12 @@ services: immich-machine-learning: container_name: immich_machine_learning - # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. + # For hardware acceleration, add one of -[armnn, cuda, rocm, openvino] to the image tag. # Example tag: ${IMMICH_VERSION:-release}-cuda image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration # file: hwaccel.ml.yml - # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable + # service: cpu # set to one of [armnn, cuda, rocm, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable volumes: - model-cache:/cache env_file: diff --git a/docker/hwaccel.ml.yml b/docker/hwaccel.ml.yml index d9455d2bb766fd..ef336c52071d2c 100644 --- a/docker/hwaccel.ml.yml +++ b/docker/hwaccel.ml.yml @@ -26,6 +26,13 @@ services: capabilities: - gpu + rocm: + group_add: + - video + devices: + - /dev/dri:/dev/dri + - /dev/kfd:/dev/kfd + openvino: device_cgroup_rules: - 'c 189:* rmw' diff --git a/docs/docs/features/ml-hardware-acceleration.md b/docs/docs/features/ml-hardware-acceleration.md index 2bcb5ee8e84b19..0f01855893d813 100644 --- a/docs/docs/features/ml-hardware-acceleration.md +++ b/docs/docs/features/ml-hardware-acceleration.md @@ -11,6 +11,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele - ARM NN (Mali) - CUDA (NVIDIA GPUs with [compute capability](https://developer.nvidia.com/cuda-gpus) 5.2 or higher) +- ROCM (AMD GPUs) - OpenVINO (Intel discrete GPUs such as Iris Xe and Arc) ## Limitations @@ -40,6 +41,10 @@ You do not need to redo any machine learning jobs after enabling hardware accele - The installed driver must be >= 535 (it must support CUDA 12.2). - On Linux (except for WSL2), you also need to have [NVIDIA Container Toolkit][nvct] installed. +#### ROCM + +- The GPU must be supported by ROCM (or use `HSA_OVERRIDE_GFX_VERSION=`) + #### OpenVINO - The server must have a discrete GPU, i.e. Iris Xe or Arc. Expect issues when attempting to use integrated graphics. @@ -49,7 +54,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele 1. If you do not already have it, download the latest [`hwaccel.ml.yml`][hw-file] file and ensure it's in the same folder as the `docker-compose.yml`. 2. In the `docker-compose.yml` under `immich-machine-learning`, uncomment the `extends` section and change `cpu` to the appropriate backend. -3. Still in `immich-machine-learning`, add one of -[armnn, cuda, openvino] to the `image` section's tag at the end of the line. +3. Still in `immich-machine-learning`, add one of -[armnn, cuda, rocm, openvino] to the `image` section's tag at the end of the line. 4. Redeploy the `immich-machine-learning` container with these updated settings. #### Single Compose File @@ -95,7 +100,7 @@ immich-machine-learning: Once this is done, you can redeploy the `immich-machine-learning` container. :::info -You can confirm the device is being recognized and used by checking its utilization (via `nvtop` for CUDA, `intel_gpu_top` for OpenVINO, etc.). You can also enable debug logging by setting `IMMICH_LOG_LEVEL=debug` in the `.env` file and restarting the `immich-machine-learning` container. When a Smart Search or Face Detection job begins, you should see a log for `Available ORT providers` containing the relevant provider. In the case of ARM NN, the absence of a `Could not load ANN shared libraries` log entry means it loaded successfully. +You can confirm the device is being recognized and used by checking its utilization (via `nvtop` for CUDA, `radeontop` for ROCM, `intel_gpu_top` for OpenVINO, etc.). You can also enable debug logging by setting `IMMICH_LOG_LEVEL=debug` in the `.env` file and restarting the `immich-machine-learning` container. When a Smart Search or Face Detection job begins, you should see a log for `Available ORT providers` containing the relevant provider. In the case of ARM NN, the absence of a `Could not load ANN shared libraries` log entry means it loaded successfully. ::: [hw-file]: https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml diff --git a/docs/docs/guides/remote-machine-learning.md b/docs/docs/guides/remote-machine-learning.md index 30249cd9d12b8b..572106d4b3ab8e 100644 --- a/docs/docs/guides/remote-machine-learning.md +++ b/docs/docs/guides/remote-machine-learning.md @@ -20,12 +20,12 @@ name: immich_remote_ml services: immich-machine-learning: container_name: immich_machine_learning - # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. + # For hardware acceleration, add one of -[armnn, cuda, rocm, openvino] to the image tag. # Example tag: ${IMMICH_VERSION:-release}-cuda image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} # extends: # file: hwaccel.ml.yml - # service: # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable + # service: # set to one of [armnn, cuda, rocm, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable volumes: - model-cache:/cache restart: always diff --git a/machine-learning/Dockerfile b/machine-learning/Dockerfile index 1aea125a1460f0..44bac6ea4a602c 100644 --- a/machine-learning/Dockerfile +++ b/machine-learning/Dockerfile @@ -17,6 +17,40 @@ RUN mkdir /opt/armnn && \ cd /opt/ann && \ sh build.sh +# Warning: 57.2Gb of disk space required to pull this image +# https://github.com/microsoft/onnxruntime/blob/main/dockerfiles/Dockerfile.rocm +FROM rocm/dev-ubuntu-22.04:6.1.2-complete as builder-rocm + +WORKDIR /code + +RUN apt-get update && apt-get install -y --no-install-recommends wget git python3.10-venv +# Install same version as the Dockerfile provided by onnxruntime +RUN wget https://github.com/Kitware/CMake/releases/download/v3.27.3/cmake-3.27.3-linux-x86_64.sh && \ + chmod +x cmake-3.27.3-linux-x86_64.sh && \ + mkdir -p /code/cmake-3.27.3-linux-x86_64 && \ + ./cmake-3.27.3-linux-x86_64.sh --skip-license --prefix=/code/cmake-3.27.3-linux-x86_64 && \ + rm cmake-3.27.3-linux-x86_64.sh + +ENV PATH /code/cmake-3.27.3-linux-x86_64/bin:${PATH} + +# Prepare onnxruntime repository & build onnxruntime +RUN git clone --single-branch --branch v1.18.1 --recursive "https://github.com/Microsoft/onnxruntime" onnxruntime +WORKDIR /code/onnxruntime +# EDIT PR +# While there's still this PR open, we need to compile on the branch of the PR +# https://github.com/microsoft/onnxruntime/pull/19567 +COPY ./rocm-PR19567.patch /tmp/ +RUN git apply /tmp/rocm-PR19567.patch +# END EDIT PR +RUN /bin/sh ./dockerfiles/scripts/install_common_deps.sh +# I ran into a compilation error when parallelizing the build +# I used 12 threads to build onnxruntime, but it needs more than 16GB of RAM, and that's the amount of RAM I have on my machine +# I lowered the number of threads to 8, and it worked +# Even with 12 threads, the compilation took more than 1,5 hours to fail +RUN ./build.sh --allow_running_as_root --config Release --build_wheel --update --build --parallel 9 --cmake_extra_defines\ + ONNXRUNTIME_VERSION=1.18.1 --use_rocm --rocm_home=/opt/rocm +RUN mv /code/onnxruntime/build/Linux/Release/dist/*.whl /opt/ + FROM builder-${DEVICE} as builder ARG DEVICE @@ -34,6 +68,9 @@ RUN poetry config installer.max-workers 10 && \ RUN python3 -m venv /opt/venv COPY poetry.lock pyproject.toml ./ +RUN if [ "$DEVICE" = "rocm" ]; then \ + poetry add /opt/onnxruntime_rocm-*.whl; \ + fi RUN poetry install --sync --no-interaction --no-ansi --no-root --with ${DEVICE} --without dev FROM python:3.11-slim-bookworm@sha256:17ec9dc2367aa748559d0212f34665ec4df801129de32db705ea34654b5bc77a as prod-cpu @@ -70,10 +107,18 @@ COPY --from=builder-armnn \ /opt/ann/build.sh \ /opt/armnn/ +FROM rocm/dev-ubuntu-22.04:6.1.2-complete as prod-rocm + + FROM prod-${DEVICE} as prod +ARG DEVICE + RUN apt-get update && \ - apt-get install -y --no-install-recommends tini libmimalloc2.0 && \ + if [ "${DEVICE}" != "rocm" ]; then \ + extra=libmimalloc2.0; \ + fi && \ + apt-get install -y --no-install-recommends tini "${extra}" && \ rm -rf /var/lib/apt/lists/* WORKDIR /usr/src/app diff --git a/machine-learning/README.md b/machine-learning/README.md index d7d099a87ec510..47f929eb3bbe34 100644 --- a/machine-learning/README.md +++ b/machine-learning/README.md @@ -7,7 +7,7 @@ This project uses [Poetry](https://python-poetry.org/docs/#installation), so be sure to install it first. Running `poetry install --no-root --with dev --with cpu` will install everything you need in an isolated virtual environment. -CUDA and OpenVINO are supported as acceleration APIs. To use them, you can replace `--with cpu` with either of `--with cuda` or `--with openvino`. In the case of CUDA, a [compute capability](https://developer.nvidia.com/cuda-gpus) of 5.2 or higher is required. +CUDA, ROCM and OpenVINO are supported as acceleration APIs. To use them, you can replace `--with cpu` with either of `--with cuda`, `--with rocm` or `--with openvino`. In the case of CUDA, a [compute capability](https://developer.nvidia.com/cuda-gpus) of 5.2 or higher is required. To add or remove dependencies, you can use the commands `poetry add $PACKAGE_NAME` and `poetry remove $PACKAGE_NAME`, respectively. Be sure to commit the `poetry.lock` and `pyproject.toml` files with `poetry lock --no-update` to reflect any changes in dependencies. @@ -37,4 +37,4 @@ This project utilizes facial recognition models from the [InsightFace](https://g ## License and Use Restrictions We have received permission to use the InsightFace facial recognition models in our project, as granted via email by Jia Guo (guojia@insightface.ai) on 18th March 2023. However, it's important to note that this permission does not extend to the redistribution or commercial use of their models by third parties. Users and developers interested in using these models should review the licensing terms provided in the InsightFace GitHub repository. -For more information on the capabilities of the InsightFace models and to ensure compliance with their license, please refer to their [official repository](https://github.com/deepinsight/insightface). Adhering to the specified licensing terms is crucial for the respectful and lawful use of their work. \ No newline at end of file +For more information on the capabilities of the InsightFace models and to ensure compliance with their license, please refer to their [official repository](https://github.com/deepinsight/insightface). Adhering to the specified licensing terms is crucial for the respectful and lawful use of their work. diff --git a/machine-learning/app/models/constants.py b/machine-learning/app/models/constants.py index c51dd3b66de153..caa66166e61912 100644 --- a/machine-learning/app/models/constants.py +++ b/machine-learning/app/models/constants.py @@ -52,7 +52,7 @@ } -SUPPORTED_PROVIDERS = ["CUDAExecutionProvider", "OpenVINOExecutionProvider", "CPUExecutionProvider"] +SUPPORTED_PROVIDERS = ["CUDAExecutionProvider", "ROCMExecutionProvider", "OpenVINOExecutionProvider", "CPUExecutionProvider"] def get_model_source(model_name: str) -> ModelSource | None: diff --git a/machine-learning/app/sessions/ort.py b/machine-learning/app/sessions/ort.py index dfa2f8417ca6d3..e2d79cdd3862bd 100644 --- a/machine-learning/app/sessions/ort.py +++ b/machine-learning/app/sessions/ort.py @@ -86,7 +86,7 @@ def _provider_options_default(self) -> list[dict[str, Any]]: options = [] for provider in self.providers: match provider: - case "CPUExecutionProvider" | "CUDAExecutionProvider": + case "CPUExecutionProvider" | "CUDAExecutionProvider"| "ROCMExecutionProvider": option = {"arena_extend_strategy": "kSameAsRequested"} case "OpenVINOExecutionProvider": option = {"device_type": "GPU_FP32", "cache_dir": (self.model_path.parent / "openvino").as_posix()} diff --git a/machine-learning/poetry.lock b/machine-learning/poetry.lock index 2d53c924e14d5b..9e7d167548aff3 100644 --- a/machine-learning/poetry.lock +++ b/machine-learning/poetry.lock @@ -3583,4 +3583,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<4.0" -content-hash = "df9afeda50e05cb62b322a047028a9b0851db197c4f379903c70adab3a98777a" +content-hash = "5f1575ab19f60841c05dde2f5b4f73d780caadc1dec1a2d9c584383a43f05f6a" diff --git a/machine-learning/pyproject.toml b/machine-learning/pyproject.toml index f4fe33cd1d9125..cafaef7adc7b46 100644 --- a/machine-learning/pyproject.toml +++ b/machine-learning/pyproject.toml @@ -47,6 +47,11 @@ optional = true [tool.poetry.group.cuda.dependencies] onnxruntime-gpu = {version = "^1.17.0", source = "cuda12"} +[tool.poetry.group.rocm] +optional = true + +[tool.poetry.group.rocm.dependencies] + [tool.poetry.group.openvino] optional = true diff --git a/machine-learning/rocm-PR19567.patch b/machine-learning/rocm-PR19567.patch new file mode 100644 index 00000000000000..fac3189821ed22 --- /dev/null +++ b/machine-learning/rocm-PR19567.patch @@ -0,0 +1,176 @@ +From a598a88db258f82a6e4bca75810921bd6bcee7e0 Mon Sep 17 00:00:00 2001 +From: David Nieto +Date: Sat, 17 Feb 2024 11:23:12 -0800 +Subject: [PATCH] Disable algo caching in ROCM EP + +Similar to the work done by Liangxijun-1001 in +https://github.com/apache/tvm/pull/16178 the ROCM spec mandates calling +miopenFindConvolution*Algorithm() before using any Convolution API + +This is the link to the porting guide describing this requirement +https://rocmdocs.amd.com/projects/MIOpen/en/latest/MIOpen_Porting_Guide.html + +Thus, this change disables the algo cache and enforces the official +API semantics + +Signed-off-by: David Nieto +--- + onnxruntime/core/providers/rocm/nn/conv.cc | 61 +++++++++---------- + onnxruntime/core/providers/rocm/nn/conv.h | 6 -- + .../core/providers/rocm/nn/conv_transpose.cc | 16 +++-- + 3 files changed, 36 insertions(+), 47 deletions(-) + +diff --git a/onnxruntime/core/providers/rocm/nn/conv.cc b/onnxruntime/core/providers/rocm/nn/conv.cc +index 6214ec7bc0ea..b08aceca48b1 100644 +--- a/onnxruntime/core/providers/rocm/nn/conv.cc ++++ b/onnxruntime/core/providers/rocm/nn/conv.cc +@@ -125,10 +125,8 @@ Status Conv::UpdateState(OpKernelContext* context, bool bias_expected) + if (input_dims_changed) + s_.last_x_dims = gsl::make_span(x_dims); + +- if (w_dims_changed) { ++ if (w_dims_changed) + s_.last_w_dims = gsl::make_span(w_dims); +- s_.cached_benchmark_fwd_results.clear(); +- } + + ORT_RETURN_IF_ERROR(conv_attrs_.ValidateInputShape(X->Shape(), W->Shape(), channels_last, channels_last)); + +@@ -277,35 +275,6 @@ Status Conv::UpdateState(OpKernelContext* context, bool bias_expected) + HIP_CALL_THROW(hipMalloc(&s_.b_zero, malloc_size)); + HIP_CALL_THROW(hipMemsetAsync(s_.b_zero, 0, malloc_size, Stream(context))); + } +- +- if (!s_.cached_benchmark_fwd_results.contains(x_dims_miopen)) { +- miopenConvAlgoPerf_t perf; +- int algo_count = 1; +- const ROCMExecutionProvider* rocm_ep = static_cast(this->Info().GetExecutionProvider()); +- static constexpr int num_algos = MIOPEN_CONVOLUTION_FWD_ALGO_COUNT; +- size_t max_ws_size = rocm_ep->GetMiopenConvUseMaxWorkspace() ? GetMaxWorkspaceSize(GetMiopenHandle(context), s_, kAllAlgos, num_algos) +- : AlgoSearchWorkspaceSize; +- IAllocatorUniquePtr algo_search_workspace = GetTransientScratchBuffer(max_ws_size); +- MIOPEN_RETURN_IF_ERROR(miopenFindConvolutionForwardAlgorithm( +- GetMiopenHandle(context), +- s_.x_tensor, +- s_.x_data, +- s_.w_desc, +- s_.w_data, +- s_.conv_desc, +- s_.y_tensor, +- s_.y_data, +- 1, // requestedAlgoCount +- &algo_count, // returnedAlgoCount +- &perf, +- algo_search_workspace.get(), +- max_ws_size, +- false)); // Do not do exhaustive algo search. +- s_.cached_benchmark_fwd_results.insert(x_dims_miopen, {perf.fwd_algo, perf.memory}); +- } +- const auto& perf = s_.cached_benchmark_fwd_results.at(x_dims_miopen); +- s_.fwd_algo = perf.fwd_algo; +- s_.workspace_bytes = perf.memory; + } else { + // set Y + s_.Y = context->Output(0, TensorShape(s_.y_dims)); +@@ -319,6 +288,34 @@ Status Conv::UpdateState(OpKernelContext* context, bool bias_expected) + s_.y_data = reinterpret_cast(s_.Y->MutableData()); + } + } ++ { ++ /* FindConvolution must always be called by the runtime */ ++ TensorShapeVector x_dims_miopen{x_dims.begin(), x_dims.end()}; ++ miopenConvAlgoPerf_t perf; ++ int algo_count = 1; ++ const ROCMExecutionProvider* rocm_ep = static_cast(this->Info().GetExecutionProvider()); ++ static constexpr int num_algos = MIOPEN_CONVOLUTION_FWD_ALGO_COUNT; ++ size_t max_ws_size = rocm_ep->GetMiopenConvUseMaxWorkspace() ? GetMaxWorkspaceSize(GetMiopenHandle(context), s_, kAllAlgos, num_algos) ++ : AlgoSearchWorkspaceSize; ++ IAllocatorUniquePtr algo_search_workspace = GetTransientScratchBuffer(max_ws_size); ++ MIOPEN_RETURN_IF_ERROR(miopenFindConvolutionForwardAlgorithm( ++ GetMiopenHandle(context), ++ s_.x_tensor, ++ s_.x_data, ++ s_.w_desc, ++ s_.w_data, ++ s_.conv_desc, ++ s_.y_tensor, ++ s_.y_data, ++ 1, // requestedAlgoCount ++ &algo_count, // returnedAlgoCount ++ &perf, ++ algo_search_workspace.get(), ++ max_ws_size, ++ false)); // Do not do exhaustive algo search. ++ s_.fwd_algo = perf.fwd_algo; ++ s_.workspace_bytes = perf.memory; ++ } + return Status::OK(); + } + +diff --git a/onnxruntime/core/providers/rocm/nn/conv.h b/onnxruntime/core/providers/rocm/nn/conv.h +index bc9846203e57..d54218f25854 100644 +--- a/onnxruntime/core/providers/rocm/nn/conv.h ++++ b/onnxruntime/core/providers/rocm/nn/conv.h +@@ -108,9 +108,6 @@ class lru_unordered_map { + list_type lru_list_; + }; + +-// cached miopen descriptors +-constexpr size_t MAX_CACHED_ALGO_PERF_RESULTS = 10000; +- + template + struct MiopenConvState { + // if x/w dims changed, update algo and miopenTensors +@@ -148,9 +145,6 @@ struct MiopenConvState { + decltype(AlgoPerfType().memory) memory; + }; + +- lru_unordered_map cached_benchmark_fwd_results{MAX_CACHED_ALGO_PERF_RESULTS}; +- lru_unordered_map cached_benchmark_bwd_results{MAX_CACHED_ALGO_PERF_RESULTS}; +- + // Some properties needed to support asymmetric padded Conv nodes + bool post_slicing_required; + TensorShapeVector slice_starts; +diff --git a/onnxruntime/core/providers/rocm/nn/conv_transpose.cc b/onnxruntime/core/providers/rocm/nn/conv_transpose.cc +index 7447113fdf84..45ed4c8ac37a 100644 +--- a/onnxruntime/core/providers/rocm/nn/conv_transpose.cc ++++ b/onnxruntime/core/providers/rocm/nn/conv_transpose.cc +@@ -76,7 +76,6 @@ Status ConvTranspose::DoConvTranspose(OpKernelContext* context, bool dy + + if (w_dims_changed) { + s_.last_w_dims = gsl::make_span(w_dims); +- s_.cached_benchmark_bwd_results.clear(); + } + + ConvTransposeAttributes::Prepare p; +@@ -127,12 +126,13 @@ Status ConvTranspose::DoConvTranspose(OpKernelContext* context, bool dy + + y_data = reinterpret_cast(p.Y->MutableData()); + +- if (!s_.cached_benchmark_bwd_results.contains(x_dims)) { +- IAllocatorUniquePtr algo_search_workspace = GetScratchBuffer(AlgoSearchWorkspaceSize, context->GetComputeStream()); +- +- miopenConvAlgoPerf_t perf; +- int algo_count = 1; +- MIOPEN_RETURN_IF_ERROR(miopenFindConvolutionBackwardDataAlgorithm( ++ } ++ // The following is required before calling convolution, we cannot cache the results ++ { ++ IAllocatorUniquePtr algo_search_workspace = GetScratchBuffer(AlgoSearchWorkspaceSize, context->GetComputeStream()); ++ miopenConvAlgoPerf_t perf; ++ int algo_count = 1; ++ MIOPEN_RETURN_IF_ERROR(miopenFindConvolutionBackwardDataAlgorithm( + GetMiopenHandle(context), + s_.x_tensor, + x_data, +@@ -147,10 +147,7 @@ Status ConvTranspose::DoConvTranspose(OpKernelContext* context, bool dy + algo_search_workspace.get(), + AlgoSearchWorkspaceSize, + false)); +- s_.cached_benchmark_bwd_results.insert(x_dims, {perf.bwd_data_algo, perf.memory}); +- } + +- const auto& perf = s_.cached_benchmark_bwd_results.at(x_dims); + s_.bwd_data_algo = perf.bwd_data_algo; + s_.workspace_bytes = perf.memory; + }