Skip to content

Commit

Permalink
Add instance support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerilk committed Aug 9, 2024
1 parent 55782c9 commit 7bb3e06
Show file tree
Hide file tree
Showing 11 changed files with 469 additions and 34 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ jobs:
& $REG DELETE $KEY_NAME /v $VALUE_NAME /f
$VALUE_NAME = "${env:GITHUB_WORKSPACE}/build/$Config/OpenCLDriverStubICD2.dll"
& $REG ADD $KEY_NAME /v $VALUE_NAME /t REG_DWORD /d 0
& ctest -C $Config --output-on-failure --no-tests=error --parallel ${env:NUMBER_OF_PROCESSORS} -R opencl_icd_loader_icd2_test
& ctest -C $Config --output-on-failure --no-tests=error --parallel ${env:NUMBER_OF_PROCESSORS} -R opencl_icd_loader_icd2_test^|opencl_icd_loader_icd2_instance_test
if ($LASTEXITCODE -ne 0) { throw "Testing OpenCL-ICD-Loader in $Config failed." }
& $REG DELETE $KEY_NAME /v $VALUE_NAME /f
}
Expand Down
50 changes: 50 additions & 0 deletions include/cl_khr_icd2.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,53 @@ clIcdSetPlatformDispatchDataKHR_t(
typedef clIcdSetPlatformDispatchDataKHR_t *
clIcdSetPlatformDispatchDataKHR_fn;
#endif // !defined(CL_ICD2_TAG_KHR)

#if !defined(CL_INVALID_INSTANCE_KHR)
#define CL_INVALID_INSTANCE_KHR -1154

#define CL_INSTANCE_PROPERTIES_LIST_END_KHR 0

typedef struct _cl_instance_khr *cl_instance_khr;
typedef intptr_t cl_instance_properties_khr;

typedef cl_instance_khr CL_API_CALL
clCreateInstanceKHR_t(
const cl_instance_properties_khr *properties,
cl_int *errcode_ret);

typedef clCreateInstanceKHR_t *
clCreateInstanceKHR_fn;

typedef cl_int CL_API_CALL
clDestroyInstanceKHR_t(
cl_instance_khr instance);

typedef clDestroyInstanceKHR_t *
clDestroyInstanceKHR_fn;

typedef cl_int CL_API_CALL
clGetPlatformIDsForInstanceKHR_t(
cl_instance_khr instance,
cl_uint num_entries,
cl_platform_id *platforms,
cl_uint *num_platforms);

typedef clGetPlatformIDsForInstanceKHR_t *
clGetPlatformIDsForInstanceKHR_fn;

typedef cl_platform_id CL_API_CALL
clIcdCreateInstancePlatformKHR_t(
cl_platform_id platform,
cl_int *errcode_ret);

typedef clIcdCreateInstancePlatformKHR_t *
clIcdCreateInstancePlatformKHR_fn;

typedef cl_int CL_API_CALL
clIcdDestroyInstancePlatformKHR_t(
cl_platform_id platform);

typedef clIcdDestroyInstancePlatformKHR_t *
clIcdDestroyInstancePlatformKHR_fn;

#endif // !defined(CL_INVALID_INSTANCE_KHR)
10 changes: 10 additions & 0 deletions loader/icd.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ void khrIcdVendorAdd(const char *libraryName)
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
clIcdGetFunctionAddressForPlatformKHR_fn p_clIcdGetFunctionAddressForPlatform = NULL;
clIcdSetPlatformDispatchDataKHR_fn p_clIcdSetPlatformDispatchData = NULL;
clIcdCreateInstancePlatformKHR_fn p_clIcdCreateInstancePlatform = NULL;
clIcdDestroyInstancePlatformKHR_fn p_clIcdDestroyInstancePlatform = NULL;
#endif
cl_uint i = 0;
cl_uint platformCount = 0;
Expand Down Expand Up @@ -110,6 +112,8 @@ void khrIcdVendorAdd(const char *libraryName)
// try to get clIcdGetFunctionAddressForPlatformKHR and clIcdSetPlatformDispatchDataKHR to detect cl_khr_icd2 support
p_clIcdGetFunctionAddressForPlatform = (clIcdGetFunctionAddressForPlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdGetFunctionAddressForPlatformKHR");
p_clIcdSetPlatformDispatchData = (clIcdSetPlatformDispatchDataKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdSetPlatformDispatchDataKHR");
p_clIcdCreateInstancePlatform = (clIcdCreateInstancePlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdCreateInstancePlatformKHR");
p_clIcdDestroyInstancePlatform = (clIcdDestroyInstancePlatformKHR_fn)(size_t)p_clGetExtensionFunctionAddress("clIcdDestroyInstancePlatformKHR");
#endif

// query the number of platforms available and allocate space to store them
Expand Down Expand Up @@ -175,6 +179,12 @@ void khrIcdVendorAdd(const char *libraryName)
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");
if (p_clIcdCreateInstancePlatform && p_clIcdDestroyInstancePlatform)
{
vendor->clIcdSetPlatformDispatchData = p_clIcdSetPlatformDispatchData;
vendor->clIcdCreateInstancePlatform = p_clIcdCreateInstancePlatform;
vendor->clIcdDestroyInstancePlatform = p_clIcdDestroyInstancePlatform;
}
}
#endif

Expand Down
13 changes: 13 additions & 0 deletions loader/icd.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,26 @@ struct KHRicdVendorRec
#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
// the loader populated dispatch table for cl_khr_icd2 compliant platforms
struct KHRDisp dispData;
clIcdSetPlatformDispatchDataKHR_fn clIcdSetPlatformDispatchData;
clIcdCreateInstancePlatformKHR_fn clIcdCreateInstancePlatform;
clIcdDestroyInstancePlatformKHR_fn clIcdDestroyInstancePlatform;
#endif

// next vendor in the list vendors
KHRicdVendor *next;
KHRicdVendor *prev;
};

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
struct _cl_instance_khr
{
cl_uint num_platforms;
cl_platform_id *platforms;
KHRicdVendor **vendors;
struct KHRDisp *dispDatas;
};
#endif // defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)

// the global state
extern KHRicdVendor * khrIcdVendors;

Expand Down
154 changes: 154 additions & 0 deletions loader/icd_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,153 @@ clGetICDLoaderInfoOCLICD(
return CL_SUCCESS;
}

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)

static clCreateInstanceKHR_t clCreateInstanceKHR;
cl_instance_khr CL_API_CALL
clCreateInstanceKHR(
const cl_instance_properties_khr *properties,
cl_int *errcode_ret)
{
#define KHR_ICD_ALLOC_AND_ZERO(var, num, type) \
do \
{ \
var = (type *)malloc(num * sizeof(type)); \
if (!var) \
{ \
err = CL_OUT_OF_HOST_MEMORY; \
goto error; \
} \
memset(var, 0, num * sizeof(type)); \
} while (0)

(void) properties;
cl_int err = CL_SUCCESS;
cl_instance_khr instance = NULL;
cl_uint num_platforms = 0;

if (!khrIcdVendors)
{
err = CL_PLATFORM_NOT_FOUND_KHR;
goto error;
}

for (KHRicdVendor* vendor = khrIcdVendors; vendor; vendor = vendor->next)
{
if (vendor->clIcdCreateInstancePlatform)
num_platforms++;
}

KHR_ICD_ALLOC_AND_ZERO(instance, 1, struct _cl_instance_khr);
KHR_ICD_ALLOC_AND_ZERO(instance->platforms, num_platforms, cl_platform_id);
KHR_ICD_ALLOC_AND_ZERO(instance->vendors, num_platforms, KHRicdVendor *);
KHR_ICD_ALLOC_AND_ZERO(instance->dispDatas, num_platforms, struct KHRDisp);

num_platforms = 0;
for (KHRicdVendor* vendor = khrIcdVendors; vendor; vendor = vendor->next)
{
if (vendor->clIcdCreateInstancePlatform)
{
cl_platform_id platform;
platform = vendor->clIcdCreateInstancePlatform(vendor->platform, &err);
if (CL_SUCCESS != err)
continue;
vendor->clIcdSetPlatformDispatchData(platform, instance->dispDatas + num_platforms);
instance->platforms[num_platforms] = platform;
instance->vendors[num_platforms] = vendor;
memcpy(instance->dispDatas + num_platforms, &vendor->dispData, sizeof(struct KHRDisp));
num_platforms++;
}
}

if (!num_platforms)
{
err = CL_PLATFORM_NOT_FOUND_KHR;
goto error;
}

instance->num_platforms = num_platforms;

if (errcode_ret)
*errcode_ret = CL_SUCCESS;
return instance;
error:
if (instance)
{
free(instance->dispDatas);
free(instance->vendors);
free(instance->platforms);
free(instance);
}
if (errcode_ret)
*errcode_ret = err;
#undef KHR_ICD_ALLOC_AND_ZERO
return NULL;
}

static clDestroyInstanceKHR_t clDestroyInstanceKHR;
cl_int CL_API_CALL
clDestroyInstanceKHR(
cl_instance_khr instance)
{
KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(instance, CL_INVALID_INSTANCE_KHR);
for (cl_uint i = 0; i < instance->num_platforms; i++)
instance->vendors[i]->clIcdDestroyInstancePlatform(instance->platforms[i]);
free(instance->dispDatas);
free(instance->vendors);
free(instance->platforms);
free(instance);
return CL_SUCCESS;
}

static clGetPlatformIDsForInstanceKHR_t clGetPlatformIDsForInstanceKHR;
cl_int CL_API_CALL
clGetPlatformIDsForInstanceKHR(
cl_instance_khr instance,
cl_uint num_entries,
cl_platform_id* platforms,
cl_uint* num_platforms)
{
cl_uint i;

KHR_ICD_VALIDATE_HANDLE_RETURN_ERROR(instance, CL_INVALID_INSTANCE_KHR);
// should be impossible since create would have refused to
// create an empty instance
if (!instance->num_platforms)
{
return CL_INVALID_INSTANCE_KHR;
}
if (!num_entries && platforms)
{
return CL_INVALID_VALUE;
}
if (!platforms && !num_platforms)
{
return CL_INVALID_VALUE;
}
if (num_platforms)
{
*num_platforms = instance->num_platforms;
}
if (platforms)
{
for (i = 0; i < num_entries; ++i)
{
platforms[i] = NULL;
}
if (instance->num_platforms < num_entries)
{
num_entries = instance->num_platforms;
}
for (i = 0; i < num_entries; ++i)
{
platforms[i] = instance->platforms[i];
}
}
return CL_SUCCESS;
}
#endif // defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)

static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
{
// Most extensions, including multi-vendor KHR and EXT extensions,
Expand Down Expand Up @@ -139,6 +286,13 @@ static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
// cl_icdl
KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetICDLoaderInfoOCLICD);

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
// cl_khr_instances
KHR_ICD_CHECK_EXTENSION_FUNCTION(clCreateInstanceKHR);
KHR_ICD_CHECK_EXTENSION_FUNCTION(clDestroyInstanceKHR);
KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetPlatformIDsForInstanceKHR);
#endif

#undef KHR_ICD_CHECK_EXTENSION_FUNCTION

return NULL;
Expand Down
14 changes: 14 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ add_test (
COMMAND icd_loader_test
)

if (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH)
add_test (
NAME opencl_icd_loader_icd2_instance_test
COMMAND icd_loader_test
)
endif ()

if (ENABLE_OPENCL_LAYERINFO)
add_test (
NAME cllayerinfo_test
Expand All @@ -47,6 +54,13 @@ set_tests_properties(opencl_icd_loader_icd2_test
ENVIRONMENT "OCL_ICD_FILENAMES=$<TARGET_FILE:OpenCLDriverStubICD2>;APP_LOG_FILE=icd_test_app_log_icd2.txt;APP_STUB_FILE=icd_test_stub_log_icd2.txt"
WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}"
)
if (ENABLE_OPENCL_LOADER_MANAGED_DISPATCH)
set_tests_properties(opencl_icd_loader_icd2_instance_test
PROPERTIES
ENVIRONMENT "OCL_ICD_FILENAMES=$<TARGET_FILE:OpenCLDriverStubICD2>;APP_LOG_FILE=icd_test_app_log_icd2_instance.txt;APP_STUB_FILE=icd_test_stub_log_icd2_instance.txt;USE_INSTANCE=1"
WORKING_DIRECTORY "${TEST_WORKING_DIRECTORY}"
)
endif()
if (ENABLE_OPENCL_LAYERINFO)
set_tests_properties(cllayerinfo_test
PROPERTIES
Expand Down
Loading

0 comments on commit 7bb3e06

Please sign in to comment.