Skip to content

Commit 86448ce

Browse files
Kerilkbashbaug
andauthored
cl_khr_icd 2.0.0 loader managed dispatch (#238)
* Working cl_khr_icd 2.0.0. * Update CMakeLists.txt Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com> --------- Co-authored-by: Ben Ashbaugh <ben.ashbaugh@intel.com>
1 parent d547426 commit 86448ce

18 files changed

Lines changed: 3759 additions & 473 deletions

File tree

.github/workflows/presubmit.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,17 @@ jobs:
397397
$KEY_NAME = "HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors"
398398
foreach ($Config in 'Release','Debug') {
399399
$VALUE_NAME = "${env:GITHUB_WORKSPACE}/build/$Config/OpenCLDriverStub.dll"
400+
$VALUE_NAME_2 = "${env:GITHUB_WORKSPACE}/build/$Config/OpenCLDriverStubICD2.dll"
400401
& $REG ADD $KEY_NAME /v $VALUE_NAME /t REG_DWORD /d 0
402+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
403+
& $REG ADD $KEY_NAME /v $VALUE_NAME_2 /t REG_DWORD /d 0
404+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
401405
& ctest -C $Config --output-on-failure --no-tests=error --parallel ${env:NUMBER_OF_PROCESSORS}
402406
if ($LASTEXITCODE -ne 0) { throw "Testing OpenCL-ICD-Loader in $Config failed." }
407+
& $REG DELETE $KEY_NAME /v $VALUE_NAME_2 /f
408+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
403409
& $REG DELETE $KEY_NAME /v $VALUE_NAME /f
410+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
404411
}
405412
406413
- name: Install
@@ -429,8 +436,11 @@ jobs:
429436
$REG = if('${{matrix.BIN}}' -eq 'x64') {"reg"} else {"${env:SystemRoot}\Syswow64\reg.exe"}
430437
$KEY_NAME = "HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors"
431438
$VALUE_NAME = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStub.dll"
439+
$VALUE_NAME_2 = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStubICD2.dll"
432440
& $REG ADD $KEY_NAME /v $VALUE_NAME /t REG_DWORD /d 0
433441
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
442+
& $REG ADD $KEY_NAME /v $VALUE_NAME_2 /t REG_DWORD /d 0
443+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
434444
foreach ($Config in 'Release','Debug') {
435445
& cmake `
436446
--build "${env:GITHUB_WORKSPACE}\downstream\pkgconfig\bare" `
@@ -442,6 +452,8 @@ jobs:
442452
}
443453
& $REG DELETE $KEY_NAME /v $VALUE_NAME /f
444454
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
455+
& $REG DELETE $KEY_NAME /v $VALUE_NAME_2 /f
456+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
445457
446458
- name: "Consume (Ninja-Multi-Config standalone): Configure/Build/Test"
447459
if: matrix.GEN == 'Ninja Multi-Config'
@@ -464,8 +476,11 @@ jobs:
464476
$REG = if('${{matrix.BIN}}' -eq 'x64') {"reg"} else {"${env:SystemRoot}\Syswow64\reg.exe"}
465477
$KEY_NAME = "HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors"
466478
$VALUE_NAME = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStub.dll"
479+
$VALUE_NAME_2 = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStubICD2.dll"
467480
& $REG ADD $KEY_NAME /v $VALUE_NAME /t REG_DWORD /d 0
468481
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
482+
& $REG ADD $KEY_NAME /v $VALUE_NAME_2 /t REG_DWORD /d 0
483+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
469484
foreach ($Config in 'Release','Debug') {
470485
& cmake `
471486
--build "${env:GITHUB_WORKSPACE}\downstream\pkgconfig\bare" `
@@ -477,6 +492,8 @@ jobs:
477492
}
478493
& $REG DELETE $KEY_NAME /v $VALUE_NAME /f
479494
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
495+
& $REG DELETE $KEY_NAME /v $VALUE_NAME_2 /f
496+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
480497
481498
- name: Consume (Emulate SDK presence)
482499
run: |
@@ -502,8 +519,11 @@ jobs:
502519
$REG = if('${{matrix.BIN}}' -eq 'x64') {"reg"} else {"${env:SystemRoot}\Syswow64\reg.exe"}
503520
$KEY_NAME = "HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors"
504521
$VALUE_NAME = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStub.dll"
522+
$VALUE_NAME_2 = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStubICD2.dll"
505523
& $REG ADD $KEY_NAME /v $VALUE_NAME /t REG_DWORD /d 0
506524
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
525+
& $REG ADD $KEY_NAME /v $VALUE_NAME_2 /t REG_DWORD /d 0
526+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
507527
foreach ($Config in 'Release','Debug') {
508528
& cmake `
509529
--build "${env:GITHUB_WORKSPACE}\downstream\pkgconfig\sdk" `
@@ -515,6 +535,8 @@ jobs:
515535
}
516536
& $REG DELETE $KEY_NAME /v $VALUE_NAME /f
517537
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
538+
& $REG DELETE $KEY_NAME /v $VALUE_NAME_2 /f
539+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
518540
519541
- name: "Consume (Ninja-Multi-Config SDK): Configure/Build/Test"
520542
if: matrix.GEN == 'Ninja Multi-Config'
@@ -537,8 +559,11 @@ jobs:
537559
$REG = if('${{matrix.BIN}}' -eq 'x64') {"reg"} else {"${env:SystemRoot}\Syswow64\reg.exe"}
538560
$KEY_NAME = "HKEY_LOCAL_MACHINE\SOFTWARE\Khronos\OpenCL\Vendors"
539561
$VALUE_NAME = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStub.dll"
562+
$VALUE_NAME_2 = "${env:GITHUB_WORKSPACE}/build/Release/OpenCLDriverStubICD2.dll"
540563
& $REG ADD $KEY_NAME /v $VALUE_NAME /t REG_DWORD /d 0
541564
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
565+
& $REG ADD $KEY_NAME /v $VALUE_NAME_2 /t REG_DWORD /d 0
566+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
542567
foreach ($Config in 'Release','Debug') {
543568
& cmake `
544569
--build "${env:GITHUB_WORKSPACE}\downstream\pkgconfig\sdk" `
@@ -550,6 +575,8 @@ jobs:
550575
}
551576
& $REG DELETE $KEY_NAME /v $VALUE_NAME /f
552577
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
578+
& $REG DELETE $KEY_NAME /v $VALUE_NAME_2 /f
579+
if ($LASTEXITCODE -ne 0) { throw "Editing registry failed." }
553580
554581
macos:
555582
runs-on: macos-latest

CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ option(OPENCL_ICD_LOADER_BUILD_SHARED_LIBS "Build OpenCL ICD Loader as shared li
5252
# It is currently needed default while the specification is being formalized,
5353
# and to study the performance impact.
5454
option (ENABLE_OPENCL_LAYERS "Enable OpenCL Layers" ON)
55+
option (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH "Enable OpenCL Loader managed dispatch" ON)
5556
include(CMakeDependentOption)
5657
cmake_dependent_option(ENABLE_OPENCL_LAYERINFO "Enable building cllayerinfo tool" ON ENABLE_OPENCL_LAYERS OFF)
5758

@@ -68,6 +69,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/loader/icd_cmake_config.h.in
6869
${CMAKE_CURRENT_BINARY_DIR}/icd_cmake_config.h)
6970

7071
set (OPENCL_ICD_LOADER_SOURCES
72+
include/cl_khr_icd2.h
7173
loader/icd.c
7274
loader/icd.h
7375
loader/icd_version.h
@@ -76,6 +78,7 @@ set (OPENCL_ICD_LOADER_SOURCES
7678
loader/icd_dispatch_generated.c
7779
loader/icd_envvars.h
7880
loader/icd_platform.h)
81+
include_directories (include)
7982

8083
if (WIN32)
8184
list (APPEND OPENCL_ICD_LOADER_SOURCES
@@ -159,8 +162,9 @@ set (OPENCL_COMPILE_DEFINITIONS
159162
CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES
160163
OPENCL_ICD_LOADER_VERSION_MAJOR=3
161164
OPENCL_ICD_LOADER_VERSION_MINOR=0
162-
OPENCL_ICD_LOADER_VERSION_REV=6
165+
OPENCL_ICD_LOADER_VERSION_REV=7
163166
$<$<BOOL:${ENABLE_OPENCL_LAYERS}>:CL_ENABLE_LAYERS>
167+
$<$<BOOL:${ENABLE_OPENCL_LOADER_MANAGED_DISPATCH}>:CL_ENABLE_LOADER_MANAGED_DISPATCH>
164168
)
165169

166170
target_compile_definitions (OpenCL

include/cl_khr_icd2.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2016-2025 The Khronos Group Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* OpenCL is a trademark of Apple Inc. used under license by Khronos.
17+
*/
18+
19+
#if !defined(CL_ICD2_TAG_KHR)
20+
#if INTPTR_MAX == INT32_MAX
21+
#define CL_ICD2_TAG_KHR ((intptr_t)0x434C3331)
22+
#else
23+
#define CL_ICD2_TAG_KHR ((intptr_t)0x4F50454E434C3331)
24+
#endif
25+
26+
typedef void * CL_API_CALL
27+
clIcdGetFunctionAddressForPlatformKHR_t(
28+
cl_platform_id platform,
29+
const char* func_name);
30+
31+
typedef clIcdGetFunctionAddressForPlatformKHR_t *
32+
clIcdGetFunctionAddressForPlatformKHR_fn;
33+
34+
typedef cl_int CL_API_CALL
35+
clIcdSetPlatformDispatchDataKHR_t(
36+
cl_platform_id platform,
37+
void *disp_data);
38+
39+
typedef clIcdSetPlatformDispatchDataKHR_t *
40+
clIcdSetPlatformDispatchDataKHR_fn;
41+
#endif // !defined(CL_ICD2_TAG_KHR)

loader/icd.c

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ void khrIcdVendorAdd(const char *libraryName)
5858
cl_int result = CL_SUCCESS;
5959
pfn_clGetExtensionFunctionAddress p_clGetExtensionFunctionAddress = NULL;
6060
pfn_clIcdGetPlatformIDs p_clIcdGetPlatformIDs = NULL;
61+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
62+
clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform = NULL;
63+
clIcdSetPlatformDispatchDataKHR_fn p_clIcdSetPlatformDispatchData = NULL;
64+
#endif
6165
cl_uint i = 0;
6266
cl_uint platformCount = 0;
6367
cl_platform_id *platforms = NULL;
@@ -104,6 +108,12 @@ void khrIcdVendorAdd(const char *libraryName)
104108
goto Done;
105109
}
106110

111+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
112+
// try to get clIcdGetFunctionAddressForPlatformKHR and clIcdSetPlatformDispatchDataKHR to detect cl_khr_icd2 support
113+
p_clIcdGetFunctionAddressForPlatform = (clIcdGetFunctionAddressForPlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdGetFunctionAddressForPlatformKHR");
114+
p_clIcdSetPlatformDispatchData = (clIcdSetPlatformDispatchDataKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdSetPlatformDispatchDataKHR");
115+
#endif
116+
107117
// query the number of platforms available and allocate space to store them
108118
result = p_clIcdGetPlatformIDs(0, NULL, &platformCount);
109119
if (CL_SUCCESS != result)
@@ -132,27 +142,68 @@ void khrIcdVendorAdd(const char *libraryName)
132142
char *suffix;
133143
size_t suffixSize;
134144

135-
// call clGetPlatformInfo on the returned platform to get the suffix
136-
if (!platforms[i])
145+
// skip NULL platforms and non dispatchable platforms
146+
if (!platforms[i] || !platforms[i]->dispatch)
147+
{
148+
continue;
149+
}
150+
151+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
152+
if (KHR_ICD2_HAS_TAG(platforms[i]) && !p_clIcdGetFunctionAddressForPlatform)
153+
{
154+
KHR_ICD_TRACE("found icd 2 object, but platform is missing clIcdGetFunctionAddressForPlatformKHR\n");
155+
continue;
156+
}
157+
if (KHR_ICD2_HAS_TAG(platforms[i]) && !p_clIcdSetPlatformDispatchData)
158+
{
159+
KHR_ICD_TRACE("found icd 2 object, but platform is missing clIcdSetPlatformDispatchDataKHR\n");
160+
continue;
161+
}
162+
if (KHR_ICD2_HAS_TAG(platforms[i]) && !((intptr_t)((platforms[i])->dispatch->clUnloadCompiler) == CL_ICD2_TAG_KHR))
163+
{
164+
KHR_ICD_TRACE("found icd 2 object, but platform is missing tag in clUnloadCompiler\n");
165+
continue;
166+
}
167+
#endif
168+
169+
// allocate a structure for the vendor
170+
vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
171+
if (!vendor)
137172
{
173+
KHR_ICD_TRACE("failed to allocate memory\n");
138174
continue;
139175
}
140-
result = platforms[i]->dispatch->clGetPlatformInfo(
176+
memset(vendor, 0, sizeof(*vendor));
177+
178+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
179+
// populate cl_khr_icd2 platform's loader managed dispatch tables
180+
if (KHR_ICD2_HAS_TAG(platforms[i]))
181+
{
182+
khrIcd2PopulateDispatchTable(platforms[i], p_clIcdGetFunctionAddressForPlatform, &vendor->dispData.dispatch);
183+
p_clIcdSetPlatformDispatchData(platforms[i], &vendor->dispData);
184+
KHR_ICD_TRACE("found icd 2 platform, using loader managed dispatch\n");
185+
}
186+
#endif
187+
188+
// call clGetPlatformInfo on the returned platform to get the suffix
189+
result = KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
141190
platforms[i],
142191
CL_PLATFORM_ICD_SUFFIX_KHR,
143192
0,
144193
NULL,
145194
&suffixSize);
146195
if (CL_SUCCESS != result)
147196
{
197+
free(vendor);
148198
continue;
149199
}
150200
suffix = (char *)malloc(suffixSize);
151201
if (!suffix)
152202
{
203+
free(vendor);
153204
continue;
154205
}
155-
result = platforms[i]->dispatch->clGetPlatformInfo(
206+
result = KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
156207
platforms[i],
157208
CL_PLATFORM_ICD_SUFFIX_KHR,
158209
suffixSize,
@@ -161,19 +212,10 @@ void khrIcdVendorAdd(const char *libraryName)
161212
if (CL_SUCCESS != result)
162213
{
163214
free(suffix);
215+
free(vendor);
164216
continue;
165217
}
166218

167-
// allocate a structure for the vendor
168-
vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
169-
if (!vendor)
170-
{
171-
free(suffix);
172-
KHR_ICD_TRACE("failed to allocate memory\n");
173-
continue;
174-
}
175-
memset(vendor, 0, sizeof(*vendor) );
176-
177219
// populate vendor data
178220
vendor->library = khrIcdOsLibraryLoad(libraryName);
179221
if (!vendor->library)

loader/icd.h

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define _ICD_H_
2121

2222
#include "icd_platform.h"
23+
#include "icd_dispatch.h"
2324

2425
#ifndef CL_USE_DEPRECATED_OPENCL_1_0_APIS
2526
#define CL_USE_DEPRECATED_OPENCL_1_0_APIS
@@ -90,6 +91,11 @@ struct KHRicdVendorRec
9091
// the platform retrieved from clGetIcdPlatformIDsKHR
9192
cl_platform_id platform;
9293

94+
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
95+
// the loader populated dispatch table for cl_khr_icd2 compliant platforms
96+
struct KHRDisp dispData;
97+
#endif
98+
9399
// next vendor in the list vendors
94100
KHRicdVendor *next;
95101
};
@@ -201,11 +207,24 @@ do \
201207
#define KHR_ICD_WIDE_TRACE(...)
202208
#endif
203209

210+
#define KHR_ICD_ERROR_RETURN_ERROR(_error) \
211+
do { \
212+
return _error; \
213+
} while(0)
214+
215+
#define KHR_ICD_ERROR_RETURN_HANDLE(_error) \
216+
do { \
217+
if (errcode_ret) { \
218+
*errcode_ret = _error; \
219+
} \
220+
return NULL; \
221+
} while(0)
222+
204223
// Check if the passed-in handle is NULL, and if it is, return the error.
205224
#define KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(_handle, _error) \
206225
do { \
207226
if (!_handle) { \
208-
return _error; \
227+
KHR_ICD_ERROR_RETURN_ERROR(_error); \
209228
} \
210229
} while (0)
211230

@@ -214,10 +233,7 @@ do { \
214233
#define KHR_ICD_VALIDATE_HANDLE_RETURN_HANDLE(_handle, _error) \
215234
do { \
216235
if (!_handle) { \
217-
if (errcode_ret) { \
218-
*errcode_ret = _error; \
219-
} \
220-
return NULL; \
236+
KHR_ICD_ERROR_RETURN_HANDLE(_error); \
221237
} \
222238
} while (0)
223239

@@ -226,7 +242,7 @@ do { \
226242
#define KHR_ICD_VALIDATE_POINTER_RETURN_ERROR(_pointer) \
227243
do { \
228244
if (!_pointer) { \
229-
return CL_INVALID_OPERATION; \
245+
KHR_ICD_ERROR_RETURN_ERROR(CL_INVALID_OPERATION); \
230246
} \
231247
} while (0)
232248

@@ -236,10 +252,7 @@ do { \
236252
#define KHR_ICD_VALIDATE_POINTER_RETURN_HANDLE(_pointer) \
237253
do { \
238254
if (!_pointer) { \
239-
if (errcode_ret) { \
240-
*errcode_ret = CL_INVALID_OPERATION; \
241-
} \
242-
return NULL; \
255+
KHR_ICD_ERROR_RETURN_HANDLE(CL_INVALID_OPERATION); \
243256
} \
244257
} while (0)
245258

loader/icd_dispatch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ static inline void* clGetExtensionFunctionAddressForPlatform_body(
303303
// to get the extension function address.
304304

305305
KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(platform, NULL);
306-
return platform->dispatch->clGetExtensionFunctionAddressForPlatform(
306+
return KHR_ICD2_DISPATCH(platform)->clGetExtensionFunctionAddressForPlatform(
307307
platform,
308308
function_name);
309309
}

0 commit comments

Comments
 (0)