| // Copyright 2017-2024 The Khronos Group. This work is licensed under a |
| // Creative Commons Attribution 4.0 International License; see |
| // http://creativecommons.org/licenses/by/4.0/ |
| |
| [[extensions-overview]] |
| == Extensions Overview |
| |
| _Extensions_ are optional features which may be supported by OpenCL |
| implementations. |
| Extensions are not required to be supported by a conformant OpenCL |
| implementation, but are expected to be widely available, and in some cases |
| may define functionality that is likely to be required in a future revision |
| of the OpenCL specification. |
| |
| In the past, this document contained full specification language for |
| Khronos-approved `khr` extensions, described in terms of changes to the core |
| OpenCL Specification. |
| This extension language has now been integrated into the OpenCL 3.0 |
| Specification, and can be read in context there. |
| |
| The remaining parts of this document describe general issues in _using_ |
| extensions, such as API <<naming-convention-for-optional-extensions, Naming |
| Conventions for Optional Extensions>>; OpenCL C |
| <<compiler-directives-for-optional-extensions, Compiler Directives for |
| Optional Extensions>>; and <<getting-opencl-api-extension-function-pointers, |
| Getting OpenCL API Extension Function Pointers>>. |
| |
| In addition, there is a section on <<spirv_extensions, Extensions to the |
| OpenCL SPIR-V Environment>>. |
| |
| Finally, the <<quick-reference, Quick Reference>> appendix summarizes khr |
| extensions and links to them in the OpenCL API Specification. |
| In some cases, extensions are mostly or entirely to the OpenCL C language |
| rather than to the OpenCL API. |
| Such extensions can be reached by following the links in the API |
| Specification extension appendices. |
| |
| |
| [[naming-convention-for-optional-extensions]] |
| === Naming Convention for Optional Extensions |
| |
| OpenCL extensions approved by the OpenCL working group use the following |
| naming convention: |
| |
| * A unique _name string_ of the form `"*cl_khr_<__name__>*"` is associated |
| with each extension. |
| If the extension is supported by an implementation, this string will be |
| present in the implementation's `CL_PLATFORM_EXTENSIONS` string or |
| `CL_DEVICE_EXTENSIONS` string. |
| * All API functions defined by the extension will have names of the form |
| *cl<__function_name__>KHR*. |
| * All enumerants defined by the extension will have names of the form |
| *CL_<__enum_name__>_KHR.* |
| |
| Functions and enumerants defined by extensions that are promoted to |
| core features will have their *KHR* affix removed. |
| OpenCL implementations of such later revisions must also export the name |
| strings of promoted extensions in the `CL_PLATFORM_EXTENSIONS` or |
| `CL_DEVICE_EXTENSIONS` string, and support the *KHR*-affixed versions of |
| functions and enumerants as a transition aid. |
| |
| Vendor extensions are strongly encouraged to follow a similar naming |
| convention: |
| |
| * A unique _name string_ of the form `"*cl_<__vendor_name__>_<__name>__*"` |
| is associated with each extension. |
| If the extension is supported by an implementation, this string will be |
| present in the implementation's `CL_PLATFORM_EXTENSIONS` string or |
| `CL_DEVICE_EXTENSIONS` string. |
| * All API functions defined by the vendor extension will have names of the |
| form *cl<__function_name__><__vendor_name__>*. |
| * All enumerants defined by the vendor extension will have names of the |
| form *CL_<__enum_name__>_<__vendor_name__>.* |
| |
| |
| [[compiler-directives-for-optional-extensions]] |
| === Compiler Directives for Optional Extensions |
| |
| The *#pragma OPENCL EXTENSION* directive controls the behavior of the OpenCL |
| compiler with respect to extensions. |
| The *#pragma OPENCL EXTENSION* directive is defined as: |
| |
| [source,opencl_c] |
| ---- |
| #pragma OPENCL EXTENSION <extension_name> : <behavior> |
| #pragma OPENCL EXTENSION all : <behavior> |
| ---- |
| |
| where _extension_name_ is the name of the extension. |
| The _extension_name_ will have names of the form *cl_khr_<__name__>* for an |
| extension approved by the OpenCL working group and will have names of the |
| form *cl_<__vendor_name__>_<__name__>* for vendor extensions. |
| The token *all* means that the behavior applies to all extensions supported |
| by the compiler. |
| The _behavior_ can be set to one of the following values given by the table |
| below. |
| |
| [cols="1,3",options="header",] |
| |==== |
| | *behavior* | *Description* |
| | *enable* |
| | Behave as specified by the extension _extension_name_. |
| |
| Report an error on the *`#pragma OPENCL EXTENSION`* if the |
| _extension_name_ is not supported, or if *all* is specified. |
| |
| | *disable* |
| | Behave (including issuing errors and warnings) as if the extension |
| _extension_name_ is not part of the language definition. |
| |
| If *all* is specified, then behavior must revert back to that of the |
| non-extended core version of the language being compiled to. |
| |
| Warn on the *`#pragma OPENCL EXTENSION`* if the extension _extension_name_ |
| is not supported. |
| |
| |==== |
| |
| The *`#pragma OPENCL EXTENSION`* directive is a simple, low-level mechanism |
| to set the behavior for each extension. |
| It does not define policies such as which combinations are appropriate; |
| those must be defined elsewhere. |
| The order of directives matter in setting the behavior for each extension. |
| Directives that occur later override those seen earlier. |
| The *all* variant sets the behavior for all extensions, overriding all |
| previously issued extension directives, but only if the _behavior_ is set to |
| *disable*. |
| |
| The initial state of the compiler is as if the directive |
| |
| [source,opencl_c] |
| ---- |
| #pragma OPENCL EXTENSION all : disable |
| ---- |
| |
| was issued, telling the compiler that all error and warning reporting must |
| be done according to this specification, ignoring any extensions. |
| |
| Every extension which affects the OpenCL language semantics, syntax or adds |
| built-in functions to the language must create a preprocessor `#define` that |
| matches the extension name string. |
| This `#define` would be available in the language if and only if the |
| extension is supported on a given implementation. |
| |
| *Example*: |
| |
| An extension which adds the extension string `"cl_khr_3d_image_writes"` |
| should also add a preprocessor `#define` called *`cl_khr_3d_image_writes`*. |
| A kernel can now use this preprocessor `#define` to do something like: |
| |
| [source,opencl_c] |
| ---- |
| #ifdef cl_khr_3d_image_writes |
| // do something using the extension |
| #else |
| // do something else or #error! |
| #endif |
| ---- |
| |
| |
| [[getting-opencl-api-extension-function-pointers]] |
| === Getting OpenCL API Extension Function Pointers |
| |
| The function |
| indexterm:[clGetExtensionFunctionAddressForPlatform] |
| [source,opencl] |
| ---- |
| void* clGetExtensionFunctionAddressForPlatform(cl_platform_id platform, |
| const char *funcname) |
| ---- |
| |
| returns the address of the extension function named by _funcname_ for a |
| given _platform_ The pointer returned should be cast to a function pointer |
| type matching the extension function's definition defined in the appropriate |
| extension specification and header file. |
| A return value of `NULL` indicates that the specified function does not |
| exist for the implementation or _platform_ is not a valid platform. |
| A non-`NULL` return value for *clGetExtensionFunctionAddressForPlatform* |
| does not guarantee that an extension function is actually supported by the |
| platform. |
| The application must also make a corresponding query using |
| *clGetPlatformInfo*(platform, CL_PLATFORM_EXTENSIONS, ...) or |
| *clGetDeviceInfo*(device, CL_DEVICE_EXTENSIONS, ...) to determine if an |
| extension is supported by the OpenCL implementation. |
| |
| Since there is no way to qualify the query with a |
| device, the function pointer returned must work for all implementations of |
| that extension on different devices for a platform. |
| The behavior of calling a device extension function on a device not |
| supporting that extension is undefined. |
| |
| *clGetExtensionFunctionAddressForPlatform* may not be be used to query for core |
| (non-extension) functions in OpenCL. |
| For extension functions that may be queried using |
| *clGetExtensionFunctionAddressForPlatform*, implementations may also choose to |
| export those functions statically from the object libraries |
| implementing those functions, however, portable applications cannot rely on |
| this behavior. |
| |
| Function pointer typedefs must be declared for all extensions that add API |
| entrypoints. |
| These typedefs are a required part of the extension interface, to be |
| provided in an appropriate header (such as cl_ext.h if the extension is an |
| OpenCL extension, or cl_gl_ext.h if the extension is an OpenCL / OpenGL |
| sharing extension). |
| |
| The following convention must be followed for all extensions affecting the |
| host API: |
| |
| [source,opencl] |
| ---- |
| #ifndef extension_name |
| #define extension_name 1 |
| |
| // all data typedefs, token #defines, prototypes, and |
| // function pointer typedefs for this extension |
| |
| // function pointer typedefs must use the |
| // following naming convention |
| |
| typedef return_type |
| (CL_API_CALL *clExtensionFunctionNameTAG_fn)(...); |
| |
| #endif // _extension_name_ |
| ---- |
| |
| where `TAG` can be `KHR`, `EXT` or `vendor-specific`. |
| |
| Consider, for example, the *cl_khr_gl_sharing* extension. |
| This extension would add the following to cl_gl_ext.h: |
| |
| [source,opencl] |
| ---- |
| #ifndef cl_khr_gl_sharing |
| #define cl_khr_gl_sharing 1 |
| |
| // all data typedefs, token #defines, prototypes, and |
| // function pointer typedefs for this extension |
| #define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000 |
| #define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006 |
| #define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007 |
| #define CL_GL_CONTEXT_KHR 0x2008 |
| #define CL_EGL_DISPLAY_KHR 0x2009 |
| #define CL_GLX_DISPLAY_KHR 0x200A |
| #define CL_WGL_HDC_KHR 0x200B |
| #define CL_CGL_SHAREGROUP_KHR 0x200C |
| |
| // function pointer typedefs must use the |
| // following naming convention |
| typedef cl_int |
| (CL_API_CALL *clGetGLContextInfoKHR_fn)( |
| const cl_context_properties * /* properties */, |
| cl_gl_context_info /* param_name */, |
| size_t /* param_value_size */, |
| void * /* param_value */, |
| size_t * /*param_value_size_ret*/); |
| |
| #endif // cl_khr_gl_sharing |
| ---- |