/** * Create a new kernel wrapper object. * * @public @memberof ccl_kernel * * @param[in] prg A program wrapper object. * @param[in] kernel_name The kernel name. * @param[out] err Return location for a ::CCLErr object, or `NULL` if error * reporting is to be ignored. * @return A new kernel wrapper object. * */ CCL_EXPORT CCLKernel* ccl_kernel_new( CCLProgram* prg, const char* kernel_name, CCLErr** err) { /* Make sure err is NULL or it is not set. */ g_return_val_if_fail((err) == NULL || *(err) == NULL, NULL); /* Make sure prg is not NULL. */ g_return_val_if_fail(prg != NULL, NULL); /* Make sure kernel_name is not NULL. */ g_return_val_if_fail(kernel_name != NULL, NULL); /* Kernel wrapper object. */ CCLKernel* krnl = NULL; /* OpenCL return status. */ cl_int ocl_status; /* The OpenCL kernel object. */ cl_kernel kernel = NULL; /* Create kernel. */ kernel = clCreateKernel(ccl_program_unwrap(prg), kernel_name, &ocl_status); ccl_if_err_create_goto(*err, CCL_OCL_ERROR, CL_SUCCESS != ocl_status, ocl_status, error_handler, "%s: unable to create kernel (OpenCL error %d: %s).", CCL_STRD, ocl_status, ccl_err(ocl_status)); /* Create kernel wrapper. */ krnl = ccl_kernel_new_wrap(kernel); /* If we got here, everything is OK. */ g_assert(err == NULL || *err == NULL); goto finish; error_handler: /* If we got here there was an error, verify that it is so. */ g_assert(err == NULL || *err != NULL); krnl = NULL; finish: /* Return kernel wrapper. */ return krnl; }
/** * Tests creation, getting info from and destruction of * kernel wrapper objects. * */ static void create_info_destroy_test() { /* Test variables. */ CCLContext* ctx = NULL; cl_context context = NULL; CCLProgram* prg = NULL; cl_program program = NULL; CCLKernel* krnl = NULL; cl_kernel kernel = NULL; CCLDevice* d = NULL; CCLQueue* cq = NULL; size_t gws; size_t lws; cl_uint host_buf[CCL_TEST_KERNEL_BUF_SIZE]; cl_uint host_buf_aux[CCL_TEST_KERNEL_BUF_SIZE]; CCLBuffer* buf; GError* err = NULL; CCLEvent* evt = NULL; CCLEventWaitList ewl = NULL; const char* krnl_name; void* args[] = { NULL, NULL }; cl_bool release_krnl; cl_int ocl_status; /* Create a context with devices from first available platform. */ ctx = ccl_test_context_new(&err); g_assert_no_error(err); /* Create a new program from source and build it. */ prg = ccl_program_new_from_source( ctx, CCL_TEST_KERNEL_CONTENT, &err); g_assert_no_error(err); ccl_program_build(prg, NULL, &err); g_assert_no_error(err); /* Create a command queue. */ cq = ccl_queue_new(ctx, d, CL_QUEUE_PROFILING_ENABLE, &err); g_assert_no_error(err); /* Test three ways to create a kernel wrapper. */ for (cl_uint i = 0; i < 3; ++i) { /* Create kernel wrapper. */ switch (i) { case 0: /* Instantiate kernel directly. */ krnl = ccl_kernel_new(prg, CCL_TEST_KERNEL_NAME, &err); g_assert_no_error(err); release_krnl = CL_TRUE; break; case 1: /* Using the program utility function. No need to free * kernel in this case, because it will be freed when * program is destroyed. */ krnl = ccl_program_get_kernel( prg, CCL_TEST_KERNEL_NAME, &err); g_assert_no_error(err); release_krnl = CL_FALSE; break; case 2: /* Using the "wrap" constructor. */ kernel = clCreateKernel(ccl_program_unwrap(prg), CCL_TEST_KERNEL_NAME, &ocl_status); g_assert_cmpint(ocl_status, ==, CL_SUCCESS); krnl = ccl_kernel_new_wrap(kernel); g_assert_cmphex(GPOINTER_TO_UINT(kernel), ==, GPOINTER_TO_UINT(ccl_kernel_unwrap(krnl))); release_krnl = CL_TRUE; break; } /* Get some kernel info, compare it with expected info. */ /* Get kernel function name from kernel info, compare it with the * expected value. */ krnl_name = ccl_kernel_get_info_array( krnl, CL_KERNEL_FUNCTION_NAME, char*, &err); g_assert_no_error(err); g_assert_cmpstr(krnl_name, ==, CCL_TEST_KERNEL_NAME); /* Check if the kernel context is the same as the initial context * and the program context. */ context = ccl_kernel_get_info_scalar( krnl, CL_KERNEL_CONTEXT, cl_context, &err); g_assert_no_error(err); g_assert(context == ccl_context_unwrap(ctx)); program = ccl_kernel_get_info_scalar( krnl, CL_KERNEL_PROGRAM, cl_program, &err); g_assert_no_error(err); g_assert(program == ccl_program_unwrap(prg)); #ifndef OPENCL_STUB cl_uint ocl_ver; /* Get OpenCL version of kernel's underlying platform. */ ocl_ver = ccl_kernel_get_opencl_version(krnl, &err); g_assert_no_error(err); (void)ocl_ver; #ifdef CL_VERSION_1_1 size_t kwgz; size_t* kcwgs; CCLDevice* dev = NULL; /* If platform supports kernel work group queries, get kernel * work group information and compare it with expected info. */ if (ocl_ver >= 110) { dev = ccl_context_get_device(ctx, 0, &err); g_assert_no_error(err); kwgz = ccl_kernel_get_workgroup_info_scalar( krnl, dev, CL_KERNEL_WORK_GROUP_SIZE, size_t, &err); g_assert_no_error(err); (void)kwgz; kcwgs = ccl_kernel_get_workgroup_info_array(krnl, dev, CL_KERNEL_COMPILE_WORK_GROUP_SIZE, size_t*, &err); g_assert_no_error(err); (void)kcwgs; } #endif /* ifdef CL_VERSION_1_1 */ #ifdef CL_VERSION_1_2 cl_kernel_arg_address_qualifier kaaq; char* kernel_arg_type_name; char* kernel_arg_name; /* If platform supports kernel argument queries, get kernel argument * information and compare it with expected info. */ if (ocl_ver >= 120) { kaaq = ccl_kernel_get_arg_info_scalar(krnl, 0, CL_KERNEL_ARG_ADDRESS_QUALIFIER, cl_kernel_arg_address_qualifier, &err); g_assert((err == NULL) || (err->code == CCL_ERROR_INFO_UNAVAILABLE_OCL)); if (err == NULL) { g_assert_cmphex(kaaq, ==, CL_KERNEL_ARG_ADDRESS_GLOBAL); } else {