From: Junyan He <[email protected]> 1. Make the code logic more clear, fix some error check problems. 2. Add devices list check, we may have more than 1 device later.
Signed-off-by: Junyan He <[email protected]> --- src/cl_api.c | 106 ++----------------------------- src/cl_api_context.c | 89 ++++++++++++++++++++++++++ src/cl_context.c | 176 ++++++++++++++++++++++++++++++--------------------- src/cl_context.h | 31 ++++----- src/cl_device_id.c | 36 +++++++++++ src/cl_device_id.h | 2 + 6 files changed, 246 insertions(+), 194 deletions(-) diff --git a/src/cl_api.c b/src/cl_api.c index 1f45e88..945d6c1 100644 --- a/src/cl_api.c +++ b/src/cl_api.c @@ -67,31 +67,6 @@ typedef intptr_t cl_device_partition_property; return RET; \ } while(0) -static cl_int -cl_check_device_type(cl_device_type device_type) -{ - const cl_device_type valid = CL_DEVICE_TYPE_GPU - | CL_DEVICE_TYPE_CPU - | CL_DEVICE_TYPE_ACCELERATOR - | CL_DEVICE_TYPE_DEFAULT - | CL_DEVICE_TYPE_CUSTOM; - - if( (device_type & valid) == 0) { - return CL_INVALID_DEVICE_TYPE; - } - if(UNLIKELY(!(device_type & CL_DEVICE_TYPE_DEFAULT) && !(device_type & CL_DEVICE_TYPE_GPU))) - return CL_DEVICE_NOT_FOUND; - - return CL_SUCCESS; -} - -static cl_int -cl_device_id_is_ok(const cl_device_id device) -{ - if(UNLIKELY(device == NULL)) return CL_FALSE; - return device != cl_get_gt_device() ? CL_FALSE : CL_TRUE; -} - cl_int clGetPlatformIDs(cl_uint num_entries, cl_platform_id * platforms, @@ -112,7 +87,8 @@ clGetDeviceIDs(cl_platform_id platform, cl_device_id * devices, cl_uint * num_devices) { - cl_int err = CL_SUCCESS; + const cl_device_type valid_type = CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_ACCELERATOR | + CL_DEVICE_TYPE_DEFAULT | CL_DEVICE_TYPE_CUSTOM; /* Check parameter consistency */ if (UNLIKELY(devices == NULL && num_devices == NULL)) @@ -121,10 +97,8 @@ clGetDeviceIDs(cl_platform_id platform, return CL_INVALID_PLATFORM; if (UNLIKELY(devices && num_entries == 0)) return CL_INVALID_VALUE; - - err = cl_check_device_type(device_type); - if(err != CL_SUCCESS) - return err; + if ((device_type & valid_type) == 0) + return CL_INVALID_DEVICE_TYPE; return cl_get_device_ids(platform, device_type, @@ -169,78 +143,6 @@ clReleaseDevice(cl_device_id device) return CL_SUCCESS; } -cl_context -clCreateContext(const cl_context_properties * properties, - cl_uint num_devices, - const cl_device_id * devices, - void (* pfn_notify) (const char*, const void*, size_t, void*), - void * user_data, - cl_int * errcode_ret) -{ - cl_int err = CL_SUCCESS; - cl_context context = NULL; - - /* Assert parameters correctness */ - INVALID_VALUE_IF (devices == NULL); - INVALID_VALUE_IF (num_devices == 0); - INVALID_VALUE_IF (pfn_notify == NULL && user_data != NULL); - - /* Now check if the user is asking for the right device */ - INVALID_DEVICE_IF (cl_device_id_is_ok(*devices) == CL_FALSE); - - context = cl_create_context(properties, - num_devices, - devices, - pfn_notify, - user_data, - &err); - initialize_env_var(); -error: - if (errcode_ret) - *errcode_ret = err; - return context; -} - -cl_context -clCreateContextFromType(const cl_context_properties * properties, - cl_device_type device_type, - void (CL_CALLBACK *pfn_notify) (const char *, const void *, size_t, void *), - void * user_data, - cl_int * errcode_ret) -{ - cl_context context = NULL; - cl_int err = CL_SUCCESS; - cl_device_id devices[1]; - cl_uint num_devices = 1; - - INVALID_VALUE_IF (pfn_notify == NULL && user_data != NULL); - - err = cl_check_device_type(device_type); - if(err != CL_SUCCESS) { - goto error; - } - - err = cl_get_device_ids(NULL, - device_type, - 1, - &devices[0], - &num_devices); - if (err != CL_SUCCESS) { - goto error; - } - - context = cl_create_context(properties, - num_devices, - devices, - pfn_notify, - user_data, - &err); -error: - if (errcode_ret) - *errcode_ret = err; - return context; -} - cl_command_queue clCreateCommandQueue(cl_context context, cl_device_id device, diff --git a/src/cl_api_context.c b/src/cl_api_context.c index f52c56a..2160950 100644 --- a/src/cl_api_context.c +++ b/src/cl_api_context.c @@ -17,6 +17,95 @@ */ #include "cl_context.h" +#include "cl_device_id.h" +#include "cl_alloc.h" + +cl_context +clCreateContext(const cl_context_properties *properties, + cl_uint num_devices, + const cl_device_id *devices, + void (*pfn_notify)(const char *, const void *, size_t, void *), + void *user_data, + cl_int *errcode_ret) +{ + cl_int err = CL_SUCCESS; + cl_context context = NULL; + + do { + /* Assure parameters correctness */ + if (devices == NULL) { + err = CL_INVALID_VALUE; + break; + } + + if (num_devices == 0) { + err = CL_INVALID_VALUE; + break; + } + + if (pfn_notify == NULL && user_data != NULL) { + err = CL_INVALID_VALUE; + break; + } + + err = cl_devices_list_check(num_devices, devices); + if (err != CL_SUCCESS) + break; + + context = cl_create_context(properties, num_devices, devices, pfn_notify, user_data, &err); + } while (0); + + if (errcode_ret) + *errcode_ret = err; + return context; +} + +cl_context +clCreateContextFromType(const cl_context_properties *properties, + cl_device_type device_type, + void(CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *), + void *user_data, + cl_int *errcode_ret) +{ + cl_context context = NULL; + cl_int err = CL_SUCCESS; + cl_device_id *devices = NULL; + cl_uint num_devices = 0; + const cl_device_type valid_type = CL_DEVICE_TYPE_GPU | CL_DEVICE_TYPE_CPU | CL_DEVICE_TYPE_ACCELERATOR | + CL_DEVICE_TYPE_DEFAULT | CL_DEVICE_TYPE_CUSTOM; + + do { + /* Assure parameters correctness */ + if (pfn_notify == NULL && user_data != NULL) { + err = CL_INVALID_VALUE; + break; + } + + if ((device_type & valid_type) == 0) { + err = CL_INVALID_DEVICE_TYPE; + break; + } + + /* Get the devices num first. */ + err = cl_get_device_ids(NULL, device_type, 0, NULL, &num_devices); + if (err != CL_SUCCESS) + break; + + assert(num_devices > 0); + devices = cl_malloc(num_devices * sizeof(cl_device_id)); + err = cl_get_device_ids(NULL, device_type, num_devices, &devices[0], &num_devices); + if (err != CL_SUCCESS) + break; + + context = cl_create_context(properties, num_devices, devices, pfn_notify, user_data, &err); + } while (0); + + if (devices) + cl_free(devices); + if (errcode_ret) + *errcode_ret = err; + return context; +} cl_int clRetainContext(cl_context context) diff --git a/src/cl_context.c b/src/cl_context.c index 229ab96..4617f11 100644 --- a/src/cl_context.c +++ b/src/cl_context.c @@ -30,6 +30,7 @@ #include "cl_khr_icd.h" #include "cl_kernel.h" #include "cl_program.h" +#include "performance.h" #include "CL/cl.h" #include "CL/cl_gl.h" @@ -167,80 +168,146 @@ cl_context_remove_program(cl_context ctx, cl_program program) { program->ctx = NULL; } - -#define CHECK(var) \ - if (var) \ - return CL_INVALID_PROPERTY; \ - else \ - var = 1; - -static cl_int +LOCAL cl_int cl_context_properties_process(const cl_context_properties *prop, struct _cl_context_prop *cl_props, cl_uint * prop_len) { int set_cl_context_platform = 0, + set_cl_context_interop_user_sync = 0, set_cl_gl_context_khr = 0, set_cl_egl_display_khr = 0, set_cl_glx_display_khr = 0, set_cl_wgl_hdc_khr = 0, set_cl_cgl_sharegroup_khr = 0; - cl_int err = CL_SUCCESS; cl_props->gl_type = CL_GL_NOSHARE; cl_props->platform_id = 0; + memset(cl_props, 0, sizeof(_cl_context_prop)); + *prop_len = 0; if (prop == NULL) - goto exit; - + return CL_SUCCESS; + /* All the properties can just be set once. */ while(*prop) { + if (prop + 1 == NULL) { + return CL_INVALID_PROPERTY; + } + switch (*prop) { case CL_CONTEXT_PLATFORM: - CHECK (set_cl_context_platform); + if (set_cl_context_platform) { + return CL_INVALID_PROPERTY; + } + set_cl_context_platform = 1; cl_props->platform_id = *(prop + 1); - if (UNLIKELY((cl_platform_id) cl_props->platform_id != cl_get_platform_default())) { - err = CL_INVALID_PLATFORM; - goto error; + + /* We now just support one platform. */ + if (UNLIKELY((cl_platform_id)cl_props->platform_id != cl_get_platform_default())) { + return CL_INVALID_PLATFORM; } break; + + case CL_CONTEXT_INTEROP_USER_SYNC: + if (set_cl_context_interop_user_sync) { + return CL_INVALID_PROPERTY; + } + set_cl_context_interop_user_sync = 1; + cl_props->interop_user_sync = *(prop + 1); + break; + case CL_GL_CONTEXT_KHR: - CHECK (set_cl_gl_context_khr); + if (set_cl_gl_context_khr || set_cl_cgl_sharegroup_khr) { + return CL_INVALID_PROPERTY; + } + set_cl_gl_context_khr = 1; cl_props->gl_context = *(prop + 1); break; + case CL_EGL_DISPLAY_KHR: - CHECK (set_cl_egl_display_khr); + if (set_cl_cgl_sharegroup_khr || set_cl_egl_display_khr || + set_cl_glx_display_khr || set_cl_wgl_hdc_khr) { + return CL_INVALID_PROPERTY; + } cl_props->gl_type = CL_GL_EGL_DISPLAY; cl_props->egl_display = *(prop + 1); break; + case CL_GLX_DISPLAY_KHR: - CHECK (set_cl_glx_display_khr); + if (set_cl_cgl_sharegroup_khr || set_cl_egl_display_khr || + set_cl_glx_display_khr || set_cl_wgl_hdc_khr) { + return CL_INVALID_PROPERTY; + } cl_props->gl_type = CL_GL_GLX_DISPLAY; cl_props->glx_display = *(prop + 1); break; + case CL_WGL_HDC_KHR: - CHECK (set_cl_wgl_hdc_khr); + if (set_cl_cgl_sharegroup_khr || set_cl_egl_display_khr || + set_cl_glx_display_khr || set_cl_wgl_hdc_khr) { + return CL_INVALID_PROPERTY; + } cl_props->gl_type = CL_GL_WGL_HDC; cl_props->wgl_hdc = *(prop + 1); break; + case CL_CGL_SHAREGROUP_KHR: - CHECK (set_cl_cgl_sharegroup_khr); + if (set_cl_cgl_sharegroup_khr || set_cl_egl_display_khr || + set_cl_glx_display_khr || set_cl_wgl_hdc_khr || set_cl_gl_context_khr) { + return CL_INVALID_PROPERTY; + } cl_props->gl_type = CL_GL_CGL_SHAREGROUP; cl_props->cgl_sharegroup = *(prop + 1); break; default: - err = CL_INVALID_PROPERTY; - goto error; + return CL_INVALID_PROPERTY; } + prop += 2; *prop_len += 2; } + + /* Add the last NULL pointer. */ (*prop_len)++; -exit: -error: - return err; + return CL_SUCCESS; } +static cl_context +cl_context_new(cl_context_prop props, const cl_context_properties* properties, cl_uint prop_len) +{ + cl_context ctx = cl_calloc(1, sizeof(_cl_context)); + if (ctx == NULL) + return NULL; + + if (properties) { + ctx->prop_user = cl_calloc(prop_len, sizeof(cl_context_properties)); + if (ctx->prop_user == NULL) { + cl_free(ctx); + return NULL; + } + memcpy(ctx->prop_user, properties, sizeof(cl_context_properties) * prop_len); + } + ctx->prop_len = prop_len; + + ctx->drv = cl_driver_new(props); + if (ctx->drv == NULL) { + cl_free(ctx); + if (ctx->prop_user) + cl_free(ctx->prop_user); + return NULL; + } + + CL_OBJECT_INIT_BASE(ctx, CL_OBJECT_CONTEXT_MAGIC); + list_init(&ctx->queues); + list_init(&ctx->mem_objects); + list_init(&ctx->samplers); + list_init(&ctx->events); + list_init(&ctx->programs); + ctx->queue_cookie = 1; + ctx->ver = cl_driver_get_ver(ctx->drv); + return ctx; +} LOCAL cl_context cl_create_context(const cl_context_properties * properties, @@ -250,70 +317,33 @@ cl_create_context(const cl_context_properties * properties, void * user_data, cl_int * errcode_ret) { - /* cl_platform_id platform = NULL; */ - struct _cl_context_prop props; cl_context ctx = NULL; - cl_int err = CL_SUCCESS; + struct _cl_context_prop props; cl_uint prop_len = 0; - /* XXX */ - FATAL_IF (num_devices != 1, "Only one device is supported"); - /* Check that we are getting the right platform */ - if (UNLIKELY(((err = cl_context_properties_process(properties, &props, &prop_len)) != CL_SUCCESS))) - goto error; + *errcode_ret = cl_context_properties_process(properties, &props, &prop_len); + if (*errcode_ret != CL_SUCCESS) + return NULL; /* We are good */ - if (UNLIKELY((ctx = cl_context_new(&props)) == NULL)) { - err = CL_OUT_OF_HOST_MEMORY; - goto error; + ctx = cl_context_new(&props, properties, prop_len); + if (ctx == NULL) { + *errcode_ret = CL_OUT_OF_HOST_MEMORY; + return NULL; } - if(properties != NULL && prop_len > 0) { - TRY_ALLOC (ctx->prop_user, CALLOC_ARRAY(cl_context_properties, prop_len)); - memcpy(ctx->prop_user, properties, sizeof(cl_context_properties)*prop_len); - } - ctx->prop_len = prop_len; /* Attach the device to the context */ + assert(num_devices == 1); // TODO: multi devices later. ctx->device = *devices; /* Save the user callback and user data*/ ctx->pfn_notify = pfn_notify; ctx->user_data = user_data; - cl_driver_set_atomic_flag(ctx->drv, ctx->device->atomic_test_result); - -exit: - if (errcode_ret != NULL) - *errcode_ret = err; - return ctx; -error: - cl_context_delete(ctx); - ctx = NULL; - goto exit; -} - -LOCAL cl_context -cl_context_new(struct _cl_context_prop *props) -{ - cl_context ctx = NULL; - TRY_ALLOC_NO_ERR (ctx, CALLOC(struct _cl_context)); - CL_OBJECT_INIT_BASE(ctx, CL_OBJECT_CONTEXT_MAGIC); - list_init(&ctx->queues); - list_init(&ctx->mem_objects); - list_init(&ctx->samplers); - list_init(&ctx->events); - list_init(&ctx->programs); - ctx->queue_cookie = 1; - TRY_ALLOC_NO_ERR (ctx->drv, cl_driver_new(props)); - ctx->props = *props; - ctx->ver = cl_driver_get_ver(ctx->drv); + cl_driver_set_atomic_flag(ctx->drv, ctx->device->atomic_test_result); -exit: + initialize_env_var(); return ctx; -error: - cl_context_delete(ctx); - ctx = NULL; - goto exit; } LOCAL void diff --git a/src/cl_context.h b/src/cl_context.h index b2903a7..e582fe2 100644 --- a/src/cl_context.h +++ b/src/cl_context.h @@ -82,23 +82,26 @@ enum _cl_internal_ker_type { CL_INTERNAL_KERNEL_MAX }; -struct _cl_context_prop { +/* Include all the possible properties for context. */ +typedef struct _cl_context_prop { cl_context_properties platform_id; - enum _cl_gl_context_type gl_type; + cl_bool interop_user_sync; + /* Extensions. */ cl_context_properties gl_context; + enum _cl_gl_context_type gl_type; union { cl_context_properties egl_display; cl_context_properties glx_display; cl_context_properties wgl_hdc; cl_context_properties cgl_sharegroup; }; -}; +} _cl_context_prop; #define IS_EGL_CONTEXT(ctx) (ctx->props.gl_type == CL_GL_EGL_DISPLAY) #define EGL_DISP(ctx) (EGLDisplay)(ctx->props.egl_display) #define EGL_CTX(ctx) (EGLContext)(ctx->props.gl_context) /* Encapsulate the whole device */ -struct _cl_context { +typedef struct _cl_context { _cl_base_object base; cl_driver drv; /* Handles HW or simulator */ cl_device_id device; /* All information about the GPU device */ @@ -129,7 +132,7 @@ struct _cl_context { /* User's callback when error occur in context */ void *user_data; /* A pointer to user supplied data */ -}; +} _cl_context; #define CL_OBJECT_CONTEXT_MAGIC 0x20BBCADE993134AALL #define CL_OBJECT_IS_CONTEXT(obj) ((obj && \ @@ -146,23 +149,13 @@ extern void cl_context_add_event(cl_context ctx, cl_event sampler); extern void cl_context_remove_event(cl_context ctx, cl_event sampler); extern void cl_context_add_program(cl_context ctx, cl_program program); extern void cl_context_remove_program(cl_context ctx, cl_program program); - -/* Implement OpenCL function */ -extern cl_context cl_create_context(const cl_context_properties*, - cl_uint, - const cl_device_id*, +extern cl_context cl_create_context(const cl_context_properties*, cl_uint, const cl_device_id*, void (CL_CALLBACK * pfn_notify) (const char*, const void*, size_t, void*), - void *, - cl_int*); - -/* Allocate and initialize a context */ -extern cl_context cl_context_new(struct _cl_context_prop *); - -/* Destroy and deallocate a context */ + void *, cl_int*); extern void cl_context_delete(cl_context); - -/* Increment the context reference counter */ extern void cl_context_add_ref(cl_context); +extern cl_int cl_context_properties_process(const cl_context_properties *prop, + struct _cl_context_prop *cl_props, cl_uint * prop_len); /* Create the command queue from the given context and device */ extern cl_command_queue cl_context_create_queue(cl_context, diff --git a/src/cl_device_id.c b/src/cl_device_id.c index 61d2d78..268fa61 100644 --- a/src/cl_device_id.c +++ b/src/cl_device_id.c @@ -869,6 +869,10 @@ cl_get_device_ids(cl_platform_id platform, { cl_device_id device; + // TODO: just GPU now. + if(!(device_type & (CL_DEVICE_TYPE_DEFAULT | CL_DEVICE_TYPE_GPU))) + return CL_DEVICE_NOT_FOUND; + /* Do we have a usable device? */ device = cl_get_gt_device(); if (device) { @@ -1510,3 +1514,35 @@ cl_get_kernel_subgroup_info(cl_kernel kernel, error: return err; } + +LOCAL cl_int +cl_devices_list_check(cl_uint num_devices, const cl_device_id *devices) +{ + cl_uint i; + + if (devices == NULL) + return CL_INVALID_DEVICE; + + assert(num_devices > 0); + for (i = 0; i < num_devices; i++) { + if (!CL_OBJECT_IS_DEVICE(devices[i])) { + return CL_INVALID_DEVICE; + } + + if (devices[i]->available == CL_FALSE) { + return CL_DEVICE_NOT_AVAILABLE; + } + + // We now just support one platform. + if (devices[i]->platform != cl_get_platform_default()) { + return CL_INVALID_DEVICE; + } + + // TODO: We now just support Gen Device. + if (devices[i] != cl_get_gt_device()) { + return CL_INVALID_DEVICE; + } + } + + return CL_SUCCESS; +} diff --git a/src/cl_device_id.h b/src/cl_device_id.h index 8cd55bb..12d6a6e 100644 --- a/src/cl_device_id.h +++ b/src/cl_device_id.h @@ -130,6 +130,8 @@ struct _cl_device_id { ((cl_base_object)obj)->magic == CL_OBJECT_DEVICE_MAGIC && \ CL_OBJECT_GET_REF(obj) >= 1)) +extern cl_int cl_devices_list_check(cl_uint num_devices, const cl_device_id *devices); + /* Get a device from the given platform */ extern cl_int cl_get_device_ids(cl_platform_id platform, cl_device_type device_type, -- 2.7.4 _______________________________________________ Beignet mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/beignet
