Other Extension Metadata
- Last Modified Date
- 
2024-09-03 
- IP Status
- 
No known IP claims. 
- Contributors
- 
- 
Ajit Hakke-Patil, NVIDIA 
- 
Amit Rao, NVIDIA 
- 
Balaji Calidas, QUALCOMM 
- 
Ben Ashbaugh, INTEL 
- 
Carsten Rohde, NVIDIA 
- 
Christoph Kubisch, NVIDIA 
- 
Debalina Bhattacharjee, NVIDIA 
- 
Faith Ekstrand, INTEL 
- 
James Jones, NVIDIA 
- 
Jeremy Kemp, IMAGINATION 
- 
Joshua Kelly, QUALCOMM 
- 
Karthik Raghavan Ravi, NVIDIA 
- 
Kedar Patil, NVIDIA 
- 
Kevin Petit, ARM 
- 
Nikhil Joshi, NVIDIA 
- 
Sharan Ashwathnarayan, NVIDIA 
- 
Vivek Kini, NVIDIA 
 
- 
Description
cl_khr_ defines a generic mechanism to share buffer and
image objects between OpenCL and many other APIs, including:
- 
Optional properties to import external memory exported by other APIs into OpenCL for a set of devices. 
- 
Routines to explicitly hand off memory ownership between OpenCL and other APIs. 
Other related extensions define specific external memory types that may be imported into OpenCL.
New Enums
- 
cl_platform_info - 
CL_PLATFORM_EXTERNAL_ MEMORY_ IMPORT_ HANDLE_ TYPES_ KHR 
 
- 
- 
cl_device_info - 
CL_DEVICE_EXTERNAL_ MEMORY_ IMPORT_ HANDLE_ TYPES_ KHR 
- 
CL_DEVICE_EXTERNAL_ MEMORY_ IMPORT_ ASSUME_ LINEAR_ IMAGES_ HANDLE_ TYPES_ KHR 
 
- 
- 
cl_mem_properties - 
CL_MEM_DEVICE_ HANDLE_ LIST_ KHR 
- 
CL_MEM_DEVICE_ HANDLE_ LIST_ END_ KHR 
 
- 
- 
Return values from clGetEventInfo when param_name is cl_command_:type - 
CL_COMMAND_ACQUIRE_ EXTERNAL_ MEM_ OBJECTS_ KHR 
- 
CL_COMMAND_RELEASE_ EXTERNAL_ MEM_ OBJECTS_ KHR 
 
- 
Sample Code
Example for Creating a CL Buffer From an Exported External Buffer in a Single Device Context
This example also requires use of the cl_khr_
extension.
// Get cl_devices of the platform.
clGetDeviceIDs(..., &devices, &deviceCount);
// Create cl_context with just first device
clCreateContext(..., 1, devices, ...);
// Obtain fd/win32 or similar handle for external memory to be imported
// from other API.
int fd = getFdForExternalMemory();
// Create extMemBuffer of type cl_mem from fd.
cl_mem_properties_khr extMemProperties[] =
{
    (cl_mem_properties_khr)CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR,
    (cl_mem_properties_khr)fd,
    0
};
cl_mem extMemBuffer = clCreateBufferWithProperties(/*context*/          clContext,
                                                   /*properties*/       extMemProperties,
                                                   /*flags*/            0,
                                                   /*size*/             size,
                                                   /*host_ptr*/         NULL,
                                                   /*errcode_ret*/      &errcode_ret);Example for Creating a CL Image From an Exported External Image for Single Device Usage in a Multi-Device Context
This example also requires use of the cl_khr_
extension.
// Get cl_devices of the platform.
clGetDeviceIDs(..., &devices, &deviceCount);
// Create cl_context with first two devices
clCreateContext(..., 2, devices, ...);
// Create img of type cl_mem usable only on devices[0]
// Create img of type cl_mem.
// Obtain fd/win32 or similar handle for external memory to be imported
// from other API.
int fd = getFdForExternalMemory();
// Set cl_image_format based on external image info
cl_image_format clImgFormat = { };
clImageFormat.image_channel_order = CL_RGBA;
clImageFormat.image_channel_data_type = CL_UNORM_INT8;
// Set cl_image_desc based on external image info
size_t clImageFormatSize;
cl_image_desc image_desc = { };
image_desc.image_type = CL_MEM_OBJECT_IMAGE2D_ARRAY;
image_desc.image_width = width;
image_desc.image_height = height;
image_desc.image_depth = depth;
image_desc.image_array_size = num_slices;
image_desc.image_row_pitch = width * 8 * 4; // May need alignment
image_desc.image_slice_pitch = image_desc.image_row_pitch * height;
image_desc.num_mip_levels = 1;
image_desc.num_samples = 0;
image_desc.buffer = NULL;
cl_mem_properties_khr extMemProperties[] = {
    (cl_mem_properties_khr)CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR,
    (cl_mem_properties_khr)fd,
    (cl_mem_properties_khr)CL_MEM_DEVICE_HANDLE_LIST_KHR,
    (cl_mem_properties_khr)devices[0],
    CL_MEM_DEVICE_HANDLE_LIST_END_KHR,
    0
};
cl_mem img = clCreateImageWithProperties(/*context*/        clContext,
                                         /*properties*/     extMemProperties,
                                         /*flags*/          0,
                                         /*image_format*/   &clImgFormat,
                                         /*image_desc*/     &image_desc,
                                         /*errcode_ret*/    &errcode_ret);
// Use clGetImageInfo to get cl_image_format details.
size_t clImageFormatSize;
clGetImageInfo(img,
               CL_IMAGE_FORMAT,
               sizeof(cl_image_format),
               &clImageFormat,
               &clImageFormatSize);Example for Synchronization Using Wait and Signal
// Start the main rendering loop
// Create extSem of type cl_semaphore_khr using clCreateSemaphoreWithPropertiesKHR
// Create extMem of type cl_mem using clCreateBufferWithProperties or clCreateImageWithProperties
while (true) {
    // (not shown) Signal the semaphore from the other API
    // Wait for the semaphore in OpenCL, by calling clEnqueueWaitSemaphoresKHR on 'extSem'
    clEnqueueWaitSemaphoresKHR(/*command_queue*/            command_queue,
                               /*num_sema_objects*/         1,
                               /*sema_objects*/             &extSem,
                               /*sema_payload_list*/        NULL,
                               /*num_events_in_wait_list*/  0,
                               /*event_wait_list*/          NULL,
                               /*event*/                    NULL);
    // Launch kernel that accesses extMem
    clEnqueueNDRangeKernel(command_queue, ...);
    // Signal the semaphore in OpenCL
    clEnqueueSignalSemaphoresKHR(/*command_queue*/           command_queue,
                                 /*num_sema_objects*/        1,
                                 /*sema_objects*/            &extSem,
                                 /*sema_payload_list*/       NULL,
                                 /*num_events_in_wait_list*/ 0,
                                 /*event_wait_list*/         NULL,
                                 /*event*/                   NULL);
    // (not shown) Launch work in other API that waits on 'extSem'
}Example With Memory Sharing Using Acquire/Release
// Create extSem of type cl_semaphore_khr using
// clCreateSemaphoreWithPropertiesKHR with CL_SEMAPHORE_HANDLE_*_KHR.
// Create extMem1 and extMem2 of type cl_mem using clCreateBufferWithProperties
// or clCreateImageWithProperties
while (true) {
    // (not shown) Signal the semaphore from the other API. Wait for the
    // semaphore in OpenCL, by calling clEnqueueWaitForSemaphore on extSem
    clEnqueueWaitSemaphoresKHR(/*command_queue*/            cq1,
                               /*num_sema_objects*/         1,
                               /*sema_objects*/             &extSem,
                               /*sema_payload_list*/        NULL,
                               /*num_events_in_wait_list*/  0,
                               /*event_wait_list*/          NULL,
                               /*event*/                    NULL);
    // Get explicit ownership of extMem1
    clEnqueueAcquireExternalMemObjectsKHR(/*command_queue*/             cq1,
                                          /*num_mem_objects*/           1,
                                          /*mem_objects*/               &extMem1,
                                          /*num_events_in_wait_list*/   0,
                                          /*event_wait_list*/           NULL,
                                          /*event*/                     NULL);
    // Launch kernel that accesses extMem1 on cq1 on cl_device1
    clEnqueueNDRangeKernel(cq1,  ..., &event1);
    // Launch kernel that accesses both extMem1 and extMem2 on cq2 on cl_device2
    // Migration of extMem1 and extMem2 handles through regular CL memory
    // migration.
    clEnqueueNDRangeKernel(cq2, ..., &event1, &event2);
    // Give up ownership of extMem1 before you signal the semaphore. Handle
    // memory migration here.
    clEnqueueReleaseExternalMemObjectsKHR(/*command_queue*/           cq2
                                          /*num_mem_objects*/         1,
                                          /*mem_objects*/             &extMem1,
                                          /*num_events_in_wait_list*/ 0,
                                          /*event_wait_list*/         NULL,
                                          /*event*/                   NULL);
    // Signal the semaphore from OpenCL
    clEnqueueSignalSemaphoresKHR(/*command_queue*/           cq2,
                                 /*num_sema_objects*/        1,
                                 /*sema_objects*/            &extSem,
                                 /*sema_payload_list*/       NULL,
                                 /*num_events_in_wait_list*/ 0,
                                 /*event_wait_list*/         NULL,
                                 /*event*/                   NULL);
    // (not shown) Launch work in other API that waits on 'extSem'
    // Other API accesses ext1, but not ext2 on device-1
}Issues
- 
How should the import of images that are created in external APIs with non-linear tiling be robustly handled? UNRESOLVED 
Version History
- 
Revision 0.9.0, 2021-09-10 - 
Initial version (experimental). 
 
- 
- 
Revision 0.9.1, 2023-05-04 - 
Clarified device handle list enum cannot be specified without an external memory handle (experimental). 
 
- 
- 
Revision 0.9.2, 2023-08-01 - 
Changed device handle list enum to the memory-specific CL_MEM_(experimental).DEVICE_ HANDLE_ LIST_ KHR 
 
- 
- 
Revision 0.9.3, 2023-08-29 - 
Added query for CL_DEVICE_(experimental).EXTERNAL_ MEMORY_ IMPORT_ ASSUME_ LINEAR_ IMAGES_ HANDLE_ TYPES_ KHR 
 
- 
- 
Revision 1.0.0, 2024-03-15 - 
First non-experimental version. 
 
- 
- 
Revision 1.0.1, 2024-09-03 - 
Return CL_INVALID_when multiple external handles are provided when creating a memory object.PROPERTY 
 
- 
Document Notes
For more information, see the OpenCL Specification
This page is a generated document. Fixes and changes should be made to the generator scripts, not directly.