31 #include "_ccl_abstract_wrapper.h"
36 typedef cl_int (*ccl_wrapper_info_fp)(void);
39 static GHashTable* wrappers = NULL;
41 G_LOCK_DEFINE(wrappers);
44 static const char* ccl_class_names[] = {
"Buffer",
"Context",
"Device",
"Event",
45 "Image",
"Kernel",
"Platform",
"Program",
"Sampler",
"Queue",
"None", NULL};
49 static const ccl_wrapper_info_fp info_funs[] = {
50 (ccl_wrapper_info_fp) clGetContextInfo,
51 (ccl_wrapper_info_fp) clGetDeviceInfo,
52 (ccl_wrapper_info_fp) clGetEventInfo,
53 (ccl_wrapper_info_fp) clGetEventProfilingInfo,
54 (ccl_wrapper_info_fp) clGetImageInfo,
55 (ccl_wrapper_info_fp) clGetKernelInfo,
57 (ccl_wrapper_info_fp) ccl_kernel_get_arg_info_adapter,
61 (ccl_wrapper_info_fp) clGetKernelWorkGroupInfo,
67 (ccl_wrapper_info_fp) clGetMemObjectInfo,
68 (ccl_wrapper_info_fp) clGetPlatformInfo,
69 (ccl_wrapper_info_fp) clGetProgramInfo,
70 (ccl_wrapper_info_fp) clGetProgramBuildInfo,
71 (ccl_wrapper_info_fp) clGetSamplerInfo,
72 (ccl_wrapper_info_fp) clGetCommandQueueInfo,
125 g_return_val_if_fail(cl_object != NULL, NULL);
135 if (wrappers == NULL) {
136 wrappers = g_hash_table_new_full(
137 g_direct_hash, g_direct_equal, NULL, NULL);
141 w = g_hash_table_lookup(wrappers, cl_object);
148 w->cl_object = cl_object;
152 g_mutex_init(&w->info->mutex);
156 g_hash_table_insert(wrappers, cl_object, w);
189 cl_bool ccl_wrapper_unref(
CCLWrapper* wrapper,
size_t size,
190 ccl_wrapper_release_fields rel_fields_fun,
191 ccl_wrapper_release_cl_object rel_cl_fun,
CCLErr** err) {
194 g_return_val_if_fail(wrapper != NULL, CL_FALSE);
197 g_return_val_if_fail(err == NULL || *err == NULL, CL_FALSE);
200 cl_bool destroyed = CL_FALSE;
205 #ifdef CCL_DEBUG_OBJ_LIFETIME
208 g_debug(
"Destroy/unref. CCL%s(%p)",
214 if (g_atomic_int_dec_and_test(&wrapper->ref_count)) {
220 if (rel_cl_fun != NULL) {
221 ocl_status = rel_cl_fun(wrapper->cl_object);
222 if (ocl_status != CL_SUCCESS) {
224 "%s: unable to create release OpenCL object "
225 "(OpenCL error %d: %s).",
226 CCL_STRD, ocl_status,
ccl_err(ocl_status));
231 if (wrapper->info->table != NULL) {
232 g_hash_table_destroy(wrapper->info->table);
234 if (wrapper->info->old_info != NULL) {
235 g_slist_free_full(wrapper->info->old_info,
236 (GDestroyNotify) ccl_wrapper_info_destroy);
238 g_mutex_clear(&wrapper->info->mutex);
244 g_hash_table_remove(wrappers, wrapper->cl_object);
245 if (g_hash_table_size(wrappers) == 0) {
246 g_hash_table_destroy(wrappers);
252 if (rel_fields_fun != NULL)
253 rel_fields_fun(wrapper);
256 g_slice_free1(size, wrapper);
277 void ccl_wrapper_add_info(
CCLWrapper* wrapper, cl_uint param_name,
281 g_return_if_fail(wrapper != NULL);
283 g_return_if_fail(info != NULL);
286 g_mutex_lock(&wrapper->info->mutex);
290 if (wrapper->info->table == NULL) {
291 wrapper->info->table = g_hash_table_new_full(
292 g_direct_hash, g_direct_equal,
293 NULL, (GDestroyNotify) ccl_wrapper_info_destroy);
298 if (g_hash_table_contains(
299 wrapper->info->table, GUINT_TO_POINTER(param_name))) {
307 wrapper->info->table, GUINT_TO_POINTER(param_name));
310 wrapper->info->old_info =
311 g_slist_prepend(wrapper->info->old_info, info_old);
315 wrapper->info->table, GUINT_TO_POINTER(param_name));
320 g_hash_table_insert(wrapper->info->table,
321 GUINT_TO_POINTER(param_name), info);
324 g_mutex_unlock(&wrapper->info->mutex);
342 info->
value = g_slice_alloc0(size);
362 g_return_if_fail(info != NULL);
385 g_return_if_fail(wrapper != NULL);
388 g_atomic_int_inc(&wrapper->ref_count);
390 #ifdef CCL_DEBUG_OBJ_LIFETIME
393 g_debug(
"New/ref. CCL%s(%p)",
413 g_return_val_if_fail(wrapper != NULL, -1);
416 return wrapper->ref_count;
432 g_return_val_if_fail(wrapper != NULL, NULL);
435 return wrapper->cl_object;
464 CCLWrapper* wrapper2, cl_uint param_name,
size_t min_size,
468 g_return_val_if_fail((err) == NULL || *(err) == NULL, NULL);
471 g_return_val_if_fail(wrapper1 != NULL, NULL);
474 g_return_val_if_fail((info_type >= 0) && (info_type <
CCL_INFO_END), NULL);
483 ccl_wrapper_info_fp info_fun = info_funs[info_type];
486 g_mutex_lock(&wrapper1->info->mutex);
487 contains = wrapper1->info->table != NULL
488 ? g_hash_table_contains(
489 wrapper1->info->table, GUINT_TO_POINTER(param_name))
491 g_mutex_unlock(&wrapper1->info->mutex);
496 if ((!use_cache) || (!contains)) {
504 ocl_status = (wrapper2 == NULL)
505 ? ((ccl_wrapper_info_fp1) info_fun)(wrapper1->cl_object,
506 param_name, 0, NULL, &size_ret)
507 : ((ccl_wrapper_info_fp2) info_fun)(wrapper1->cl_object,
508 wrapper2->cl_object, param_name, 0, NULL, &size_ret);
511 #if defined(__APPLE__) || defined(__MACOSX)
512 if ((ocl_status == CL_INVALID_VALUE)
513 && (info_fun == (ccl_wrapper_info_fp) clGetEventProfilingInfo))
514 ocl_status = CL_SUCCESS;
518 CL_SUCCESS != ocl_status, ocl_status, error_handler,
519 "%s: get info [size] (OpenCL error %d: %s).",
520 CCL_STRD, ocl_status,
ccl_err(ocl_status));
523 "%s: the requested info is unavailable (info size is 0).",
527 info = ccl_wrapper_info_new(size_ret);
530 ocl_status = (wrapper2 == NULL)
531 ? ((ccl_wrapper_info_fp1) info_fun)(wrapper1->cl_object,
532 param_name, size_ret, info->
value, NULL)
533 : ((ccl_wrapper_info_fp2) info_fun)(wrapper1->cl_object,
534 wrapper2->cl_object, param_name, size_ret, info->
value,
537 CL_SUCCESS != ocl_status, ocl_status, error_handler,
538 "%s: get context info [info] (OpenCL error %d: %s).",
539 CCL_STRD, ocl_status,
ccl_err(ocl_status));
542 ccl_wrapper_add_info(wrapper1, param_name, info);
548 g_mutex_lock(&wrapper1->info->mutex);
549 info = g_hash_table_lookup(
550 wrapper1->info->table, GUINT_TO_POINTER(param_name));
551 g_mutex_unlock(&wrapper1->info->mutex);
556 g_assert(err == NULL || *err == NULL);
561 g_assert(err == NULL || *err != NULL);
565 if (info != NULL) ccl_wrapper_info_destroy(info);
566 info = ccl_wrapper_info_new(min_size);
567 ccl_wrapper_add_info(wrapper1, param_name, info);
601 CCLWrapper* wrapper2, cl_uint param_name,
size_t min_size,
605 g_return_val_if_fail(err == NULL || *err == NULL, NULL);
608 g_return_val_if_fail(wrapper1 != NULL, NULL);
611 g_return_val_if_fail((info_type >= 0) && (info_type <
CCL_INFO_END), NULL);
615 param_name, min_size, info_type, use_cache, err);
618 return diw != NULL ? diw->
value : NULL;
642 CCLWrapper* wrapper2, cl_uint param_name,
size_t min_size,
646 g_return_val_if_fail(err == NULL || *err == NULL, 0);
649 g_return_val_if_fail(wrapper1 != NULL, 0);
652 g_return_val_if_fail((info_type >= 0) && (info_type <
CCL_INFO_END), 0);
656 param_name, min_size, info_type, use_cache, err);
659 return diw != NULL ? diw->
size : 0;
692 GString* logstr = NULL;
700 check = (wrappers == NULL);
708 g_debug(
"Wrappers table is empty");
715 g_hash_table_iter_init(&iter, wrappers);
718 logstr = g_string_new(
"");
719 g_string_append_printf(logstr,
720 "There are %u wrappers in table: ", g_hash_table_size(wrappers));
723 while(g_hash_table_iter_next(&iter, &addr, (gpointer) &obj)) {
726 g_string_append_printf(logstr,
"\n%s(%p) ",
732 g_debug(
"%s\n", logstr->str);
735 g_string_free(logstr, TRUE);
759 g_return_val_if_fail(wrapper != NULL, NULL);
762 g_return_val_if_fail(
763 (wrapper->class >= 0) && (wrapper->class <
CCL_NONE), NULL);
766 return ccl_class_names[wrapper->class];
int ccl_wrapper_ref_count(CCLWrapper *wrapper)
Returns the wrapper object reference count.
Information about wrapped OpenCL objects.
#define CCL_OCL_ERROR
Resolves to error category identifying string, in this case an error in the OpenCL library...
enum ccl_info CCLInfo
Type of information to obtain using ccl_wrapper_get_info(), ccl_wrapper_get_info_value() and ccl_wrap...
#define ccl_if_err_create_goto(err, quark, error_condition, error_code, label, msg,...)
If error is detected (error_code != no_error_code), create an error object (CCLErr) and go to the spe...
Useful definitions used internally by cf4ocl.
size_t ccl_wrapper_get_info_size(CCLWrapper *wrapper1, CCLWrapper *wrapper2, cl_uint param_name, size_t min_size, CCLInfo info_type, cl_bool use_cache, CCLErr **err)
Get information size.
Enumeration termination marker.
const char * ccl_err(int code)
Convert OpenCL error code to a readable string.
enum ccl_class CCLClass
Class or type of wrapped OpenCL object.
void ccl_wrapper_ref(CCLWrapper *wrapper)
Increase the reference count of the wrapper object.
This header provides the prototype of the ccl_kernel_get_arg_info_adapter() function.
#define CCL_ERROR
Resolves to error category identifying string, in this case an error in cf4ocl.
CCLWrapperInfo * ccl_wrapper_get_info(CCLWrapper *wrapper1, CCLWrapper *wrapper2, cl_uint param_name, size_t min_size, CCLInfo info_type, cl_bool use_cache, CCLErr **err)
Get information about any wrapped OpenCL object.
Base class for all OpenCL wrappers.
size_t size
Size in bytes of object information.
const char * ccl_wrapper_get_class_name(CCLWrapper *wrapper)
Get wrapper class or type name.
Object information is unavailable.
Definition of an abstract wrapper class and its methods for OpenCL objects.
void * value
Object information.
void * ccl_wrapper_get_info_value(CCLWrapper *wrapper1, CCLWrapper *wrapper2, cl_uint param_name, size_t min_size, CCLInfo info_type, cl_bool use_cache, CCLErr **err)
Get pointer to information value.
Class which represents information about a wrapped OpenCL object.
GError CCLErr
Error handling class.
No object, enumeration termination marker.
cl_bool ccl_wrapper_memcheck()
Debug function which checks if memory allocated by wrappers has been properly freed.
void * ccl_wrapper_unwrap(CCLWrapper *wrapper)
Get the wrapped OpenCL object.