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 Nov 20, 2023
1 parent 229410f commit 405f5b7
Show file tree
Hide file tree
Showing 7 changed files with 3,256 additions and 422 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
57 changes: 43 additions & 14 deletions loader/icd.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ 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
clGetFunctionAddressForPlatformKHR_fn p_clGetFunctionAddressForPlatform = NULL;
#endif
cl_uint i = 0;
cl_uint platformCount = 0;
cl_platform_id *platforms = NULL;
Expand Down Expand Up @@ -104,6 +107,11 @@ void khrIcdVendorAdd(const char *libraryName)
goto Done;
}

#if KHR_LOADER_MANAGED_DISPATCH
// try to get clGetFunctionAddressForPlatformKHR to detect cl_khr_icd2 support
p_clGetFunctionAddressForPlatform = (clGetFunctionAddressForPlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clGetFunctionAddressForPlatformKHR");
#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 +140,58 @@ 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;
}

#if KHR_LOADER_MANAGED_DISPATCH
if (KHR_ICD2_HAS_TAG(platforms[i]) && !p_clGetFunctionAddressForPlatform)
{
KHR_ICD_TRACE("found icd 2 object, but platform is missing clGetFunctionAddressForPlatformKHR");
continue;
}
#endif

// allocate a structure for the vendor
vendor = (KHRicdVendor*)malloc(sizeof(*vendor) );
if (!vendor)
{
KHR_ICD_TRACE("failed to allocate memory\n");
continue;
}
result = platforms[i]->dispatch->clGetPlatformInfo(
memset(vendor, 0, sizeof(*vendor));

#if KHR_LOADER_MANAGED_DISPATCH
// populate cl_khr_icd2 platform's loader managed dispatch tables
if (p_clGetFunctionAddressForPlatform && KHR_ICD2_HAS_TAG(platforms[i]))
{
khrIcd2PopulateDispatchTable(platforms[i], p_clGetFunctionAddressForPlatform, &vendor->dispData.dispatch);
platforms[i]->dispData = &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 +203,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
96 changes: 69 additions & 27 deletions loader/icd_dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,66 @@
#include <CL/cl_ext.h>
#include <CL/cl_egl.h>
#include <CL/cl_icd.h>
#include <stdint.h>

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) && !defined(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;

extern void khrIcd2PopulateDispatchTable(
cl_platform_id platform,
clGetFunctionAddressForPlatformKHR_fn p_clGetFunctionAddressForPlatform,
struct _cl_icd_dispatch* dispatch);
#endif // defined(CL_ICD2_TAG_KHR)

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

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH) && defined(CL_ICD2_TAG_KHR)
#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

/*
*
Expand All @@ -67,49 +127,31 @@
*/

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 405f5b7

Please sign in to comment.