From 41d30395daabe253227bf96df68d8ba879f4f2b3 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Fri, 31 Jul 2026 22:25:00 +0200 Subject: [PATCH] fix(ort): CUDA detection was gated behind the TensorRT-EP build flag detect_ort_provider() only tested for CUDAExecutionProvider inside #ifdef SAE_ORT_WITH_TRT_EP, so any build that did not also opt into the TensorRT execution provider could never select CUDA and fell straight through to the CPU. The two are independent: the TRT EP needs the headers and profile plumbing and is rightly an opt-in, CUDA is a plain ORT provider and is not. The failure is silent rather than loud, which is why it survived -- inference runs on the CPU and every answer is still correct, just far slower. Measured on the VR-012 study: 0.32 s/crop against 0.0021 s/crop once a GPU backend is actually used, with the card sitting at 212 MiB and 0% utilisation throughout. Only the TensorrtExecutionProvider line stays inside the guard. --- src/backends/ort_provider.hpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/backends/ort_provider.hpp b/src/backends/ort_provider.hpp index 7f27c26..a420435 100644 --- a/src/backends/ort_provider.hpp +++ b/src/backends/ort_provider.hpp @@ -23,12 +23,23 @@ enum class OrtProvider { CPU, CUDA, ROCm, TensorRT }; inline OrtProvider detect_ort_provider() { + // ORT returns these in its own preference order (TensorRT, CUDA, ..., CPU + // last), so the first recognised entry is the best available and the loop + // returns on it. auto available = Ort::GetAvailableProviders(); for (const auto& p : available) { + // Only the TensorRT *EP* is a build-time opt-in — it needs the headers + // and the profile plumbing below. CUDA is not: it is a plain ORT + // provider, and gating its detection on the TRT flag (as this did) made + // the CUDA branch unreachable in every build that did not also ask for + // TensorRT. The symptom is silent rather than loud — inference simply + // runs on the CPU and everything still returns correct answers — which + // is why it survived: a 300-actor VR-012 grid cell took 76 s on the CPU + // with the GPU idle at 212 MiB. #ifdef SAE_ORT_WITH_TRT_EP if (p == "TensorrtExecutionProvider") return OrtProvider::TensorRT; - if (p == "CUDAExecutionProvider") return OrtProvider::CUDA; #endif + if (p == "CUDAExecutionProvider") return OrtProvider::CUDA; if (p == "ROCMExecutionProvider") return OrtProvider::ROCm; } return OrtProvider::CPU;