diff options
-rw-r--r-- | include/cl_driver.h | 3 | ||||
-rw-r--r-- | libclapi/cl_kernel.c | 32 |
2 files changed, 34 insertions, 1 deletions
diff --git a/include/cl_driver.h b/include/cl_driver.h index fe0021c5..c71a1532 100644 --- a/include/cl_driver.h +++ b/include/cl_driver.h @@ -48,7 +48,8 @@ typedef struct _cl_driver { cl_int (*release_program)(cl_program program, const cl_device_id device); cl_int (*get_program_kernel_names)(cl_program program, const cl_device_id device, char *names, cl_uint name_sz, cl_uint* ret_sz, cl_uint* ker_num); - + cl_int (*create_kernel)(cl_kernel kernel, const cl_device_id device); + cl_int (*release_kernel)(cl_kernel kernel, const cl_device_id device); diff --git a/libclapi/cl_kernel.c b/libclapi/cl_kernel.c index e03bd29d..91083219 100644 --- a/libclapi/cl_kernel.c +++ b/libclapi/cl_kernel.c @@ -26,6 +26,7 @@ #include "cl_kernel.h" #include "cl_program.h" #include "cl_context.h" +#include "cl_device_id.h" static void cl_argument_release(cl_argument arg) { @@ -97,10 +98,19 @@ LOCAL void cl_retain_kernel(cl_kernel k) LOCAL void cl_release_kernel(cl_kernel k) { + cl_uint i; + assert(k); if (atomic_dec(&k->ref_n) > 1) return; + for (i = 0; i < k->program->ctx->device_num; i++) { + if (k->program->valid[i] == 0) // We do not build for that device. + continue; + + k->program->ctx->devices[i]->driver->release_kernel(k, k->program->ctx->devices[i]); + } + cl_kernel_delete(k); } @@ -108,6 +118,8 @@ LOCAL cl_kernel cl_create_kernel(cl_program p, char* kernel_name, cl_int* errcod { cl_kernel k = NULL; cl_int err = CL_SUCCESS; + cl_uint created = 0; + cl_uint i; k = cl_kernel_new(p, kernel_name); if (UNLIKELY(k == NULL)) { @@ -115,11 +127,31 @@ LOCAL cl_kernel cl_create_kernel(cl_program p, char* kernel_name, cl_int* errcod goto error; } + for (i = 0; i < p->ctx->device_num; i++) { + if (p->valid[i] == 0) // We do not build for that device. + continue; + + err = p->ctx->devices[i]->driver->create_kernel(k, p->ctx->devices[i]); + if (err != CL_SUCCESS) + break; + + created = i; + } + if (errcode_ret) *errcode_ret = err; return k; error: + if (created) { + for (i = 0; i < created; i++) { + if (p->valid[i] == 0) // We do not build for that device. + continue; + + p->ctx->devices[i]->driver->release_kernel(k, p->ctx->devices[i]); + } + } + if (k) cl_kernel_delete(k); if (errcode_ret) |