Having trouble using GPU for detection

I am using the rust bindings for opencv, and I set the preferred backend and target and run detection like so:

                        match model.set_preferable_target(dnn::Target::DNN_TARGET_CUDA) {
                            Ok(_) => println!("Successfully set the preferable target to CUDA"),
                            Err(e) => println!("Failed to set the preferable target to CUDA: {}", e),
                        }
                    
                        match model.set_preferable_backend(dnn::Backend::DNN_BACKEND_CUDA) {
                            Ok(_) => println!("Successfully set the preferable backend to CUDA"),
                            Err(e) => println!("Failed to set the preferable backend to CUDA: {}", e),
                        }

                        // Perform detections
                        model.detect_def(
                            &frame,
                            &mut class_ids,
                            &mut confidences,
                            &mut boxes,
                        )?;

When I do so I get the below error. I compiled OPENCV with CUDA/CUDNN, and I have the below code that tests CUDA

Error: Error { code: "StsAssert, -215", message: "OpenCV(4.12.0-dev) C:\\tools\\opencv_head\\modules\\dnn\\src\\net_impl.cpp:120: error: (-215:Assertion failed) preferableBackend != DNN_BACKEND_CUDA || IS_DNN_CUDA_TARGET(preferableTarget) in function 'cv::dnn::dnn4_v20241223::Net::Impl::validateBackendAndTarget'\n" }

test code:

fn test_cuda() -> Result<(), Box<dyn std::error::Error>> {
    // Check if CUDA is available
    if !core::get_cuda_enabled_device_count().unwrap_or(0) > 0 {
        println!("CUDA is not available on this system.");
        return Ok(());
    }

    // Print CUDA device information
    let device_id = 0;
    core::set_device(device_id)?;
    let device = core::DeviceInfo::new(device_id)?;

    println!("CUDA Device: {}", device.name()?);
    println!("Compute Capability: {}.{}", device.major_version()?, device.minor_version()?);
    println!("Total Memory: {} MB", device.total_memory()? / (1024 * 1024));

    // Test a simple CUDA operation
    let src = core::Mat::zeros(10, 10, core::CV_8U)?;
    let mut gpu_mat = core::GpuMat::new_def()?;
    gpu_mat.upload(&src)?;

    let mut dst = core::GpuMat::new_def()?;
    opencv::cudaarithm::threshold_def(&gpu_mat, &mut dst, 128.0, 255.0, crate::imgproc::THRESH_BINARY)?;

    println!("CUDA support test passed.");

    Ok(())
}

Which prints:
CUDA Device: NVIDIA GeForce RTX 2080 Ti
Compute Capability: 7.5
Total Memory: 11263 MB
CUDA support test passed.

Can anyone help explain why setting the target is not working?

Looks like this might be the issue:

#if CV_CUDA4DNN
#ifndef HAVE_CUDA
#error “Configuration error: re-run CMake from clean build directory”
#endif
#else
#undef HAVE_CUDA
#endif

It is getting unset due to that.

Seems like OPENCV_DNN_CUDA wasn’t checked in cmake-gui :confused:

You can confirm whether OpenCV is going to be built against cuDNN by inspecting the CUDA section of the CMake configuration output, see below:

--   NVIDIA CUDA:                   YES (ver 12.5.40, CUFFT CUBLAS NVCUVID NVCUVENC)
--     NVIDIA GPU arch:             50 52 60 61 70 75 80 86 89 90
--     NVIDIA PTX archs:            90
--
--   cuDNN:                         YES (ver 9.2.0)