Some of this applies to VULKAN too Separate post coming soon
I’ve been battling with OpenCL implementations for a while now. Has this ever happened to you:
So I had enough of this and wanted to dive deeper. Also I need to get CL working for my PhD work. This is going through Windows specific stuff, some logic will apply to Linux issues.
When you install a graphics driver or similar, this will install that vendors OpenCl implementation into your system. What happens when you have multiple Drivers installed? Things get Hairy.
Khronos came up with a solution to having multiple different versions and vendors of OpenCL on one system, they published a spec and code for a generic installable Client Driver.
Spec: khronos.org/registry/OpenCL/specs/2.2/html/OpenCL_ICD_Installation.html
Code: github.com/KhronosGroup/OpenCL-ICD-Loader
This should be the first call from your CL app. It has code within it so search around the system and report all the different implementations available to your app.
For this to work:
If 1 and 2 aren’t true, which is pretty common, you won’t see any or all of your devices at runtime. Here’s how to diagnose this:
You can get OpenCl dependencies from multiple places.
To build an opencl program you need the headders:
You also need the .Lib to link against
And then the runtime .dll
When you Launch an application, it needs to find the openCll.dll. This is where things get hairy.
CMAKE
If you use cmake to locate OpenCL for building your app: You can use the FindCL module , although I find it always ends at the CUDA install, which atm is rather outdated and only has headders for CL 1.2. You may want to find these things manually.
So if you are having trouble, here’s what you can do.
Visual studio Output window can show you which .dlls are being loaded:
You should see:
Nice, let’s go check that dll out
Ok. If you don’t see this and instead see, AMD/Nvidia/ something else. You may want to go compile the ICD yourself and replace this. Skip to ‘Roll your own ICD’ section.
Back to Visual studio, if everything is working. In my system I have both an Nvidia and AMD card, and I should see the following at some point:
If this is the case, fantastic. it means the ICD loaded first, then went and found and loaded the two other vendor’s CL implementation. My application reports the following:
So Above shows an ideal working situation, if you aren’t in this place, here’s some of the things that could have gone wrong, and an idiot-check list
So the ICD is open source, so you can compile it yourself, thankfully it’s straightforward.
why would you want to do this?
Here’s what saved my bacon. Get the code, build it, and modify loader/a/icd.h as
for
Now grab that new .dll and plonk it in the same folder as your app (or system32 if you want).
Run it and have a look at the console:
[TrcEvent] CL Init
KHR ICD trace at \loader\windows\icd_windows_dxgk.c:116: D3DKMT_QUERYADAPTERINFO status != SUCCESS
KHR ICD trace at \loader\windows\icd_windows.c:47: Failed to load via DXGK interface on RS4, continuing
KHR ICD trace at \loader\windows\icd_windows_hkr.c:277: Device ID: PCI\VEN_1002&DEV_699F&SUBSYS_05111043&REV_C7\4&10ee519c&0&001A
KHR ICD trace at \loader\windows\icd_windows_hkr.c:282: devinst: 1
KHR ICD trace at \loader\windows\icd_windows_hkr.c:295: Trying to look for the key in the display adapter HKR...
KHR ICD trace at \loader\windows\icd_windows_hkr.c:118: RegQueryValueExA, hkey:0x23c, lpValueName:OpenCLDriverName
KHR ICD trace at \loader\windows\icd_windows_hkr.c:132: lpType: 7, lpData: C:\Windows\System32\DriverStore\FileRepository\u0342855.inf_amd64_b40622b25c29110f\B342717\amdocl64.dll
KHR ICD trace at \loader\windows\icd_windows_hkr.c:140: Path: C:\Windows\System32\DriverStore\FileRepository\u0342855.inf_amd64_b40622b25c29110f\B342717\amdocl64.dll
KHR ICD trace at \loader\icd.c:50: attempting to add vendor C:\Windows\System32\DriverStore\FileRepository\u0342855.inf_amd64_b40622b25c29110f\B342717\amdocl64.dll...
KHR ICD trace at \loader\icd.c:176: successfully added vendor C:\Windows\System32\DriverStore\FileRepository\u0342855.inf_amd64_b40622b25c29110f\B342717\amdocl64.dll with suffix AMD
KHR ICD trace at \loader\windows\icd_windows_hkr.c:277: Device ID: PCI\VEN_10DE&DEV_1E04&SUBSYS_86751043&REV_A1\4&1da95f35&0&0019
KHR ICD trace at \loader\windows\icd_windows_hkr.c:282: devinst: 2
KHR ICD trace at \loader\windows\icd_windows_hkr.c:295: Trying to look for the key in the display adapter HKR...
KHR ICD trace at \loader\windows\icd_windows_hkr.c:118: RegQueryValueExA, hkey:0x23c, lpValueName:OpenCLDriverName
KHR ICD trace at \loader\windows\icd_windows_hkr.c:132: lpType: 1, lpData: C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_b49751b9038af669\nvopencl64.dll
KHR ICD trace at \loader\windows\icd_windows_hkr.c:140: Path: C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_b49751b9038af669\nvopencl64.dll
KHR ICD trace at \loader\icd.c:50: attempting to add vendor C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_b49751b9038af669\nvopencl64.dll...
KHR ICD trace at \loader\icd.c:176: successfully added vendor C:\Windows\System32\DriverStore\FileRepository\nv_dispi.inf_amd64_b49751b9038af669\nvopencl64.dll with suffix NV
KHR ICD trace at \loader\windows\icd_windows.c:54: Opening key HKLM\SOFTWARE\Khronos\OpenCL\Vendors...
KHR ICD trace at \loader\windows\icd_windows.c:77: Reading value 0...
KHR ICD trace at \loader\windows\icd_windows.c:90: Failed to read value 0, done reading key.
Beautiful, now you can get a good idea what is going on.
How is this useful
Well in a few cases now, I’ve not had AMD’s platform appear. Turns out this was because they weren’t following the ICD Spec and as such the ICD wouldn’t load it
Using this output I determined this and fixed it myself, and reported the issue to AMD who have now fixed that issue.
I now keep this dll in system32 for all my CL app to use, so I can keep an eye on things and spot if a driver update has borked things.
Other solutions
Go read the ICD spec, specifically how it finds the vendor platforms, then follow the steps yourself to see if anything is amiss. 9/10 times it’s a registry value that’s been (suspiciously) wiped