Skip to content

Commit

Permalink
WIP: instance support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerilk committed Feb 20, 2024
1 parent e551eec commit 92b9c09
Show file tree
Hide file tree
Showing 9 changed files with 504 additions and 32 deletions.
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 KHR_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)khrIcdOsLibraryGetFunctionAddress(library, "clIcdGetFunctionAddressForPlatformKHR");
p_clIcdSetPlatformDispatchData = (clIcdSetPlatformDispatchDataKHR_fn)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clIcdSetPlatformDispatchDataKHR");
p_clIcdCreateInstancePlatform = (clIcdCreateInstancePlatformKHR_fn)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "clIcdCreateInstancePlatformKHR");
p_clIcdDestroyInstancePlatform = (clIcdDestroyInstancePlatformKHR_fn)(size_t)khrIcdOsLibraryGetFunctionAddress(library, "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
11 changes: 11 additions & 0 deletions loader/icd.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,24 @@ struct KHRicdVendorRec
#if KHR_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;
};

struct _cl_instance
{
cl_uint num_platforms;
cl_platform_id *platforms;
KHRicdVendor **vendors;
struct KHRDisp *dispDatas;
};

// the global state
extern KHRicdVendor * khrIcdVendors;

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

#if KHR_LOADER_MANAGED_DISPATCH

static clCreateInstanceKHR_t clCreateInstanceKHR;
cl_instance CL_API_CALL
clCreateInstanceKHR(
const cl_instance_properties *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 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_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 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;
static cl_int clGetPlatformIDsForInstanceKHR(
cl_instance 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 //KHR_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 +285,13 @@ static void* khrIcdGetExtensionFunctionAddress(const char* function_name)
// cl_icdl
KHR_ICD_CHECK_EXTENSION_FUNCTION(clGetICDLoaderInfoOCLICD);

#if KHR_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
48 changes: 48 additions & 0 deletions loader/icd_dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,54 @@ extern void khrIcd2PopulateDispatchTable(

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

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

typedef struct _cl_instance *cl_instance;
typedef cl_properties cl_instance_properties;

typedef cl_instance CL_API_CALL
clCreateInstanceKHR_t(
const cl_instance_properties *properties,
cl_int *errcode_ret);

typedef clCreateInstanceKHR_t *
clCreateInstanceKHR_fn;

typedef cl_int CL_API_CALL
clDestroyInstanceKHR_t(
cl_instance instance);

typedef clDestroyInstanceKHR_t *
clDestroyInstanceKHR_fn;

typedef cl_int CL_API_CALL
clGetPlatformIDsForInstanceKHR_t(
cl_instance 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_ENABLE_LOADER_MANAGED_DISPATCH) && !defined(CL_INVALID_INSTANCE_KHR)

#if defined(CL_ENABLE_LOADER_MANAGED_DISPATCH)
#define KHR_LOADER_MANAGED_DISPATCH 1
#else
Expand Down
11 changes: 11 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ add_test (
NAME opencl_icd_loader_icd2_test
COMMAND icd_loader_test
)
add_test (
NAME opencl_icd_loader_icd2_instance_test
COMMAND icd_loader_test
)

if (ENABLE_OPENCL_LAYERINFO)
add_test (
Expand All @@ -47,6 +51,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 92b9c09

Please sign in to comment.