Search code examples
visual-studioopencvgocmakegocv

How can I use gocv in Go with CUDA support on windows 11?


I want to use gocv in Go with CUDA support on windows 11. But when I run my Program, the task is only using the CPU.

This shows me this command.

nvidia-smi

No processes are found on GPU during executing my Go Code.

gocv is installed as described here and works properly. The instruction is not 100% correct, but I got it running.

Anyway, testing it with following command fails:

PS C:\...\cuda>go run .\main.go
# gocv.io/x/gocv/cuda
In file included from arithm.cpp:2:
arithm.h:9:10: fatal error: opencv2/cudaarithm.hpp: No such file or directory
 #include <opencv2/cudaarithm.hpp>
          ^~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

So after litte research I found this thread on github. I did the git clone and created my build directory. I changed the CMakeLists.txt

    set(OpenCV_DIR "C:/opencv/build")
    set(CUDA_TOOLKIT_ROOT_DIR "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.8")

I run cmake .. -G "Visual Studio 17 2022" and I got the cvglue.sln - File in my build directory.

This throws no error.

But when I build project INSTALL I get errors and it creates only "C:\opencv\cvglue_4.7.0\lib\gocv.lib".

During building the project in VS 2022 I got lot of errors like:

2>imgproc.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: __cdecl cv::Mat::~Mat(void)" (??1Mat@cv@@QEAA@XZ)".

Schweregrad Code    Beschreibung    Projekt Pfad    Datei   Zeile   Quelle  Unterdrückungszustand   Details
Fehler  LNK2001 Nicht aufgelöstes externes Symbol ""class cv::debug_build_guard::_InputOutputArray const & __cdecl cv::noArray(void)" (?noArray@cv@@YAAEBV_InputOutputArray@debug_build_guard@1@XZ)".   gocv    C:\opencv\build\install\gocv\cvglue\build\gocv  C:\opencv\build\install\gocv\cvglue\build\gocv\core.obj 1   Build

Is there any way to debug this? Does anybody know how to set include paths correctly?

Or was anybody able to run CUDA under windows in gocv and can give me instructions?

I tried to include the C:\opencv\build\install\include\opencv2 in VS but it did not change anything.


Solution

  • After lot of try and error and research I got it running!

    I want to share my procedure and give you detailed instructions:

    1. My Environment
    • Windows 11
    • NVIDIA GeForce RTX 4060 Laptop GPU
    • go1.22.2
    1. Requirements
    • Visual Studio 17 2022
    • CMake, latest stable Version. I had 3.29.3
    • NVIDIA CUDA Toolkit 12.3
    • cuDNN 8.9.7. Be sure, that you download the cuDNN for CUDA 12.x
    • Nvidia Video Codec SDK 12.2
    • OpenCV 4.9.0 Prebuild with CUDA. I was not able to build it from source. (Download it here). Download the opencv_contrib_cuda_4.9.0_win_amd64.7z

    Optional you can build OpenCV from source if you are able to. Maybe higher versions of NVIDIA tools are also possible, but I did not try it. It could be that OpenCV 4.9.0 needs CUDA 12.3 cuDNN 8.9.7

    1. Detailed Steps

    First I installed Visual Studio 17 2022 and CMake. There is nothing special.

    Then I run the NVIDIA Toolkit installer. After the installation, the toolkit should be installed in C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.3

    Copy the files from cuDNN\bin, \lib\x64 and \include to CUDA\v12.3\bin, lib\x64 and \include.Filestructure From the Nvidia Video Codec SDK I copied the files from Lib to lib and from Interface to include. Additionally I added the following Paths in my Environment:

    C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.3\include
    C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.3\lib\x64
    C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.3\bin
    

    It should look like this: Environment Variables

    Now it is time to add OpenCV. Run the follwing commands in a Command Prompt:

    cd C:\
    mkdir opencv
    cd C:\opencv
    mkdir build
    

    Extract the OpenCV 4.9.0 Prebuild opencv_contrib_cuda_4.9.0_win_amd64.7z to the build Directory.

    Extracted OpenCV

    Now let's add gocv.

    cd %GOPATH%\pkg\mod\github.com
    mkdir garfeng
    cd garfeng
    git clone https://github.com/garfeng/gocv.git
    cd gocv
    git checkout cuda_win
    cd cvglue/
    mkdir build 
    cd build
    

    Now make changes to the gocv\cvglue\CMakeLists.txt File Change the following two lines:

    set(OpenCV_DIR C:/opencv/4.6.0-cuda/3.5-8.6/) 
    set(CUDA_TOOLKIT_ROOT_DIR D:/cuda/) 
    

    To:

    set(OpenCV_DIR C:/opencv/build/x64/vc17/lib)
    set(CUDA_TOOLKIT_ROOT_DIR "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.3")
    

    Then run:

    cmake .. -G "Visual Studio 17 2022"
    

    This can throw following error:

    Could NOT find CUDAToolkit: Found unsuitable version "12.3.52", but required is exact version "12.3.103" (found C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v12.3/include)

    For workaround I opened

    C:\opencv\build\x64\vc17\lib\OpenCVConfig.cmake
    

    I changed

    set(OpenCV_CUDA_VERSION "12.3.103")
    

    To:

    set(OpenCV_CUDA_VERSION "12.3.52")
    

    And re-run cmake .. -G "Visual Studio 17 2022"

    CMake will Generate a Visual studio solution in the build dir. Open the cvglue.sln with VS, then build Release x64, build project INSTALL in the solution explorer.

    VS Build

    It will copy all of the dlls to dir C:/opencv/cvglue_4.7.0

    It takes some time to build. Rename the Folder only to cvglue

    /c/opencv/cvglue
    $ tree
    .
    ├── bin
    │   ├── gocv.dll
    │   ├── gocv_contrib.dll
    │   └── gocv_cuda.dll
    └── lib
        ├── gocv.lib
        ├── gocv_contrib.lib
        └── gocv_cuda.lib
    
    2 directories, 6 files
    

    Add the new created lib and bin folder to your environment paths as well.

    C:\opencv\cvglue\bin
    C:\opencv\cvglue\lib
    

    Environment Path

    Now it is time to validate.

    cd %GOPATH%\pkg\mod\github.com\garfeng\gocv\cmd\cuda
    go run main.go
    
    gocv version: 0.32.0
    cuda information:
      Device 0:  "NVIDIA GeForce RTX 4060 Laptop GPU"  8188Mb, sm_89, Driver/Runtime ver.12.50/12.30
    

    Usage Create your go project. Import gocv.io/x/gocv as usually. Add the following line to your go.mod

    replace gocv.io/x/gocv v0.36.1 => github.com/garfeng/gocv v0.31.5
    

    Maybe you have to rename \garfeng\gocv\

    To

    \garfeng\gocv@v0.31.5\

    That's it.

    References: https://github.com/garfeng/gocv/blob/cuda_win/UseCudaOnWindows.md