From 81fffbaebb6025726a482fba88ad2d8856b9d846 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Wed, 4 Sep 2024 16:29:43 -0500 Subject: [PATCH 1/2] Extension of cl_khr_icd to 2.0.0 with loader managed dispatch. --- api/cl_khr_icd.asciidoc | 59 +++++++++++++++++++++++++++++- api/opencl_platform_layer.asciidoc | 37 +++++++++++++++++++ scripts/gen_dictionaries.py | 2 +- xml/cl.xml | 26 ++++++++++++- 4 files changed, 121 insertions(+), 3 deletions(-) diff --git a/api/cl_khr_icd.asciidoc b/api/cl_khr_icd.asciidoc index 39d4125f3..f69aaa342 100644 --- a/api/cl_khr_icd.asciidoc +++ b/api/cl_khr_icd.asciidoc @@ -9,7 +9,7 @@ include::{generated}/meta/{refprefix}cl_khr_icd.txt[] === Other Extension Metadata *Last Modified Date*:: - 2020-04-21 + 2024-09-04 *IP Status*:: No known IP claims. @@ -48,6 +48,8 @@ An object is said to be ICD compatible if it is of the following structure: struct _cl_ { struct _cl_icd_dispatch *dispatch; + // Since version 2.0.0 + void *dispatch_data; // ... remainder of internal data }; ---- @@ -67,6 +69,13 @@ can be appended. Functions which do not have an argument from which the vendor implementation may be inferred have been deprecated and may be ignored. +New in version 2.0.0, object that are ICD 2 compatible should also contain +a `dispatch_data` field of type `void *` that the loader is free to modify +for a platform through the {clIcdSetPlatformDispatchDataKHR} new API entry +point. In order to distinguish ICD 1 and ICD 2 objects, the pointers to +`clGetPlatformIDs` and `clUnloadCompiler` in the dispatch structure must be +set to `CL_ICD2_TAG_KHR`. The vendor driver is responsible for propagating +the `dispatch_data` value when returning objects to users. === ICD Data @@ -230,10 +239,31 @@ value {CL_PLATFORM_ICD_SUFFIX_KHR}. If any of these steps fail, the ICD Loader will ignore the Vendor ICD and continue on to the next. +New in version 2.0.0, the ICD Loader will also query the following functions +from the library: {clIcdGetFunctionAddressForPlatformKHR} and +{clIcdSetPlatformDispatchDataKHR}. If these two functions are present and the +pointers to `clGetPlatformIDs` and `clUnloadCompiler` in the dispatch +structure of a platform is set to `CL_ICD2_TAG_KHR` the platform will be +deemed ICD 2 compatible and dispatch will be managed by the ICD Loader. If the +`CL_ICD2_TAG_KHR` tag is present but one of the two functions above is +missing or it the tag is present in only one of the pointers, the ICD Loader +will ignore the Vendor ICD and continue on to the next. + +During initialization, after calling {clIcdGetPlatformIDsKHR} to query the +available platforms, the ICD Loader will, for each ICD 2 compatible platform, +query dispatchable entry points using {clIcdGetFunctionAddressForPlatformKHR} +and then set the platform dispatch data using +{clIcdSetPlatformDispatchDataKHR}. + === New Commands * {clIcdGetPlatformIDsKHR} +New in version 2.0.0: + + * {clIcdGetFunctionAddressForPlatformKHR} + * {clIcdSetPlatformDispatchDataKHR} + === New Enums Accepted as _param_name_ to the function {clGetPlatformInfo}: @@ -244,6 +274,11 @@ Returned by {clGetPlatformIDs} when no platforms are found: * {CL_PLATFORM_NOT_FOUND_KHR} +New in version 2.0.0, used as a value in the pointers to `clGetPlatformIDs` +and `clUnloadCompiler` in the dispatch structure: + + * `CL_ICD2_TAG_KHR` + === Issues . Some OpenCL functions do not take an object argument from which their @@ -286,9 +321,31 @@ obtaining the ICD dispatch table. On detecting a `NULL` object it will return one of the an invalid object error values (e.g. {CL_INVALID_DEVICE} corresponding to the object in question. +-- + + . How will the ICD loader avoid calling entry points outside of the dispatch + table of old implementations, potentially causing segfaults? ++ +-- +*RESOLVED*: From versions 2.0.0 and above, the loader will be responsible for +managing dispatch data information per platform. The content of the dispatch +table is obtained through a dedicated entry point, and missing entry points are +replaced by stubs that return {CL_INVALID_OPERATION}. +-- + + . How will the ICD loader set the loader managed dispatch information in new + objects? Some of these objects may be created by extension functions that + the loader is unaware of. ++ +-- +*RESOLVED*: During initialization, the loader will set the platform dispatch +information through a new entry point. The implementation will be responsible +for propagating this information to new objects. -- === Version History * Revision 1.0.0, 2020-04-21 ** First assigned version. + * Revision 2.0.0, 2024-09-04 + ** Loader managed dispatch. diff --git a/api/opencl_platform_layer.asciidoc b/api/opencl_platform_layer.asciidoc index 2b1ae266d..e37ba3e2b 100644 --- a/api/opencl_platform_layer.asciidoc +++ b/api/opencl_platform_layer.asciidoc @@ -84,6 +84,43 @@ Otherwise, it returns one of the following errors: * {CL_INVALID_VALUE} if _num_entries_ is equal to zero and _platforms_ is not `NULL` or if both _num_platforms_ and _platforms_ are `NULL`. -- + +[open,refpage='clIcdGetFunctionAddressForPlatformKHR',desc='Query API entry points for a platform',type='protos'] +-- +The entry point of a given platform that is ICD 2 compatible can be obtained +using the following function: + +include::{generated}/api/protos/clIcdGetFunctionAddressForPlatformKHR.txt[] +include::{generated}/api/version-notes/clIcdGetFunctionAddressForPlatformKHR.asciidoc[] + + * _platform_ refers to the platform ID returned by {clIcdGetPlatformIDsKHR} + * _func_name_ name of an API entry point + +{clIcdGetFunctionAddressForPlatformKHR} returns the address of the API entry +point named by _func_name_. The pointer returned should be cast to a function +pointer type matching the API entry point as defined in the specification +header file. + +A return value of `NULL` indicates that the specified function does not exist +for _platform_, or _platform_ is not a valid platform for the implementation. +-- + +[open,refpage='clIcdSetPlatformDispatchDataKHR',desc='Set the dispatch data for a platform',type='protos'] +-- +The `dispatch_data` field of a platform can be set using the following function: + +include::{generated}/api/protos/clIcdSetPlatformDispatchDataKHR.txt[] +include::{generated}/api/version-notes/clIcdSetPlatformDispatchDataKHR.asciidoc[] + + * _platform_ refers to the platform ID returned by {clIcdGetPlatformIDsKHR} + * _dispatch_data_ is the value to set the `dispatch_data` field of the + structure to + +{clIcdSetPlatformDispatchDataKHR} returns {CL_SUCCESS} if the function is +executed successfully. +It returns {CL_INVALID_PLATFORM} if _platform_ is not a valid platform. +-- + endif::cl_khr_icd[] [open,refpage='clGetPlatformInfo',desc='Query information about an OpenCL platform',type='protos'] diff --git a/scripts/gen_dictionaries.py b/scripts/gen_dictionaries.py index e513385f6..f7fbe5ec8 100755 --- a/scripts/gen_dictionaries.py +++ b/scripts/gen_dictionaries.py @@ -249,7 +249,7 @@ def GetFooter(): addLink = True name = type.get('name') elif category == 'define': - if type.text and type.text.startswith("#define"): + if type.text and (type.text.startswith("#define") or type.text.strip().startswith("#if")): continue name = type.find('name').text else: diff --git a/xml/cl.xml b/xml/cl.xml index e07843004..f6a8bd618 100644 --- a/xml/cl.xml +++ b/xml/cl.xml @@ -382,6 +382,15 @@ server's OpenCL/api-docs repository. const size_t* global_work_size const size_t* local_work_size + + +#if INTPTR_MAX == INT32_MAX +#define CL_ICD2_TAG_KHR ((intptr_t)0x434C3331) +#else +#define CL_ICD2_TAG_KHR ((intptr_t)0x4F50454E434C3331) +#endif + + @@ -2558,6 +2567,16 @@ server's OpenCL/api-docs repository. cl_platform_id* platforms cl_uint* num_platforms + + void* clIcdGetFunctionAddressForPlatformKHR + cl_platform_id platform + const char* func_name + + + cl_int clIcdSetPlatformDispatchDataKHR + cl_platform_id platform + void* dispatch_data + cl_program clCreateProgramWithILKHR cl_context context @@ -5600,7 +5619,7 @@ server's OpenCL/api-docs repository. - + @@ -5610,8 +5629,13 @@ server's OpenCL/api-docs repository. + + + + + From 57c65a4c9864b7f11eff0e82992a489e1b692149 Mon Sep 17 00:00:00 2001 From: Brice Videau Date: Wed, 4 Sep 2024 16:45:09 -0500 Subject: [PATCH 2/2] Add CL_PLATFORM_UNLOADABLE_KHR and layers deinitialization. --- api/cl_khr_icd.asciidoc | 11 +++++++++-- api/opencl_platform_layer.asciidoc | 5 +++++ extensions/cl_loader_layers.asciidoc | 20 ++++++++++++++++++-- xml/cl.xml | 12 ++++++++++-- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/api/cl_khr_icd.asciidoc b/api/cl_khr_icd.asciidoc index f69aaa342..2d2bcba97 100644 --- a/api/cl_khr_icd.asciidoc +++ b/api/cl_khr_icd.asciidoc @@ -274,11 +274,18 @@ Returned by {clGetPlatformIDs} when no platforms are found: * {CL_PLATFORM_NOT_FOUND_KHR} -New in version 2.0.0, used as a value in the pointers to `clGetPlatformIDs` -and `clUnloadCompiler` in the dispatch structure: +New in version 2.0.0. + +Used as a value in the pointers to `clGetPlatformIDs` and `clUnloadCompiler` +in the dispatch structure: * `CL_ICD2_TAG_KHR` +Used as a parameter name to query if a platform can be unlaoded by the ICD +Loader: + + * {CL_PLATFORM_UNLOADABLE_KHR} + === Issues . Some OpenCL functions do not take an object argument from which their diff --git a/api/opencl_platform_layer.asciidoc b/api/opencl_platform_layer.asciidoc index e37ba3e2b..8f32e713e 100644 --- a/api/opencl_platform_layer.asciidoc +++ b/api/opencl_platform_layer.asciidoc @@ -337,6 +337,11 @@ include::{generated}/api/version-notes/CL_PLATFORM_ICD_SUFFIX_KHR.asciidoc[] | {char_TYPE}[] | The function name suffix used to identify extension functions to be directed to this platform by the ICD Loader. +| {CL_PLATFORM_UNLOADABLE_KHR_anchor} + +include::{generated}/api/version-notes/CL_PLATFORM_UNLOADABLE_KHR.asciidoc[] + | {cl_bool_TYPE} + | The platform can be unloaded by the ICD Loader. endif::cl_khr_icd[] |==== diff --git a/extensions/cl_loader_layers.asciidoc b/extensions/cl_loader_layers.asciidoc index c286706de..49800c2c3 100644 --- a/extensions/cl_loader_layers.asciidoc +++ b/extensions/cl_loader_layers.asciidoc @@ -21,6 +21,7 @@ interception layers (Layer ICDs) for OpenCL. |==== | *Date* | *Version* | *Description* | 2020-11-04 | 1.0.0 | First assigned version. +| 2024-09-04 | 2.0.0 | Deinitialization support. |==== ==== Contributors @@ -45,6 +46,8 @@ cl_int clInitLayer(cl_uint num_entries, const cl_icd_dispatch *target_dispatch, cl_uint *num_entries_ret, const cl_icd_dispatch **layer_dispatch_ret); + +cl_int clDeinitLayer(void); ---- [[cl_loader_layers-new-api-types]] @@ -72,12 +75,13 @@ Accepted as _param_name_ to the function *clGetLayerInfo*: === New API Tokens Returned by *clGetLayerInfo* when supplied *CL_LAYER_API_VERSION* -and the corresponding layer implements version 1.0.0 of the layer -API: +and the corresponding layer implements version 1.0.0 or 2.0.0 of +the layer API: [source,opencl] ---- #define CL_LAYER_API_VERSION_100 100 +#define CL_LAYER_API_VERSION_200 200 ---- [[cl_loader_layers-new-environment-variables]] @@ -173,6 +177,18 @@ Otherwise, it returns one of the following errors. _target_dispatch_ is a `NULL` value, or _num_entries_ret_ is a `NULL` value, or _layer_dispatch_ret_ is a `NULL` value. +==== Layer Deinitialization + +[open,refpage='clDeinitLayer',desc='Deinitialize an OpenCL layer',type='protos'] +Deinitilization of a layer can be achieved with the function: +[source,opencl] + +---- +cl_int clInitLayer(void); +---- + +*clDeinitLayer* returns *CL_SUCCESS* if the function is executed successfully. + [[cl_loader_layers-source-code]] === Source Code diff --git a/xml/cl.xml b/xml/cl.xml index f6a8bd618..1745f724d 100644 --- a/xml/cl.xml +++ b/xml/cl.xml @@ -522,6 +522,7 @@ server's OpenCL/api-docs repository. + @@ -1422,7 +1423,8 @@ server's OpenCL/api-docs repository. - + + @@ -4246,6 +4248,9 @@ server's OpenCL/api-docs repository. cl_uint* num_entries_ret const cl_icd_dispatch** layer_dispatch_ret + + cl_int clDeinitLayer + cl_int clGetICDLoaderInfoOCLICD cl_icdl_info param_name @@ -5625,6 +5630,7 @@ server's OpenCL/api-docs repository. + @@ -5638,7 +5644,7 @@ server's OpenCL/api-docs repository. - + @@ -5652,10 +5658,12 @@ server's OpenCL/api-docs repository. + +