问题核心:Hdevelop中可以用GPU呢,C#里面不得行
目录
我的开发工具环境:
- Hdevelop 23.11 Progress
- Microsoft Visual Studio Enterprise 2022 (64 位) - Current 版本 17.13.0
- .NET Framework 4.8
- Winform
问题描述:
在Hdevelop 23.11中,我使用深度学习,可以正常获取到GPU设备,正常用于目标检测,但是程序导出为C#后,不能正常使用了,C#里面无法获取到GPU设备
情况是,如下代码无法正常获取到GPU设备用于深度学习
HOperatorSet.QueryAvailableDlDevices((new HTuple("runtime")),
(new HTuple("gpu")), out hv_DLDeviceHandles);
经过查阅很多资料,都说安装的CUDA版本不一致;然后喊查下自己显卡支持的CUDA版本多少,我查了下我的显卡版本如下,使用命令 nvidia-smi,控制台里面执行
C:\Users\user1>nvidia-smi
Sat Mar 15 11:24:27 2025
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 546.33 Driver Version: 546.33 CUDA Version: 12.3 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name TCC/WDDM | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA GeForce RTX 2080 WDDM | 00000000:01:00.0 On | N/A |
| N/A 59C P5 24W / 150W | 1049MiB / 8192MiB | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| 0 N/A N/A 1088 C+G ...5n1h2txyewy\ShellExperienceHost.exe N/A |
| 0 N/A N/A 1832 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 2452 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 5260 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 7648 C+G ...2txyewy\StartMenuExperienceHost.exe N/A |
| 0 N/A N/A 8600 C+G ...nt.CBS_cw5n1h2txyewy\SearchHost.exe N/A |
| 0 N/A N/A 9780 C+G ...1\extracted\runtime\WeChatAppEx.exe N/A |
| 0 N/A N/A 12144 C+G ...CBS_cw5n1h2txyewy\TextInputHost.exe N/A |
| 0 N/A N/A 12348 C+G ...ekyb3d8bbwe\PhoneExperienceHost.exe N/A |
| 0 N/A N/A 13112 C+G ...crosoft\Edge\Application\msedge.exe N/A |
| 0 N/A N/A 13244 C+G ...crosoft\Edge\Application\msedge.exe N/A |
| 0 N/A N/A 14776 C+G ...on\133.0.3065.92\msedgewebview2.exe N/A |
| 0 N/A N/A 15052 C+G ..._x64__8wekyb3d8bbwe\WebViewHost.exe N/A |
| 0 N/A N/A 15444 C+G ...on\133.0.3065.92\msedgewebview2.exe N/A |
| 0 N/A N/A 18056 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 21044 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 21500 C+G ...cal\Microsoft\OneDrive\OneDrive.exe N/A |
| 0 N/A N/A 23088 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 23724 C+G ...t.LockApp_cw5n1h2txyewy\LockApp.exe N/A |
| 0 N/A N/A 24808 C+G C:\Windows\PrintDialog\PrintDialog.exe N/A |
| 0 N/A N/A 27504 C+G ...0305\office6\promecefpluginhost.exe N/A |
| 0 N/A N/A 28596 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 28636 C+G ...Progress\bin\x64-win64\hdevelop.exe N/A |
| 0 N/A N/A 29416 C+G ...siveControlPanel\SystemSettings.exe N/A |
| 0 N/A N/A 29608 C+G G:\ProgramInstall\QQNT\QQ.exe N/A |
| 0 N/A N/A 30936 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 30952 C+G ...on\133.0.3065.92\msedgewebview2.exe N/A |
| 0 N/A N/A 33028 C+G ...__8wekyb3d8bbwe\WindowsTerminal.exe N/A |
| 0 N/A N/A 38972 C+G ...BrowserEngine\BaiduNetdiskUnite.exe N/A |
| 0 N/A N/A 42016 C+G C:\Windows\explorer.exe N/A |
| 0 N/A N/A 42956 C+G C:\Windows\explorer.exe N/A |
+---------------------------------------------------------------------------------------+
C:\Users\user1>
然后为何Hdevelop 23.11 中可以呢,C#里面不得行;然后还有人喊把Hdevelop的bin目录加入系统环境变量中,其实我测试了都没用。我百思不得其解,我想应该是环境问题;
解决办法
将HALCON-23.11-Progress安装目录中的thirdparty整个文件夹复制到你winform程序的bin目录根目录中,就可以解决获取不到GPU问题了,就可以正常获取了,因为thirdparty包括有CUDA文件夹的驱动dll文件。也不用去安装CUDA工具了,我都没有安装CUDA照样可以用GPU运行深度学习
HDevelop里面的代码,检查GPU设备
cublas_version能获取到值,说明是正常可以使用GPU的;获取到-1或者false就是不对的;
*=============测试代码,在生产环境可注释=============
*检查CUDA是否加载
get_system ('cuda_loaded', cuda_is_loaded)
*检查CUDA版本是否≥12.1.0(12010)
get_system ('cuda_version', cuda_version)
*获取CUDA设备,显示显卡型号
get_system ('cuda_devices', cuda_devices)
*在c#中如下变量获取不到值,就表示不能正常使用GPU;
*可以获取值就能用GPU
get_system ('cudnn_loaded', Information4)
get_system ('cudnn_version', Information5)
get_system ('cublas_loaded', Information6)
get_system ('cublas_version', Information7)
*读取设备列表
* dev_open_window(0,0,512,512,'black',WindowHandle)
* set_display_font (WindowHandle, 22, 'mono', 'true', 'false')
* query_available_compute_devices(DeviceIdentifier)
* if(|DeviceIdentifier| == 0)
* disp_message(WindowHandle, '没有找到gpu', 'window', 12, 12, 'black', 'white')
* else
* disp_message(WindowHandle, '设备显卡个数'+|DeviceIdentifier|+'GPU', 'window', 12, 12, 'black', 'white')
* endif
*=============测试代码【结束】,可以生产环境可注释========
*
* Inference can be done on a GPU or CPU.
* See the respective system requirements in the Installation Guide.
* If possible a GPU is used in this example.
* In case you explicitly wish to run this example on the CPU,
* choose the CPU device instead.
query_available_dl_devices (['runtime', 'runtime'], ['gpu', 'cpu'], DLDeviceHandles)
if (|DLDeviceHandles| == 0)
throw ('No supported device found to continue this example.')
endif
* Due to the filter used in query_available_dl_devices, the first device is a GPU, if available.
*第一个设备是 GPU(如果可用)
DLDevice := DLDeviceHandles[0]
*
正确配置C#的Halcon深度学习环境,操作图示:
将thirdparty整个文件夹放入winform程序bin目录中,和程序exe在同级;
复制完成后,运行C#,发现可以读取到GPU的版本信息了,hv_DeviceIdentifier4这个值有具体的值,不是-1,就正常了,如果是-1则不能使用显卡。
获取GPU信息C#代码
//=============测试代码,可以生产环境可注释=============
HTuple hv_cuda_is_loaded = new HTuple(), hv_cuda_version = new HTuple();
HTuple hv_cuda_devices = new HTuple();
//检查CUDA是否加载
hv_cuda_is_loaded.Dispose();
HOperatorSet.GetSystem("cuda_loaded", out hv_cuda_is_loaded);
//检查CUDA版本是否≥12.1.0(12010)
hv_cuda_version.Dispose();
HOperatorSet.GetSystem("cuda_version", out hv_cuda_version);
//获取CUDA设备,显示显卡型号
hv_cuda_devices.Dispose();
HOperatorSet.GetSystem("cuda_devices", out hv_cuda_devices);
//读取设备列表
HTuple hv_DeviceIdentifier1 = new HTuple();
HTuple hv_DeviceIdentifier2 = new HTuple();
HTuple hv_DeviceIdentifier3 = new HTuple();
HTuple hv_DeviceIdentifier4 = new HTuple();
HOperatorSet.GetSystem("cudnn_loaded", out hv_DeviceIdentifier1);
HOperatorSet.GetSystem("cudnn_version", out hv_DeviceIdentifier2);
HOperatorSet.GetSystem("cublas_loaded", out hv_DeviceIdentifier3);
HOperatorSet.GetSystem("cublas_version", out hv_DeviceIdentifier4);
正常获取到GPU的图示: