cf4ocl (C Framework for OpenCL)  v2.1.0
Object-oriented framework for developing and benchmarking OpenCL projects in C/C++
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ccl_queue_wrapper.c
Go to the documentation of this file.
1 /*
2  * This file is part of cf4ocl (C Framework for OpenCL).
3  *
4  * cf4ocl is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, either version 3 of the
7  * License, or (at your option) any later version.
8  *
9  * cf4ocl is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with cf4ocl. If not, see
16  * <http://www.gnu.org/licenses/>.
17  * */
18 
29 #include "ccl_queue_wrapper.h"
30 #include "_ccl_abstract_wrapper.h"
31 #include "_ccl_defs.h"
32 
38 struct ccl_queue {
39 
44  CCLWrapper base;
45 
50  CCLContext* ctx;
51 
56  CCLDevice* dev;
57 
62  GHashTable* evts;
63 
68  GHashTableIter evt_iter;
69 
70 };
71 
81 static void ccl_queue_release_fields(CCLQueue* cq) {
82 
83  /* Make sure cq wrapper object is not NULL. */
84  g_return_if_fail(cq != NULL);
85 
86  /* Decrease reference count of context and device wrappers, if
87  * they're set. */
88  if (cq->ctx != NULL)
89  ccl_context_unref(cq->ctx);
90  if (cq->dev != NULL)
91  ccl_device_unref(cq->dev);
92 
93  /* Destroy the events table. */
94  if (cq->evts != NULL) {
95  g_hash_table_destroy(cq->evts);
96  }
97 }
98 
122 CCL_EXPORT
123 CCLQueue* ccl_queue_new_wrap(cl_command_queue command_queue) {
124 
125  return (CCLQueue*) ccl_wrapper_new(
126  CCL_QUEUE, (void*) command_queue, sizeof(CCLQueue));
127 
128 }
129 
154 CCL_EXPORT
156  const cl_queue_properties* prop_full, CCLErr** err) {
157 
158  /* Make sure ctx is not NULL. */
159  g_return_val_if_fail(ctx != NULL, NULL);
160  /* Make sure err is NULL or it is not set. */
161  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
162 
163  /* The OpenCL status flag. */
164  cl_int ocl_status;
165  /* The OpenCL command queue object. */
166  cl_command_queue queue = NULL;
167  /* The command queue wrapper object. */
168  CCLQueue* cq = NULL;
169  /* Internal error object. */
170  CCLErr* err_internal = NULL;
171  /* OpenCL <= 1.2 properties. */
172  cl_command_queue_properties properties = 0;
173  /* Are there any OpenCL >= 2.0 properties? */
174  cl_bool prop_other = CL_FALSE;
175 
176  /* Extract <= 1.2 properties and initialize flag indicating if any >= 2.0
177  * properties are passed. */
178  if (prop_full != NULL) {
179 
180  /* Cycle through the prop_full array. */
181  for (cl_uint i = 0; prop_full[i] != 0; i = i + 2) {
182 
183  /* Check if current property name is known in OpenCL <= 1.2. */
184  if (prop_full[i] == CL_QUEUE_PROPERTIES) {
185 
186  /* Yes, current property name (CL_QUEUE_PROPERTIES) is know in
187  * OpenCL <= 1.2. */
188  properties = prop_full[i + 1];
189 
190  } else {
191 
192  /* No, current property name is valid only for OpenCL >= 2.0. */
193  prop_other = CL_TRUE;
194 
195  }
196  }
197 
198  /* Check if all values in the CL_QUEUE_PROPERTIES bitfield are known
199  * in OpenCL <= 1.2. */
200  if ((properties &
201  ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
202  CL_QUEUE_PROFILING_ENABLE)) != 0) {
203 
204  /* There are values in the CL_QUEUE_PROPERTIES bitfield which
205  * require OpenCL >= 2.0. */
206  prop_other = CL_TRUE;
207 
208  }
209 
210  }
211 
212  /* If dev is NULL, get first device in context. */
213  if (dev == NULL) {
214  dev = ccl_context_get_device(ctx, 0, &err_internal);
215  ccl_if_err_propagate_goto(err, err_internal, error_handler);
216  }
217 
218 #ifdef CL_VERSION_2_0
219 
220  /* OpenCL platform version of the given context. */
221  double platf_ver;
222 
223  /* Get context platform version. */
224  platf_ver = ccl_context_get_opencl_version(ctx, &err_internal);
225  ccl_if_err_propagate_goto(err, err_internal, error_handler);
226 
227  /* Create and keep the OpenCL command queue object. */
228  if (platf_ver >= 200) {
229 
230  /* Platform is OpenCL >= 2.0 and supports
231  * clCreateCommandQueueWithProperties(). */
232  queue = clCreateCommandQueueWithProperties(
234  prop_full, &ocl_status);
235 
236  } else {
237 
238  /* Platform is OpenCL <= 1.2 and we should use
239  * clCreateCommandQueue(). */
240 
241  /* Where any OpenCL >= 2.0 property names or values specified? */
242  if (prop_other) {
243 
244  /* If so, log warning and ignore them. */
245  g_warning("OpenCL >= 2.0 queue properties are not supported by "
246  "the selected OpenCL platform and will be ignored.");
247  properties = properties &
248  (CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
249  CL_QUEUE_PROFILING_ENABLE);
250  }
251 
252  /* Create queue with clCreateCommandQueue(). */
253  CCL_BEGIN_IGNORE_DEPRECATIONS
254  queue = clCreateCommandQueue(ccl_context_unwrap(ctx),
255  ccl_device_unwrap(dev), properties, &ocl_status);
256  CCL_END_IGNORE_DEPRECATIONS
257  }
258 
259 #else
260 
261  /* Where any OpenCL >= 2.0 property names or values specified? */
262  if (prop_other) {
263 
264  /* If so, log warning and ignore them. */
265  g_warning("OpenCL >= 2.0 queue properties are not supported by "
266  "the selected OpenCL platform and will be ignored.");
267  properties = properties &
268  (CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE |
269  CL_QUEUE_PROFILING_ENABLE);
270  }
271 
272  /* Create queue with clCreateCommandQueue(). */
273  queue = clCreateCommandQueue(ccl_context_unwrap(ctx),
274  ccl_device_unwrap(dev), properties, &ocl_status);
275 
276 #endif
277 
278  /* Check for erros in queue creation. */
280  CL_SUCCESS != ocl_status, ocl_status, error_handler,
281  "%s: unable to create queue (OpenCL error %d: %s).",
282  CCL_STRD, ocl_status, ccl_err(ocl_status));
283 
284  /* Wrap the queue. */
285  cq = ccl_queue_new_wrap(queue);
286 
287  /* Keep the context and device wrappers, update their reference
288  * count. */
289  cq->ctx = ctx;
290  ccl_context_ref(ctx);
291  cq->dev = dev;
292  ccl_device_ref(dev);
293 
294  /* If we got here, everything is OK. */
295  g_assert(err == NULL || *err == NULL);
296  goto finish;
297 
298 error_handler:
299  /* If we got here there was an error, verify that it is so. */
300  g_assert(err == NULL || *err != NULL);
301 
302 finish:
303 
304  /* Return the new command queue wrapper object. */
305  return cq;
306 
307 }
308 
332 CCL_EXPORT
334  cl_command_queue_properties properties, CCLErr** err) {
335 
336  const cl_queue_properties prop_full[] =
337  { CL_QUEUE_PROPERTIES, properties, 0 };
338 
339  return ccl_queue_new_full(ctx, dev, prop_full, err);
340 
341 }
342 
352 CCL_EXPORT
354 
355  ccl_wrapper_unref((CCLWrapper*) cq, sizeof(CCLQueue),
356  (ccl_wrapper_release_fields) ccl_queue_release_fields,
357  (ccl_wrapper_release_cl_object) clReleaseCommandQueue, NULL);
358 
359 }
360 
373 CCL_EXPORT
375 
376  /* Make sure cq is not NULL. */
377  g_return_val_if_fail(cq != NULL, NULL);
378  /* Make sure err is NULL or it is not set. */
379  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
380 
381  CCLContext* ctx = NULL;
382 
383  /* Internal error object. */
384  CCLErr* err_internal = NULL;
385 
386  /* Check if context wrapper is already kept by the queue wrapper. */
387  if (cq->ctx != NULL) {
388  /* If so, return it. */
389  ctx = cq->ctx;
390  } else {
391  /* Otherwise, get it using a query. */
392  CCLWrapperInfo* info = NULL;
393  info = ccl_queue_get_info(cq, CL_QUEUE_CONTEXT, &err_internal);
394  ccl_if_err_propagate_goto(err, err_internal, error_handler);
395  ctx = ccl_context_new_wrap(*((cl_context*) info->value));
396  cq->ctx = ctx;
397  }
398 
399  /* If we got here, everything is OK. */
400  g_assert(err == NULL || *err == NULL);
401  goto finish;
402 
403 error_handler:
404  /* If we got here there was an error, verify that it is so. */
405  g_assert(err == NULL || *err != NULL);
406 
407 finish:
408 
409  /* Return the command queue context wrapper. */
410  return ctx;
411 
412 }
413 
426 CCL_EXPORT
428 
429  /* Make sure cq is not NULL. */
430  g_return_val_if_fail(cq != NULL, NULL);
431  /* Make sure err is NULL or it is not set. */
432  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
433 
434  /* The device wrapper object to return. */
435  CCLDevice* dev = NULL;
436 
437  /* Internal error object. */
438  CCLErr* err_internal = NULL;
439 
440  /* Check if device wrapper is already kept by the queue wrapper. */
441  if (cq->dev != NULL) {
442  /* If so, return it. */
443  dev = cq->dev;
444  } else {
445  /* Otherwise, get it using a query. */
446  CCLWrapperInfo* info = NULL;
447  info = ccl_queue_get_info(cq, CL_QUEUE_DEVICE, &err_internal);
448  ccl_if_err_propagate_goto(err, err_internal, error_handler);
449  dev = ccl_device_new_wrap(*((cl_device_id*) info->value));
450  cq->dev = dev;
451  }
452 
453  /* If we got here, everything is OK. */
454  g_assert(err == NULL || *err == NULL);
455  goto finish;
456 
457 error_handler:
458  /* If we got here there was an error, verify that it is so. */
459  g_assert(err == NULL || *err != NULL);
460 
461 finish:
462 
463  /* Return the command queue device wrapper object. */
464  return dev;
465 
466 }
467 
483 CCL_EXPORT
484 CCLEvent* ccl_queue_produce_event(CCLQueue* cq, cl_event event) {
485 
486  /* Make sure cq is not NULL. */
487  g_return_val_if_fail(cq != NULL, NULL);
488  /* Make sure event is not NULL. */
489  g_return_val_if_fail(event != NULL, NULL);
490 
491  /* Wrap the OpenCL event. */
492  CCLEvent* evt = ccl_event_new_wrap(event);
493 
494  /* Initialize the list of events of this command queue. */
495  if (cq->evts == NULL) {
496  cq->evts = g_hash_table_new_full(g_direct_hash, g_direct_equal,
497  (GDestroyNotify) ccl_event_destroy, NULL);
498  }
499 
500  /* Add the wrapped event to the list of events of this command
501  * queue. */
502  g_hash_table_add(cq->evts, (gpointer) evt);
503 
504  /* Return the wrapped event. */
505  return evt;
506 
507 }
508 
522 CCL_EXPORT
523 void ccl_queue_iter_event_init(CCLQueue* cq) {
524 
525  /* Make sure cq is not NULL. */
526  g_return_if_fail(cq != NULL);
527 
528  /* Initialize iterator. */
529  g_hash_table_iter_init(&cq->evt_iter, cq->evts);
530 
531 }
532 
552 CCL_EXPORT
553 CCLEvent* ccl_queue_iter_event_next(CCLQueue* cq) {
554 
555  /* Make sure cq is not NULL. */
556  g_return_val_if_fail(cq != NULL, NULL);
557 
558  gpointer evt;
559  gboolean exists = g_hash_table_iter_next(&cq->evt_iter, &evt, NULL);
560  return exists ? (CCLEvent*) evt : NULL;
561 }
562 
576 CCL_EXPORT
577 cl_bool ccl_queue_flush(CCLQueue* cq, CCLErr** err) {
578 
579  /* Make sure err is NULL or it is not set. */
580  g_return_val_if_fail(err == NULL || *err == NULL, CL_INT_MAX);
581  /* Make sure cq is not NULL. */
582  g_return_val_if_fail(cq != NULL, CL_INVALID_COMMAND_QUEUE);
583 
584  /* OpenCL status flag. */
585  cl_int ocl_status;
586 
587  /* Flush queue. */
588  ocl_status = clFlush(ccl_queue_unwrap(cq));
589  if (ocl_status != CL_SUCCESS)
590  g_set_error(err, CCL_OCL_ERROR, ocl_status,
591  "%s: unable to flush queue (OpenCL error %d: %s).",
592  CCL_STRD, ocl_status, ccl_err(ocl_status));
593 
594  /* Return status. */
595  return ocl_status == CL_SUCCESS ? CL_TRUE : CL_FALSE;
596 }
597 
611 CCL_EXPORT
612 cl_bool ccl_queue_finish(CCLQueue* cq, CCLErr** err) {
613 
614  /* Make sure err is NULL or it is not set. */
615  g_return_val_if_fail(err == NULL || *err == NULL, CL_INT_MAX);
616  /* Make sure cq is not NULL. */
617  g_return_val_if_fail(cq != NULL, CL_INVALID_COMMAND_QUEUE);
618 
619  /* OpenCL status flag. */
620  cl_int ocl_status;
621 
622  /* Finish queue. */
623  ocl_status = clFinish(ccl_queue_unwrap(cq));
624  if (ocl_status != CL_SUCCESS)
625  g_set_error(err, CCL_OCL_ERROR, ocl_status,
626  "%s: unable to finish queue (OpenCL error %d: %s).",
627  CCL_STRD, ocl_status, ccl_err(ocl_status));
628 
629  /* Return status. */
630  return ocl_status == CL_SUCCESS ? CL_TRUE : CL_FALSE;
631 
632 }
633 
651 CCL_EXPORT
653 
654  /* Make sure cq is not NULL. */
655  g_return_if_fail(cq != NULL);
656 
657  /* Release events. */
658  if (cq->evts != NULL) {
659  g_hash_table_remove_all(cq->evts);
660  }
661 
662 }
663 
688 static cl_event ccl_enqueue_barrier_deprecated(CCLQueue* cq,
689  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
690 
691  /* OpenCL status. */
692  cl_int ocl_status;
693  /* OpenCL event object. */
694  cl_event event = NULL;
695 
696  CCL_BEGIN_IGNORE_DEPRECATIONS
697 
698  /* Exact OpenCL function to use depends on whether evt_wait_lst
699  * is NULL or empty. */
700  if ((evt_wait_lst == NULL) ||
701  (ccl_event_wait_list_get_num_events(evt_wait_lst) == 0)) {
702 
703  /* If so, use clEnqueueBarrier() */
704  ocl_status = clEnqueueBarrier(ccl_queue_unwrap(cq));
706  CL_SUCCESS != ocl_status, ocl_status, error_handler,
707  "%s: error in clEnqueueBarrier() (OpenCL error %d: %s).",
708  CCL_STRD, ocl_status, ccl_err(ocl_status));
709 
710  } else {
711 
712  /* Otherwise use clEnqueueWaitForEvents(). */
713  ocl_status = clEnqueueWaitForEvents(ccl_queue_unwrap(cq),
714  ccl_event_wait_list_get_num_events(evt_wait_lst),
715  ccl_event_wait_list_get_clevents(evt_wait_lst));
717  CL_SUCCESS != ocl_status, ocl_status, error_handler,
718  "%s: error in clEnqueueWaitForEvents() (OpenCL error %d: %s).",
719  CCL_STRD, ocl_status, ccl_err(ocl_status));
720 
721  }
722 
723  /* Enqueue a marker so we get an OpenCL event object. */
724  ocl_status = clEnqueueMarker(ccl_queue_unwrap(cq), &event);
726  CL_SUCCESS != ocl_status, ocl_status, error_handler,
727  "%s: error in clEnqueueMarker() (OpenCL error %d: %s).",
728  CCL_STRD, ocl_status, ccl_err(ocl_status));
729 
730  CCL_END_IGNORE_DEPRECATIONS
731 
732  /* If we got here, everything is OK. */
733  g_assert(err == NULL || *err == NULL);
734  goto finish;
735 
736 error_handler:
737  /* If we got here there was an error, verify that it is so. */
738  g_assert(err == NULL || *err != NULL);
739 
740  /* In case of error, return a NULL event. */
741  event = NULL;
742 
743 finish:
744 
745  /* Return OpenCL event. */
746  return event;
747 
748 }
749 
770 CCL_EXPORT
772  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
773 
774  /* Make sure cq is not NULL. */
775  g_return_val_if_fail(cq != NULL, NULL);
776  /* Make sure err is NULL or it is not set. */
777  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
778 
779  /* Event wrapper to return. */
780  CCLEvent* evt;
781  /* OpenCL event object. */
782  cl_event event;
783  /* Internal error handling object. */
784  CCLErr* err_internal = NULL;
785 
786 #ifdef CL_VERSION_1_2
787 
788  /* If library is compiled with support for OpenCL >= 1.2, then use
789  * the platform's OpenCL version for selecting the desired
790  * functionality. */
791 
792  /* Context associated with event. */
793  CCLContext* ctx;
794  /* OpenCL version. */
795  double platf_ver;
796  /* OpenCL status. */
797  cl_int ocl_status;
798 
799  /* Get platform version. */
800  ctx = ccl_queue_get_context(cq, &err_internal);
801  ccl_if_err_propagate_goto(err, err_internal, error_handler);
802  platf_ver = ccl_context_get_opencl_version(ctx, &err_internal);
803  ccl_if_err_propagate_goto(err, err_internal, error_handler);
804 
805  /* Proceed depending on platform version. */
806  if (platf_ver >= 120) {
807 
808  /* Use "new" functions. */
809  ocl_status = clEnqueueBarrierWithWaitList(ccl_queue_unwrap(cq),
810  ccl_event_wait_list_get_num_events(evt_wait_lst),
811  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
813  CL_SUCCESS != ocl_status, ocl_status, error_handler,
814  "%s: error in clEnqueueBarrierWithWaitList() "
815  "(OpenCL error %d: %s).",
816  CCL_STRD, ocl_status, ccl_err(ocl_status));
817 
818  } else {
819 
820  /* Use "old" functions. */
821  event = ccl_enqueue_barrier_deprecated(
822  cq, evt_wait_lst, &err_internal);
823  ccl_if_err_propagate_goto(err, err_internal, error_handler);
824  }
825 
826 #else
827 
828  /* If library is compiled with support for OpenCL 1.0 and 1.1,
829  * then use those functions by default. */
830  event = ccl_enqueue_barrier_deprecated(
831  cq, evt_wait_lst, &err_internal);
832  ccl_if_err_propagate_goto(err, err_internal, error_handler);
833 
834 #endif
835 
836  /* Wrap event and associate it with the respective command queue.
837  * The event object will be released automatically when the command
838  * queue is released. */
839  evt = ccl_queue_produce_event(cq, event);
840 
841  /* Clear event wait list. */
842  ccl_event_wait_list_clear(evt_wait_lst);
843 
844  /* If we got here, everything is OK. */
845  g_assert(err == NULL || *err == NULL);
846  goto finish;
847 
848 error_handler:
849 
850  /* If we got here there was an error, verify that it is so. */
851  g_assert(err == NULL || *err != NULL);
852 
853  /* In case of error, return NULL. */
854  evt = NULL;
855 
856 finish:
857 
858  /* Return event. */
859  return evt;
860 
861 }
862 
883 static cl_event ccl_enqueue_marker_deprecated(CCLQueue* cq,
884  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
885 
886  /* OpenCL status. */
887  cl_int ocl_status;
888  /* OpenCL event object. */
889  cl_event event = NULL;
890 
891  /* evt_wait_lst must be NULL or empty, because getting a marker to
892  * wait on some events is only supported in OpenCL >= 1.2. */
893  if (evt_wait_lst != NULL) {
894  g_warning("The OpenCL version of the selected platform " \
895  "doesn't support markers on specific events. The marker " \
896  "will only fire an event when all previous events have " \
897  "been completed");
898  }
899 
900  CCL_BEGIN_IGNORE_DEPRECATIONS
901 
902  /* Call clEnqueueMarker() once. */
903  ocl_status = clEnqueueMarker(ccl_queue_unwrap(cq), &event);
905  CL_SUCCESS != ocl_status, ocl_status, error_handler,
906  "%s: error in clEnqueueMarker() (OpenCL error %d: %s).",
907  CCL_STRD, ocl_status, ccl_err(ocl_status));
908 
909  CCL_END_IGNORE_DEPRECATIONS
910 
911  /* If we got here, everything is OK. */
912  g_assert(err == NULL || *err == NULL);
913  goto finish;
914 
915 error_handler:
916  /* If we got here there was an error, verify that it is so. */
917  g_assert(err == NULL || *err != NULL);
918 
919  /* In case of error, return a NULL event. */
920  event = NULL;
921 
922 finish:
923 
924  /* Return OpenCL event. */
925  return event;
926 
927 }
928 
950 CCL_EXPORT
952  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
953 
954  /* Make sure cq is not NULL. */
955  g_return_val_if_fail(cq != NULL, NULL);
956  /* Make sure err is NULL or it is not set. */
957  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
958 
959  /* Event wrapper to return. */
960  CCLEvent* evt;
961  /* OpenCL event object. */
962  cl_event event;
963  /* Internal error handling object. */
964  CCLErr* err_internal = NULL;
965 
966 #ifdef CL_VERSION_1_2
967 
968  /* If library is compiled with support for OpenCL >= 1.2, then use
969  * the platform's OpenCL version for selecting the desired
970  * functionality. */
971 
972  /* Context associated with event. */
973  CCLContext* ctx;
974  /* OpenCL version. */
975  double platf_ver;
976  /* OpenCL status. */
977  cl_int ocl_status;
978 
979  /* Get platform version. */
980  ctx = ccl_queue_get_context(cq, &err_internal);
981  ccl_if_err_propagate_goto(err, err_internal, error_handler);
982  platf_ver = ccl_context_get_opencl_version(ctx, &err_internal);
983  ccl_if_err_propagate_goto(err, err_internal, error_handler);
984 
985  /* Proceed depending on platform version. */
986  if (platf_ver >= 120) {
987 
988  /* Use "new" functions. */
989  ocl_status = clEnqueueMarkerWithWaitList(ccl_queue_unwrap(cq),
990  ccl_event_wait_list_get_num_events(evt_wait_lst),
991  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
993  CL_SUCCESS != ocl_status, ocl_status, error_handler,
994  "%s: error in clEnqueueMarkerWithWaitList() (OpenCL error %d: %s).",
995  CCL_STRD, ocl_status, ccl_err(ocl_status));
996 
997  } else {
998 
999  /* Use "old" functions. */
1000  event = ccl_enqueue_marker_deprecated(
1001  cq, evt_wait_lst, &err_internal);
1002  ccl_if_err_propagate_goto(err, err_internal, error_handler);
1003  }
1004 
1005 #else
1006 
1007  /* If library is compiled with support for OpenCL 1.0 and 1.1,
1008  * then use those functions by default. */
1009  event = ccl_enqueue_marker_deprecated(
1010  cq, evt_wait_lst, &err_internal);
1011  ccl_if_err_propagate_goto(err, err_internal, error_handler);
1012 
1013 #endif
1014 
1015  /* Wrap event and associate it with the respective command queue.
1016  * The event object will be released automatically when the command
1017  * queue is released. */
1018  evt = ccl_queue_produce_event(cq, event);
1019 
1020  /* Clear event wait list. */
1021  ccl_event_wait_list_clear(evt_wait_lst);
1022 
1023  /* If we got here, everything is OK. */
1024  g_assert(err == NULL || *err == NULL);
1025  goto finish;
1026 
1027 error_handler:
1028 
1029  /* If we got here there was an error, verify that it is so. */
1030  g_assert(err == NULL || *err != NULL);
1031 
1032  /* In case of error, return NULL. */
1033  evt = NULL;
1034 
1035 finish:
1036 
1037  /* Return event. */
1038  return evt;
1039 
1040 }
1041 
CCLEvent * ccl_enqueue_barrier(CCLQueue *cq, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Enqueues a barrier command on the given command queue.
#define CCL_OCL_ERROR
Resolves to error category identifying string, in this case an error in the OpenCL library...
Definition: ccl_common.h:324
#define ccl_context_ref(ctx)
Increase the reference count of the context wrapper object.
CCLQueue * ccl_queue_new(CCLContext *ctx, CCLDevice *dev, cl_command_queue_properties properties, CCLErr **err)
Create a new command queue wrapper object.
#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...
Definition: _ccl_defs.h:91
#define ccl_context_unwrap(ctx)
Get the OpenCL context object.
GPtrArray * CCLEventWaitList
A list of event objects on which enqueued commands can wait.
Useful definitions used internally by cf4ocl.
void ccl_event_destroy(CCLEvent *evt)
Decrements the reference count of the event wrapper object.
The context wrapper class.
#define ccl_if_err_propagate_goto(err_dest, err_src, label)
Same as ccl_if_err_goto(), but rethrows error in a source CCLErr object to a new destination CCLErr o...
Definition: _ccl_defs.h:120
CCLEvent * ccl_enqueue_marker(CCLQueue *cq, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Enqueues a marker command on the given command queue.
Command queue wrapper class.
CCLDevice * ccl_context_get_device(CCLContext *ctx, cl_uint index, CCLErr **err)
Get CCLDevice wrapper at given index.
const char * ccl_err(int code)
Convert OpenCL error code to a readable string.
Definition: ccl_errors.c:118
void ccl_event_wait_list_clear(CCLEventWaitList *evt_wait_lst)
Clears an event wait list.
#define ccl_queue_get_info(cq, param_name, err)
Get a CCLWrapperInfo command queue information object.
CCLContext * ccl_context_new_wrap(cl_context context)
Get the context wrapper for the given OpenCL context.
cl_uint ccl_context_get_opencl_version(CCLContext *ctx, CCLErr **err)
Get the OpenCL version of the platform associated with this context.
cl_bool ccl_queue_flush(CCLQueue *cq, CCLErr **err)
Issues all previously queued commands in a command queue to the associated device.
CCLQueue * ccl_queue_new_wrap(cl_command_queue command_queue)
Get the command queue wrapper for the given OpenCL command queue.
void ccl_queue_gc(CCLQueue *cq)
Release all events associated with the command queue.
Queue object.
Definition: ccl_common.h:112
cl_bool ccl_queue_finish(CCLQueue *cq, CCLErr **err)
Blocks until all previously queued OpenCL commands in a command-queue are issued to the associated de...
#define ccl_device_ref(dev)
Increase the reference count of the device wrapper object.
Event wrapper class.
Base class for all OpenCL wrappers.
CCLDevice * ccl_queue_get_device(CCLQueue *cq, CCLErr **err)
Get the device associated with the given command queue wrapper object.
#define ccl_device_unwrap(dev)
Get the OpenCL device_id object.
#define ccl_context_unref(ctx)
Alias to ccl_context_destroy().
CCLQueue * ccl_queue_new_full(CCLContext *ctx, CCLDevice *dev, const cl_queue_properties *prop_full, CCLErr **err)
Create a new command queue wrapper object.
#define ccl_device_unref(dev)
Alias to ccl_device_destroy().
void * value
Object information.
Class which represents information about a wrapped OpenCL object.
GError CCLErr
Error handling class.
Definition: ccl_common.h:291
Definition of a wrapper class and its methods for OpenCL queue objects.
CCLEvent * ccl_event_new_wrap(cl_event event)
Get the event wrapper for the given OpenCL event.
CCLContext * ccl_queue_get_context(CCLQueue *cq, CCLErr **err)
Get the context associated with the given command queue wrapper object.
void ccl_queue_destroy(CCLQueue *cq)
Decrements the reference count of the command queue wrapper object.
#define ccl_queue_unwrap(cq)
Get the OpenCL command queue object.
Device wrapper class.
CCLDevice * ccl_device_new_wrap(cl_device_id device)
Get the device wrapper for the given OpenCL device.