Skip to content

Commit

Permalink
Working cl_khr_icd 2.0.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerilk committed Feb 15, 2024
1 parent 932d826 commit 8dde4f0
Show file tree
Hide file tree
Showing 14 changed files with 3,638 additions and 468 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ endif()
# It is currently needed default while the specification is being formalized,
# and to study the performance impact.
option (ENABLE_OPENCL_LAYERS "Enable OpenCL Layers" ON)
option (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH "Enable OpenCL Loader managed dispatch" ON)
include(CMakeDependentOption)
cmake_dependent_option(ENABLE_OPENCL_LAYERINFO "Enable building cllayerinfo tool" ON ENABLE_OPENCL_LAYERS OFF)

Expand Down Expand Up @@ -158,6 +159,7 @@ set (OPENCL_COMPILE_DEFINITIONS
OPENCL_ICD_LOADER_VERSION_MINOR=0
OPENCL_ICD_LOADER_VERSION_REV=6
$<$<BOOL:${ENABLE_OPENCL_LAYERS}>:CL_ENABLE_LAYERS>
$<$<BOOL:${ENABLE_OPENCL_LOADER_MANAGED_DISPATCH}>:CL_ENABLE_LOADER_MANAGED_DISPATCH>
)

target_compile_definitions (OpenCL
Expand Down
64 changes: 50 additions & 14 deletions loader/icd.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ void khrIcdVendorAdd(const char *libraryName)
cl_int result = CL_SUCCESS;
pfn_clGetExtensionFunctionAddress p_clGetExtensionFunctionAddress = NULL;
pfn_clIcdGetPlatformIDs p_clIcdGetPlatformIDs = NULL;
#if KHR_LOADER_MANAGED_DISPATCH
clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform = NULL;
clIcdSetPlatformDispatchDataKHR_fn p_clIcdSetPlatformDispatchData = NULL;
#endif
cl_uint i = 0;
cl_uint platformCount = 0;
cl_platform_id *platforms = NULL;
Expand Down Expand Up @@ -104,6 +108,12 @@ void khrIcdVendorAdd(const char *libraryName)
goto Done;
}

#if KHR_LOADER_MANAGED_DISPATCH
// try to get clIcdGetFunctionAddressForPlatformKHR and clIcdSetPlatformDispatchDataKHR to detect cl_khr_icd2 support
p_clIcdGetFunctionAddressForPlatform = (clIcdGetFunctionAddressForPlatformKHR_fn)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clIcdGetFunctionAddressForPlatformKHR");
p_clIcdSetPlatformDispatchData = (clIcdSetPlatformDispatchDataKHR_fn)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clIcdSetPlatformDispatchDataKHR");
#endif

// query the number of platforms available and allocate space to store them
result = p_clIcdGetPlatformIDs(0, NULL, &platformCount);
if (CL_SUCCESS != result)
Expand Down Expand Up @@ -132,27 +142,63 @@ void khrIcdVendorAdd(const char *libraryName)
char *suffix;
size_t suffixSize;

// call clGetPlatformInfo on the returned platform to get the suffix
if (!platforms[i])
// skip NULL platforms and non dispatchable platforms
if (!platforms[i] || !platforms[i]->dispatch)
{
continue;
}
result = platforms[i]->dispatch->clGetPlatformInfo(

#if KHR_LOADER_MANAGED_DISPATCH
if (KHR_ICD2_HAS_TAG(platforms[i]) && !p_clIcdGetFunctionAddressForPlatform)
{
KHR_ICD_TRACE("found icd 2 object, but platform is missing clIcdGetFunctionAddressForPlatformKHR\n");
continue;
}
if (KHR_ICD2_HAS_TAG(platforms[i]) && !p_clIcdSetPlatformDispatchData)
{
KHR_ICD_TRACE("found icd 2 object, but platform is missing clIcdSetPlatformDispatchDataKHR\n");
continue;
}
#endif

// allocate a structure for the vendor
vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
if (!vendor)
{
KHR_ICD_TRACE("failed to allocate memory\n");
continue;
}
memset(vendor, 0, sizeof(*vendor));

#if KHR_LOADER_MANAGED_DISPATCH
// populate cl_khr_icd2 platform's loader managed dispatch tables
if (KHR_ICD2_HAS_TAG(platforms[i]))
{
khrIcd2PopulateDispatchTable(platforms[i], p_clIcdGetFunctionAddressForPlatform, &vendor->dispData.dispatch);
p_clIcdSetPlatformDispatchData(platforms[i], &vendor->dispData);
KHR_ICD_TRACE("found icd 2 platform, using loader managed dispatch\n");
}
#endif

// call clGetPlatformInfo on the returned platform to get the suffix
result = KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
platforms[i],
CL_PLATFORM_ICD_SUFFIX_KHR,
0,
NULL,
&suffixSize);
if (CL_SUCCESS != result)
{
free(vendor);
continue;
}
suffix = (char *)malloc(suffixSize);
if (!suffix)
{
free(vendor);
continue;
}
result = platforms[i]->dispatch->clGetPlatformInfo(
result = KHR_ICD2_DISPATCH(platforms[i])->clGetPlatformInfo(
platforms[i],
CL_PLATFORM_ICD_SUFFIX_KHR,
suffixSize,
Expand All @@ -164,16 +210,6 @@ void khrIcdVendorAdd(const char *libraryName)
continue;
}

// allocate a structure for the vendor
vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
if (!vendor)
{
free(suffix);
KHR_ICD_TRACE("failed to allocate memory\n");
continue;
}
memset(vendor, 0, sizeof(*vendor) );

// populate vendor data
vendor->library = khrIcdOsLibraryLoad(libraryName);
if (!vendor->library)
Expand Down
33 changes: 23 additions & 10 deletions loader/icd.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define _ICD_H_

#include "icd_platform.h"
#include "icd_dispatch.h"

#ifndef CL_USE_DEPRECATED_OPENCL_1_0_APIS
#define CL_USE_DEPRECATED_OPENCL_1_0_APIS
Expand Down Expand Up @@ -90,6 +91,11 @@ struct KHRicdVendorRec
// the platform retrieved from clGetIcdPlatformIDsKHR
cl_platform_id platform;

#if KHR_LOADER_MANAGED_DISPATCH
// the loader populated dispatch table for cl_khr_icd2 compliant platforms
struct KHRDisp dispData;
#endif

// next vendor in the list vendors
KHRicdVendor *next;
};
Expand Down Expand Up @@ -201,11 +207,24 @@ do \
#define KHR_ICD_WIDE_TRACE(...)
#endif

#define KHR_ICD_ERROR_RETURN_ERROR(_error) \
do { \
return _error; \
} while(0)

#define KHR_ICD_ERROR_RETURN_HANDLE(_error) \
do { \
if (errcode_ret) { \
*errcode_ret = _error; \
} \
return NULL; \
} while(0)

// Check if the passed-in handle is NULL, and if it is, return the error.
#define KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(_handle, _error) \
do { \
if (!_handle) { \
return _error; \
KHR_ICD_ERROR_RETURN_ERROR(_error); \
} \
} while (0)

Expand All @@ -214,10 +233,7 @@ do { \
#define KHR_ICD_VALIDATE_HANDLE_RETURN_HANDLE(_handle, _error) \
do { \
if (!_handle) { \
if (errcode_ret) { \
*errcode_ret = _error; \
} \
return NULL; \
KHR_ICD_ERROR_RETURN_HANDLE(_error); \
} \
} while (0)

Expand All @@ -226,7 +242,7 @@ do { \
#define KHR_ICD_VALIDATE_POINTER_RETURN_ERROR(_pointer) \
do { \
if (!_pointer) { \
return CL_INVALID_OPERATION; \
KHR_ICD_ERROR_RETURN_ERROR(CL_INVALID_OPERATION); \
} \
} while (0)

Expand All @@ -236,10 +252,7 @@ do { \
#define KHR_ICD_VALIDATE_POINTER_RETURN_HANDLE(_pointer) \
do { \
if (!_pointer) { \
if (errcode_ret) { \
*errcode_ret = CL_INVALID_OPERATION; \
} \
return NULL; \
KHR_ICD_ERROR_RETURN_HANDLE(CL_INVALID_OPERATION); \
} \
} while (0)

Expand Down
2 changes: 1 addition & 1 deletion loader/icd_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ static inline void* clGetExtensionFunctionAddressForPlatform_body(
// to get the extension function address.

KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(platform, NULL);
return platform->dispatch->clGetExtensionFunctionAddressForPlatform(
return KHR_ICD2_DISPATCH(platform)->clGetExtensionFunctionAddressForPlatform(
platform,
function_name);
}
Expand Down
97 changes: 70 additions & 27 deletions loader/icd_dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,56 +60,99 @@
#include <CL/cl_egl.h>
#include <CL/cl_icd.h>

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) && !defined(CL_ICD2_TAG_KHR)
#define CL_ICD2_TAG_KHR ((size_t)0x4F50454E434C3331ULL)

typedef void * CL_API_CALL
clIcdGetFunctionAddressForPlatformKHR_t(
cl_platform_id platform,
const char* func_name);

typedef clIcdGetFunctionAddressForPlatformKHR_t *
clIcdGetFunctionAddressForPlatformKHR_fn;

typedef cl_int CL_API_CALL
clIcdSetPlatformDispatchDataKHR_t(
cl_platform_id platform,
void *disp_data);

typedef clIcdSetPlatformDispatchDataKHR_t *
clIcdSetPlatformDispatchDataKHR_fn;

extern void khrIcd2PopulateDispatchTable(
cl_platform_id platform,
clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform,
struct _cl_icd_dispatch* dispatch);

#endif // defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) && !defined(CL_ICD2_TAG_KHR)

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
#define KHR_LOADER_MANAGED_DISPATCH 1
#else
#define KHR_LOADER_MANAGED_DISPATCH 0
#endif

#if KHR_LOADER_MANAGED_DISPATCH
struct KHRDisp
{
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)->dispData->dispatch : \
(object)->dispatch)

#define KHR_ICD_OBJECT_BODY { \
cl_icd_dispatch *dispatch; \
struct KHRDisp *dispData; \
}

#else // KHR_LOADER_MANAGED_DISPATCH

#define KHR_ICD2_DISPATCH(object) ((object)->dispatch)

#define KHR_ICD_OBJECT_BODY { \
cl_icd_dispatch *dispatch; \
}

#endif // KHR_LOADER_MANAGED_DISPATCH

/*
*
* vendor dispatch table structure
*
*/

struct _cl_platform_id
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_device_id
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_context
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_command_queue
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_mem
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_program
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_kernel
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_event
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

struct _cl_sampler
{
cl_icd_dispatch *dispatch;
};
KHR_ICD_OBJECT_BODY;

#endif // _ICD_DISPATCH_H_

Loading

0 comments on commit 8dde4f0

Please sign in to comment.