Problem
PR #250 added khrIcdDeinitialize() in DllMain(DLL_PROCESS_DETACH),
but this is called AFTER C++ global destructors (oneDNN, OpenVINO)
have already tried to use OpenCL objects. Results in CL_INVALID_OPERATION (-59).
Root Cause
On Windows, DllMain/FreeLibrary is called at the end of process shutdown,
but C++ static destructors run BEFORE that. When oneDNN tries to cleanup
its OpenCL engine, the ICD platform table is already cleared.
Reproduction
- Run any oneDNN/OpenVINO app with multi-GPU (NVL with 2+ tile)
- Process exits with CL_INVALID_OPERATION errors from clGetPlatformIDs
- Logs: src/xpu/ocl/utils_shared.cpp:199
Proposed Fix
Check lpvReserved in DllMain:
- lpvReserved == NULL -> FreeLibrary() call (WinML unload) → cleanup safe ✅
- lpvReserved != NULL -> process exit → skip cleanup ✅
if (reserved == NULL) {
khrIcdDeinitialize();
}
Note
This ONLY affects Windows. Linux/Unix don't have this issue
(dlclose happens after C++ destructors).
Problem
PR #250 added khrIcdDeinitialize() in DllMain(DLL_PROCESS_DETACH),
but this is called AFTER C++ global destructors (oneDNN, OpenVINO)
have already tried to use OpenCL objects. Results in CL_INVALID_OPERATION (-59).
Root Cause
On Windows, DllMain/FreeLibrary is called at the end of process shutdown,
but C++ static destructors run BEFORE that. When oneDNN tries to cleanup
its OpenCL engine, the ICD platform table is already cleared.
Reproduction
Proposed Fix
Check lpvReserved in DllMain:
if (reserved == NULL) {
khrIcdDeinitialize();
}
Note
This ONLY affects Windows. Linux/Unix don't have this issue
(dlclose happens after C++ destructors).