From 866963240086ec452fb311340d4596993ebd8473 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Mon, 13 Nov 2023 09:22:16 -0700 Subject: [PATCH 1/6] Working implementation of cl_khr_icd 2.0.0. --- icd_generator.rb | 98 +++++++++++++++++++++++++++++++++++++----------- ocl_icd_loader.c | 48 ++++++++++++++++-------- ocl_icd_loader.h | 61 +++++++++++++++++++++++++++++- 3 files changed, 170 insertions(+), 37 deletions(-) diff --git a/icd_generator.rb b/icd_generator.rb index c06c2b5..5eb3639 100644 --- a/icd_generator.rb +++ b/icd_generator.rb @@ -542,20 +542,15 @@ def self.generate_ocl_icd_loader_header clGetExtensionFunctionAddress_fn ext_fn_ptr; }; -struct platform_icd { - char * extension_suffix; - char * version; - struct vendor_icd *vicd; - cl_platform_id pid; - cl_uint ngpus; /* number of GPU devices */ - cl_uint ncpus; /* number of CPU devices */ - cl_uint ndevs; /* total number of devices, of all types */ -}; - +extern struct _cl_icd_dispatch master_dispatch; EOF - ocl_icd_header += "extern struct _cl_icd_dispatch master_dispatch;\n" $cl_objects.each { |o| - ocl_icd_header += "struct _cl_#{o} { struct _cl_icd_dispatch *dispatch; };\n" + ocl_icd_header += <#{e} = (typeof(#{e})*)pltfn_fn_ptr(pid, "#{e}"); + if (!dispatch->#{e}) + dispatch->#{e} = #{e}_unsupp; +EOF + else + ocl_icd_loader_gen_source << " dispatch->clUnknown#{i} = NULL;\n" + end + } + + ocl_icd_loader_gen_source << <ngpus = p->ncpus = p->ndevs = 0; - error = p->pid->dispatch->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_GPU, 0, NULL, &(p->ngpus)); + error = KHR_ICD2_DISPATCH(p->pid)->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_GPU, 0, NULL, &(p->ngpus)); if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND){ debug(D_WARN, "Error %s while counting GPU devices in platform %p", _clerror2string(error), p->pid); } - error = p->pid->dispatch->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_CPU, 0, NULL, &(p->ncpus)); + error = KHR_ICD2_DISPATCH(p->pid)->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_CPU, 0, NULL, &(p->ncpus)); if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND){ debug(D_WARN, "Error %s while counting CPU devices in platform %p", _clerror2string(error), p->pid); } - error = p->pid->dispatch->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_ALL, 0, NULL, &(p->ndevs)); + error = KHR_ICD2_DISPATCH(p->pid)->clGetDeviceIDs(p->pid, CL_DEVICE_TYPE_ALL, 0, NULL, &(p->ndevs)); if (error != CL_SUCCESS && error != CL_DEVICE_NOT_FOUND){ debug(D_WARN, "Error %s while counting ALL devices in platform %p", _clerror2string(error), p->pid); @@ -496,6 +496,10 @@ static inline void _find_and_check_platforms(cl_uint num_icds) { debug(D_WARN, "Not enough platform allocated. Skipping ICD"); continue; } +#ifdef CL_ICD2_TAG_KHR + clGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr = + _get_function_addr(dlh, picd->ext_fn_ptr, "clGetFunctionAddressForPlatformKHR"); +#endif for(j=0; jvicd=&_icds[i]; p->pid=platforms[j]; +#ifdef CL_ICD2_TAG_KHR + if (KHR_ICD2_HAS_TAG(p->pid) && !pltfn_fn_ptr) { + debug(D_WARN, "Found icd 2 platform, but it is missing clGetFunctionAddressForPlatformKHR, skipping it"); + continue; + } + + if (pltfn_fn_ptr && KHR_ICD2_HAS_TAG(p->pid)) + { + _populate_dispatch_table(p->pid, pltfn_fn_ptr, &p->disp_data.dispatch); + p->pid->disp_data = &p->disp_data; + debug(D_LOG, "Found icd 2 pltform, using loader managed dispatch"); + } +#endif + /* If clGetPlatformInfo is not exported and we are here, it * means that OCL_ICD_ASSUME_ICD_EXTENSION. Si we try to take it * from the dispatch * table. If that fails too, we have to * bail. */ if (plt_info_ptr == NULL) { - plt_info_ptr = p->pid->dispatch->clGetPlatformInfo; + plt_info_ptr = KHR_ICD2_DISPATCH(p->pid)->clGetPlatformInfo; if (plt_info_ptr == NULL) { debug(D_WARN, "Missing clGetPlatformInfo even in ICD dispatch table, skipping it"); continue; @@ -1176,8 +1194,8 @@ hidden_alias(clGetPlatformIDs); RETURN_WITH_ERRCODE(errcode_ret, CL_INVALID_PLATFORM, NULL); \ } \ } \ - RETURN(((struct _cl_platform_id *) properties[i+1]) \ - ->dispatch->clCreateContext(properties, num_devices, devices, \ + RETURN(KHR_ICD2_DISPATCH((struct _cl_platform_id *) properties[i+1]) \ + ->clCreateContext(properties, num_devices, devices, \ pfn_notify, user_data, errcode_ret)); \ } \ i += 2; \ @@ -1189,8 +1207,8 @@ hidden_alias(clGetPlatformIDs); if((struct _cl_device_id *)devices[0] == NULL) { \ RETURN_WITH_ERRCODE(errcode_ret, CL_INVALID_DEVICE, NULL); \ } \ - RETURN(((struct _cl_device_id *)devices[0]) \ - ->dispatch->clCreateContext(properties, num_devices, devices, \ + RETURN(KHR_ICD2_DISPATCH((struct _cl_device_id *)devices[0]) \ + ->clCreateContext(properties, num_devices, devices, \ pfn_notify, user_data, errcode_ret)); @@ -1239,15 +1257,15 @@ hidden_alias(clCreateContext); goto out; \ } \ } \ - return ((struct _cl_platform_id *) properties[i+1]) \ - ->dispatch->clCreateContextFromType(properties, device_type, \ + return KHR_ICD2_DISPATCH((struct _cl_platform_id *) properties[i+1]) \ + ->clCreateContextFromType(properties, device_type, \ pfn_notify, user_data, errcode_ret); \ } \ i += 2; \ } \ } else { \ cl_platform_id default_platform=getDefaultPlatformID(); \ - RETURN(default_platform->dispatch->clCreateContextFromType \ + RETURN(KHR_ICD2_DISPATCH(default_platform)->clCreateContextFromType \ (properties, device_type, pfn_notify, user_data, errcode_ret)); \ } \ out: \ @@ -1292,8 +1310,8 @@ hidden_alias(clCreateContextFromType); RETURN(CL_INVALID_PLATFORM); \ } \ } \ - RETURN(((struct _cl_platform_id *) properties[i+1]) \ - ->dispatch->clGetGLContextInfoKHR(properties, param_name, \ + RETURN(KHR_ICD2_DISPATCH((struct _cl_platform_id *) properties[i+1]) \ + ->clGetGLContextInfoKHR(properties, param_name, \ param_value_size, param_value, param_value_size_ret)); \ } \ i += 2; \ @@ -1333,8 +1351,8 @@ hidden_alias(clGetGLContextInfoKHR); RETURN(CL_INVALID_VALUE); \ if( (struct _cl_event *)event_list[0] == NULL ) \ RETURN(CL_INVALID_EVENT); \ - RETURN(((struct _cl_event *)event_list[0]) \ - ->dispatch->clWaitForEvents(num_events, event_list)); + RETURN(KHR_ICD2_DISPATCH((struct _cl_event *)event_list[0]) \ + ->clWaitForEvents(num_events, event_list)); __attribute__ ((visibility ("hidden"))) cl_int clWaitForEvents_disp(cl_uint num_events, diff --git a/ocl_icd_loader.h b/ocl_icd_loader.h index 6ebc823..0b96490 100644 --- a/ocl_icd_loader.h +++ b/ocl_icd_loader.h @@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ocl_icd.h" #include "ocl_icd_loader_gen.h" +#include cl_platform_id __attribute__((visibility("internal"))) getDefaultPlatformID(); @@ -73,6 +74,64 @@ struct layer_icd { #endif }; -__attribute__((visibility("hidden"))) extern struct layer_icd *_first_layer; + +#ifndef CL_ICD2_TAG_KHR + +#if SIZE_MAX == UINT64_MAX +#define CL_ICD2_TAG_KHR ((size_t)UINT64_C(0x4F50454E434C3331)) +#elif SIZE_MAX == UINT32_MAX +#define CL_ICD2_TAG_KHR ((size_t)UINT32_C(0x434C3331)) +#endif + +#ifdef CL_ICD2_TAG_KHR +typedef void * CL_API_CALL +clGetFunctionAddressForPlatformKHR_t( + cl_platform_id platform, + const char* function_name); + +typedef clGetFunctionAddressForPlatformKHR_t * +clGetFunctionAddressForPlatformKHR_fn; + +__attribute__((visibility("hidden"))) +extern void _populate_dispatch_table( + cl_platform_id platform, + clGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr, + struct _cl_icd_dispatch* dispatch); +#endif + +#endif + +#ifdef CL_ICD2_TAG_KHR +struct _cl_disp_data +{ + struct _cl_icd_dispatch dispatch; +}; + +#define KHR_ICD2_HAS_TAG(object) \ +(((size_t)((object)->dispatch->clGetPlatformIDs)) == CL_ICD2_TAG_KHR) + +#define KHR_ICD2_DISPATCH(object) \ +(KHR_ICD2_HAS_TAG(object) ? \ + &(object)->disp_data->dispatch : \ + (object)->dispatch) +#else +#define KHR_ICD2_DISPATCH(object) ((object)->dispatch) +#endif + +struct platform_icd { + char *extension_suffix; + char *version; + struct vendor_icd *vicd; + cl_platform_id pid; + cl_uint ngpus; /* number of GPU devices */ + cl_uint ncpus; /* number of CPU devices */ + cl_uint ndevs; /* total number of devices, of all types */ +#ifdef CL_ICD2_TAG_KHR + struct _cl_disp_data disp_data; +#endif +}; + +__attribute__((visibility("hidden"))) +extern struct layer_icd *_first_layer; #endif From d05b6f6f7af9edf85f7c246172bfa2ed8744767b Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Tue, 21 Nov 2023 16:34:35 -0600 Subject: [PATCH 2/6] Added clSetPlatformDispatchDataKHR function. --- ocl_icd_loader.c | 11 +++++++++-- ocl_icd_loader.h | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ocl_icd_loader.c b/ocl_icd_loader.c index 8d638e7..64c429a 100644 --- a/ocl_icd_loader.c +++ b/ocl_icd_loader.c @@ -499,6 +499,8 @@ static inline void _find_and_check_platforms(cl_uint num_icds) { #ifdef CL_ICD2_TAG_KHR clGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr = _get_function_addr(dlh, picd->ext_fn_ptr, "clGetFunctionAddressForPlatformKHR"); + clSetPlatformDispatchDataKHR_fn spltdd_fn_ptr = + _get_function_addr(dlh, picd->ext_fn_ptr, "clSetPlatformDispatchDataKHR"); #endif for(j=0; jpid)) + if (KHR_ICD2_HAS_TAG(p->pid) && !spltdd_fn_ptr) { + debug(D_WARN, "Found icd 2 platform, but it is missing clSetPlatformDispatchDataKHR, skipping it"); + continue; + } + + if (KHR_ICD2_HAS_TAG(p->pid)) { _populate_dispatch_table(p->pid, pltfn_fn_ptr, &p->disp_data.dispatch); - p->pid->disp_data = &p->disp_data; + spltdd_fn_ptr(p->pid, &p->disp_data); debug(D_LOG, "Found icd 2 pltform, using loader managed dispatch"); } #endif diff --git a/ocl_icd_loader.h b/ocl_icd_loader.h index 0b96490..463b968 100644 --- a/ocl_icd_loader.h +++ b/ocl_icd_loader.h @@ -92,6 +92,14 @@ clGetFunctionAddressForPlatformKHR_t( typedef clGetFunctionAddressForPlatformKHR_t * clGetFunctionAddressForPlatformKHR_fn; +typedef cl_int CL_API_CALL +clSetPlatformDispatchDataKHR_t( + cl_platform_id platform, + void *disp_data); + +typedef clSetPlatformDispatchDataKHR_t * +clSetPlatformDispatchDataKHR_fn; + __attribute__((visibility("hidden"))) extern void _populate_dispatch_table( cl_platform_id platform, From 7b8d68c6452217337499fc8ff34327a5f02152e9 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Tue, 21 Nov 2023 18:36:49 -0600 Subject: [PATCH 3/6] Simplify `CL_ICD2_TAG_KHR` definition. --- icd_generator.rb | 4 ---- ocl_icd_loader.c | 5 +---- ocl_icd_loader.h | 16 +--------------- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/icd_generator.rb b/icd_generator.rb index 5eb3639..8f2691e 100644 --- a/icd_generator.rb +++ b/icd_generator.rb @@ -828,9 +828,7 @@ def self.generate_ocl_icd_loader_gen_source ocl_icd_loader_gen_source += "));\n" ocl_icd_loader_gen_source += "}\n\n" } - ocl_icd_loader_gen_source += "#ifdef CL_ICD2_TAG_KHR\n" $api_entries.each &(api_stub) - ocl_icd_loader_gen_source += "#endif\n" $api_entries.each &(api_proc.curry[true]) $api_entries.each &(api_proc.curry[false]) ocl_icd_loader_gen_source += "#pragma GCC visibility push(hidden)\n\n" @@ -899,7 +897,6 @@ def self.generate_ocl_icd_loader_gen_source } #endif -#ifdef CL_ICD2_TAG_KHR void _populate_dispatch_table( cl_platform_id pid, clGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr, @@ -919,7 +916,6 @@ def self.generate_ocl_icd_loader_gen_source ocl_icd_loader_gen_source << <ext_fn_ptr, "clGetFunctionAddressForPlatformKHR"); clSetPlatformDispatchDataKHR_fn spltdd_fn_ptr = _get_function_addr(dlh, picd->ext_fn_ptr, "clSetPlatformDispatchDataKHR"); -#endif + for(j=0; jvicd=&_icds[i]; p->pid=platforms[j]; -#ifdef CL_ICD2_TAG_KHR if (KHR_ICD2_HAS_TAG(p->pid) && !pltfn_fn_ptr) { debug(D_WARN, "Found icd 2 platform, but it is missing clGetFunctionAddressForPlatformKHR, skipping it"); continue; @@ -527,7 +525,6 @@ static inline void _find_and_check_platforms(cl_uint num_icds) { spltdd_fn_ptr(p->pid, &p->disp_data); debug(D_LOG, "Found icd 2 pltform, using loader managed dispatch"); } -#endif /* If clGetPlatformInfo is not exported and we are here, it * means that OCL_ICD_ASSUME_ICD_EXTENSION. Si we try to take it diff --git a/ocl_icd_loader.h b/ocl_icd_loader.h index 463b968..b84b11c 100644 --- a/ocl_icd_loader.h +++ b/ocl_icd_loader.h @@ -76,14 +76,8 @@ struct layer_icd { #ifndef CL_ICD2_TAG_KHR +#define CL_ICD2_TAG_KHR ((size_t)0x4F50454E434C3331ULL) -#if SIZE_MAX == UINT64_MAX -#define CL_ICD2_TAG_KHR ((size_t)UINT64_C(0x4F50454E434C3331)) -#elif SIZE_MAX == UINT32_MAX -#define CL_ICD2_TAG_KHR ((size_t)UINT32_C(0x434C3331)) -#endif - -#ifdef CL_ICD2_TAG_KHR typedef void * CL_API_CALL clGetFunctionAddressForPlatformKHR_t( cl_platform_id platform, @@ -107,9 +101,6 @@ extern void _populate_dispatch_table( struct _cl_icd_dispatch* dispatch); #endif -#endif - -#ifdef CL_ICD2_TAG_KHR struct _cl_disp_data { struct _cl_icd_dispatch dispatch; @@ -122,9 +113,6 @@ struct _cl_disp_data (KHR_ICD2_HAS_TAG(object) ? \ &(object)->disp_data->dispatch : \ (object)->dispatch) -#else -#define KHR_ICD2_DISPATCH(object) ((object)->dispatch) -#endif struct platform_icd { char *extension_suffix; @@ -134,9 +122,7 @@ struct platform_icd { cl_uint ngpus; /* number of GPU devices */ cl_uint ncpus; /* number of CPU devices */ cl_uint ndevs; /* total number of devices, of all types */ -#ifdef CL_ICD2_TAG_KHR struct _cl_disp_data disp_data; -#endif }; __attribute__((visibility("hidden"))) From 6d64fa3d28f51b816256789fd1d133398c720860 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Tue, 28 Nov 2023 12:55:57 -0600 Subject: [PATCH 4/6] Replace `cl` prefix with `clIcd` prefix for new entry points. --- icd_generator.rb | 2 +- ocl_icd_loader.c | 12 ++++++------ ocl_icd_loader.h | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/icd_generator.rb b/icd_generator.rb index 8f2691e..31ee34d 100644 --- a/icd_generator.rb +++ b/icd_generator.rb @@ -899,7 +899,7 @@ def self.generate_ocl_icd_loader_gen_source void _populate_dispatch_table( cl_platform_id pid, - clGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr, + clIcdGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr, struct _cl_icd_dispatch *dispatch) { EOF ($api_entries.length+$buff).times { |i| diff --git a/ocl_icd_loader.c b/ocl_icd_loader.c index 636d9d6..43372ea 100644 --- a/ocl_icd_loader.c +++ b/ocl_icd_loader.c @@ -496,10 +496,10 @@ static inline void _find_and_check_platforms(cl_uint num_icds) { debug(D_WARN, "Not enough platform allocated. Skipping ICD"); continue; } - clGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr = - _get_function_addr(dlh, picd->ext_fn_ptr, "clGetFunctionAddressForPlatformKHR"); - clSetPlatformDispatchDataKHR_fn spltdd_fn_ptr = - _get_function_addr(dlh, picd->ext_fn_ptr, "clSetPlatformDispatchDataKHR"); + clIcdGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr = + _get_function_addr(dlh, picd->ext_fn_ptr, "clIcdGetFunctionAddressForPlatformKHR"); + clIcdSetPlatformDispatchDataKHR_fn spltdd_fn_ptr = + _get_function_addr(dlh, picd->ext_fn_ptr, "clIcdSetPlatformDispatchDataKHR"); for(j=0; jpid=platforms[j]; if (KHR_ICD2_HAS_TAG(p->pid) && !pltfn_fn_ptr) { - debug(D_WARN, "Found icd 2 platform, but it is missing clGetFunctionAddressForPlatformKHR, skipping it"); + debug(D_WARN, "Found icd 2 platform, but it is missing clIcdGetFunctionAddressForPlatformKHR, skipping it"); continue; } if (KHR_ICD2_HAS_TAG(p->pid) && !spltdd_fn_ptr) { - debug(D_WARN, "Found icd 2 platform, but it is missing clSetPlatformDispatchDataKHR, skipping it"); + debug(D_WARN, "Found icd 2 platform, but it is missing clIcdSetPlatformDispatchDataKHR, skipping it"); continue; } diff --git a/ocl_icd_loader.h b/ocl_icd_loader.h index b84b11c..55d77fe 100644 --- a/ocl_icd_loader.h +++ b/ocl_icd_loader.h @@ -79,25 +79,25 @@ struct layer_icd { #define CL_ICD2_TAG_KHR ((size_t)0x4F50454E434C3331ULL) typedef void * CL_API_CALL -clGetFunctionAddressForPlatformKHR_t( +clIcdGetFunctionAddressForPlatformKHR_t( cl_platform_id platform, const char* function_name); -typedef clGetFunctionAddressForPlatformKHR_t * -clGetFunctionAddressForPlatformKHR_fn; +typedef clIcdGetFunctionAddressForPlatformKHR_t * +clIcdGetFunctionAddressForPlatformKHR_fn; typedef cl_int CL_API_CALL -clSetPlatformDispatchDataKHR_t( +clIcdSetPlatformDispatchDataKHR_t( cl_platform_id platform, void *disp_data); -typedef clSetPlatformDispatchDataKHR_t * -clSetPlatformDispatchDataKHR_fn; +typedef clIcdSetPlatformDispatchDataKHR_t * +clIcdSetPlatformDispatchDataKHR_fn; __attribute__((visibility("hidden"))) extern void _populate_dispatch_table( cl_platform_id platform, - clGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr, + clIcdGetFunctionAddressForPlatformKHR_fn pltfn_fn_ptr, struct _cl_icd_dispatch* dispatch); #endif From f34826988760c1a87c42b791c93fa23a610b96c0 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Tue, 28 Nov 2023 14:37:43 -0600 Subject: [PATCH 5/6] Typo. --- ocl_icd_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocl_icd_loader.c b/ocl_icd_loader.c index 43372ea..54b1e08 100644 --- a/ocl_icd_loader.c +++ b/ocl_icd_loader.c @@ -523,7 +523,7 @@ static inline void _find_and_check_platforms(cl_uint num_icds) { { _populate_dispatch_table(p->pid, pltfn_fn_ptr, &p->disp_data.dispatch); spltdd_fn_ptr(p->pid, &p->disp_data); - debug(D_LOG, "Found icd 2 pltform, using loader managed dispatch"); + debug(D_LOG, "Found icd 2 platform, using loader managed dispatch"); } /* If clGetPlatformInfo is not exported and we are here, it From 6e908eb63b1e43d53ca96d3381458c46a709b15e Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Thu, 12 Sep 2024 23:36:30 -0500 Subject: [PATCH 6/6] Add second tag check in clUnloadCompiler pointer. --- ocl_icd_loader.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ocl_icd_loader.c b/ocl_icd_loader.c index 54b1e08..5074684 100644 --- a/ocl_icd_loader.c +++ b/ocl_icd_loader.c @@ -519,6 +519,11 @@ static inline void _find_and_check_platforms(cl_uint num_icds) { continue; } + if (KHR_ICD2_HAS_TAG(p->pid) && !(((size_t)((p->pid)->dispatch->clUnloadCompiler)) == CL_ICD2_TAG_KHR)) { + debug(D_WARN, "Found icd 2 platform, but it is missing clUnloadCompiler tag, skipping it"); + continue; + } + if (KHR_ICD2_HAS_TAG(p->pid)) { _populate_dispatch_table(p->pid, pltfn_fn_ptr, &p->disp_data.dispatch);