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_buffer_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 
30 #include "ccl_buffer_wrapper.h"
31 #include "ccl_image_wrapper.h"
32 #include "_ccl_memobj_wrapper.h"
33 #include "_ccl_defs.h"
34 
40 struct ccl_buffer {
41 
46  CCLMemObj mo;
47 
48 };
49 
71 CCL_EXPORT
72 CCLBuffer* ccl_buffer_new_wrap(cl_mem mem_object) {
73 
74  return (CCLBuffer*) ccl_wrapper_new(
75  CCL_BUFFER, (void*) mem_object, sizeof(CCLBuffer));
76 
77 }
78 
87 CCL_EXPORT
89 
90  ccl_wrapper_unref((CCLWrapper*) buf, sizeof(CCLBuffer),
91  (ccl_wrapper_release_fields) ccl_memobj_release_fields,
92  (ccl_wrapper_release_cl_object) clReleaseMemObject, NULL);
93 
94 }
95 
112 CCL_EXPORT
113 CCLBuffer* ccl_buffer_new(CCLContext* ctx, cl_mem_flags flags,
114  size_t size, void* host_ptr, CCLErr** err) {
115 
116  /* Make sure ctx is not NULL. */
117  g_return_val_if_fail(ctx != NULL, NULL);
118  /* Make sure err is NULL or it is not set. */
119  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
120 
121  cl_int ocl_status;
122  cl_mem buffer;
123  CCLBuffer* buf = NULL;
124 
125  /* Create OpenCL buffer. */
126  buffer = clCreateBuffer(ccl_context_unwrap(ctx), flags, size,
127  host_ptr, &ocl_status);
129  CL_SUCCESS != ocl_status, ocl_status, error_handler,
130  "%s: unable to create buffer (OpenCL error %d: %s).",
131  CCL_STRD, ocl_status, ccl_err(ocl_status));
132 
133  /* Wrap OpenCL buffer. */
134  buf = ccl_buffer_new_wrap(buffer);
135 
136  /* If we got here, everything is OK. */
137  g_assert(err == NULL || *err == NULL);
138  goto finish;
139 
140 error_handler:
141  /* If we got here there was an error, verify that it is so. */
142  g_assert(err == NULL || *err != NULL);
143 
144 finish:
145 
146  /* Return new buffer wrapper. */
147  return buf;
148 
149 }
150 
174 CCL_EXPORT
176  cl_bool blocking_read, size_t offset, size_t size, void *ptr,
177  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
178 
179  /* Make sure cq is not NULL. */
180  g_return_val_if_fail(cq != NULL, NULL);
181  /* Make sure buf is not NULL. */
182  g_return_val_if_fail(buf != NULL, NULL);
183  /* Make sure err is NULL or it is not set. */
184  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
185 
186  cl_int ocl_status;
187  cl_event event = NULL;
188  CCLEvent* evt = NULL;
189 
190  ocl_status = clEnqueueReadBuffer(ccl_queue_unwrap(cq),
191  ccl_memobj_unwrap(buf), blocking_read, offset, size, ptr,
192  ccl_event_wait_list_get_num_events(evt_wait_lst),
193  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
195  CL_SUCCESS != ocl_status, ocl_status, error_handler,
196  "%s: unable to read buffer (OpenCL error %d: %s).",
197  CCL_STRD, ocl_status, ccl_err(ocl_status));
198 
199  /* Wrap event and associate it with the respective command queue.
200  * The event object will be released automatically when the command
201  * queue is released. */
202  evt = ccl_queue_produce_event(cq, event);
203 
204  /* Clear event wait list. */
205  ccl_event_wait_list_clear(evt_wait_lst);
206 
207  /* If we got here, everything is OK. */
208  g_assert(err == NULL || *err == NULL);
209  goto finish;
210 
211 error_handler:
212  /* If we got here there was an error, verify that it is so. */
213  g_assert(err == NULL || *err != NULL);
214 
215  /* An error occurred, return NULL to signal it. */
216  evt = NULL;
217 
218 finish:
219 
220  /* Return event. */
221  return evt;
222 
223 }
224 
249 CCL_EXPORT
251  cl_bool blocking_write, size_t offset, size_t size, void *ptr,
252  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
253 
254  /* Make sure cq is not NULL. */
255  g_return_val_if_fail(cq != NULL, NULL);
256  /* Make sure buf is not NULL. */
257  g_return_val_if_fail(buf != NULL, NULL);
258  /* Make sure err is NULL or it is not set. */
259  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
260 
261  cl_int ocl_status;
262  cl_event event = NULL;
263  CCLEvent* evt = NULL;
264 
265  ocl_status = clEnqueueWriteBuffer(ccl_queue_unwrap(cq),
266  ccl_memobj_unwrap(buf), blocking_write, offset, size, ptr,
267  ccl_event_wait_list_get_num_events(evt_wait_lst),
268  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
270  CL_SUCCESS != ocl_status, ocl_status, error_handler,
271  "%s: unable to write buffer (OpenCL error %d: %s).",
272  CCL_STRD, ocl_status, ccl_err(ocl_status));
273 
274  /* Wrap event and associate it with the respective command queue.
275  * The event object will be released automatically when the command
276  * queue is released. */
277  evt = ccl_queue_produce_event(cq, event);
278 
279  /* Clear event wait list. */
280  ccl_event_wait_list_clear(evt_wait_lst);
281 
282  /* If we got here, everything is OK. */
283  g_assert(err == NULL || *err == NULL);
284  goto finish;
285 
286 error_handler:
287  /* If we got here there was an error, verify that it is so. */
288  g_assert(err == NULL || *err != NULL);
289 
290  /* An error occurred, return NULL to signal it. */
291  evt = NULL;
292 
293 finish:
294 
295  /* Return event. */
296  return evt;
297 
298 }
299 
327 CCL_EXPORT
329  cl_bool blocking_map, cl_map_flags map_flags, size_t offset,
330  size_t size, CCLEventWaitList* evt_wait_lst, CCLEvent** evt,
331  CCLErr** err) {
332 
333  /* Make sure cq is not NULL. */
334  g_return_val_if_fail(cq != NULL, NULL);
335  /* Make sure buf is not NULL. */
336  g_return_val_if_fail(buf != NULL, NULL);
337  /* Make sure err is NULL or it is not set. */
338  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
339 
340  cl_int ocl_status;
341  cl_event event = NULL;
342  CCLEvent* evt_inner = NULL;
343  void* ptr = NULL;
344 
345  /* Perform buffer map. */
346  ptr = clEnqueueMapBuffer(ccl_queue_unwrap(cq),
347  ccl_memobj_unwrap(buf), blocking_map, map_flags, offset, size,
348  ccl_event_wait_list_get_num_events(evt_wait_lst),
349  ccl_event_wait_list_get_clevents(evt_wait_lst),
350  &event, &ocl_status);
352  CL_SUCCESS != ocl_status, ocl_status, error_handler,
353  "%s: unable to map buffer (OpenCL error %d: %s).",
354  CCL_STRD, ocl_status, ccl_err(ocl_status));
355 
356  /* Wrap event and associate it with the respective command queue.
357  * The event object will be released automatically when the command
358  * queue is released. */
359  evt_inner = ccl_queue_produce_event(cq, event);
360  if (evt != NULL)
361  *evt = evt_inner;
362 
363  /* Clear event wait list. */
364  ccl_event_wait_list_clear(evt_wait_lst);
365 
366  /* If we got here, everything is OK. */
367  g_assert(err == NULL || *err == NULL);
368  goto finish;
369 
370 error_handler:
371  /* If we got here there was an error, verify that it is so. */
372  g_assert(err == NULL || *err != NULL);
373 
374  /* An error occurred, return NULL to signal it. */
375  ptr = NULL;
376 
377 finish:
378 
379  /* Return host pointer. */
380  return ptr;
381 
382 }
383 
407 CCL_EXPORT
409  CCLBuffer* dst_buf, CCLQueue* cq, size_t src_offset,
410  size_t dst_offset, size_t size, CCLEventWaitList* evt_wait_lst,
411  CCLErr** err) {
412 
413  /* Make sure cq is not NULL. */
414  g_return_val_if_fail(cq != NULL, NULL);
415  /* Make sure src_buf is not NULL. */
416  g_return_val_if_fail(src_buf != NULL, NULL);
417  /* Make sure dst_buf is not NULL. */
418  g_return_val_if_fail(dst_buf != NULL, NULL);
419  /* Make sure err is NULL or it is not set. */
420  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
421 
422  cl_int ocl_status;
423  cl_event event = NULL;
424  CCLEvent* evt = NULL;
425 
426  ocl_status = clEnqueueCopyBuffer(ccl_queue_unwrap(cq),
427  ccl_memobj_unwrap(src_buf), ccl_memobj_unwrap(dst_buf),
428  src_offset, dst_offset, size,
429  ccl_event_wait_list_get_num_events(evt_wait_lst),
430  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
432  CL_SUCCESS != ocl_status, ocl_status, error_handler,
433  "%s: unable to write buffer (OpenCL error %d: %s).",
434  CCL_STRD, ocl_status, ccl_err(ocl_status));
435 
436  /* Wrap event and associate it with the respective command queue.
437  * The event object will be released automatically when the command
438  * queue is released. */
439  evt = ccl_queue_produce_event(cq, event);
440 
441  /* Clear event wait list. */
442  ccl_event_wait_list_clear(evt_wait_lst);
443 
444  /* If we got here, everything is OK. */
445  g_assert(err == NULL || *err == NULL);
446  goto finish;
447 
448 error_handler:
449  /* If we got here there was an error, verify that it is so. */
450  g_assert(err == NULL || *err != NULL);
451 
452  /* An error occurred, return NULL to signal it. */
453  evt = NULL;
454 
455 finish:
456 
457  /* Return event. */
458  return evt;
459 
460 }
461 
491 CCL_EXPORT
493  CCLImage* dst_img, CCLQueue* cq, size_t src_offset,
494  const size_t *dst_origin, const size_t *region,
495  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
496 
497  /* Make sure cq is not NULL. */
498  g_return_val_if_fail(cq != NULL, NULL);
499  /* Make sure src_buf is not NULL. */
500  g_return_val_if_fail(src_buf != NULL, NULL);
501  /* Make sure dst_img is not NULL. */
502  g_return_val_if_fail(dst_img != NULL, NULL);
503  /* Make sure err is NULL or it is not set. */
504  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
505 
506  /* OpenCL function status. */
507  cl_int ocl_status;
508  /* OpenCL event object. */
509  cl_event event = NULL;
510  /* Event wrapper object. */
511  CCLEvent* evt = NULL;
512 
513  /* Copy buffer to image. */
514  ocl_status = clEnqueueCopyBufferToImage(ccl_queue_unwrap(cq),
515  ccl_memobj_unwrap(src_buf), ccl_memobj_unwrap(dst_img),
516  src_offset, dst_origin, region,
517  ccl_event_wait_list_get_num_events(evt_wait_lst),
518  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
520  CL_SUCCESS != ocl_status, ocl_status, error_handler,
521  "%s: unable to copy buffer to image (OpenCL error %d: %s).",
522  CCL_STRD, ocl_status, ccl_err(ocl_status));
523 
524  /* Wrap event and associate it with the respective command queue.
525  * The event object will be released automatically when the command
526  * queue is released. */
527  evt = ccl_queue_produce_event(cq, event);
528 
529  /* Clear event wait list. */
530  ccl_event_wait_list_clear(evt_wait_lst);
531 
532  /* If we got here, everything is OK. */
533  g_assert(err == NULL || *err == NULL);
534  goto finish;
535 
536 error_handler:
537  /* If we got here there was an error, verify that it is so. */
538  g_assert(err == NULL || *err != NULL);
539 
540  /* An error occurred, return NULL to signal it. */
541  evt = NULL;
542 
543 finish:
544 
545  /* Return event. */
546  return evt;
547 
548 }
549 
568 CCL_EXPORT
570  cl_mem_flags flags, size_t origin, size_t size, CCLErr** err) {
571 
572  /* Make sure buf is not NULL. */
573  g_return_val_if_fail(buf != NULL, NULL);
574  /* Make sure err is NULL or it is not set. */
575  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
576 
577  /* OpenCL function status. */
578  cl_int ocl_status;
579  /* OpenCL sub-buffer object- */
580  cl_mem buffer;
581  /* Buffer wrapper. */
582  CCLBuffer* subbuf;
583  /* OpenCL version of the underlying platform. */
584  double ocl_ver;
585  /* Internal error handling object. */
586  CCLErr* err_internal = NULL;
587 
588 #ifndef CL_VERSION_1_1
589 
590  CCL_UNUSED(ocl_ver);
591  CCL_UNUSED(buffer);
592  CCL_UNUSED(ocl_status);
593  CCL_UNUSED(flags);
594  CCL_UNUSED(origin);
595  CCL_UNUSED(size);
596  CCL_UNUSED(err_internal);
597 
598  /* If cf4ocl was not compiled with support for OpenCL >= 1.1, always throw
599  * error. */
600  ccl_if_err_create_goto(*err, CCL_ERROR, TRUE,
601  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
602  "%s: Sub-buffers require cf4ocl to be deployed with support "
603  "for OpenCL version 1.1 or newer.",
604  CCL_STRD);
605 
606 #else
607 
608  /* Set options. */
609  const cl_buffer_region br = { .origin = origin, .size = size};
610 
611  /* Check that context platform is >= OpenCL 1.1 */
613  (CCLMemObj*) buf, &err_internal);
614  ccl_if_err_propagate_goto(err, err_internal, error_handler);
615 
616  /* If OpenCL version is not >= 1.1, throw error. */
617  ccl_if_err_create_goto(*err, CCL_ERROR, ocl_ver < 110,
618  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
619  "%s: sub-buffers require OpenCL version 1.1 or newer.",
620  CCL_STRD);
621 
622  /* Create the OpenCL sub-buffer. */
623  buffer = clCreateSubBuffer(ccl_memobj_unwrap(buf), flags,
624  CL_BUFFER_CREATE_TYPE_REGION, (const void*) &br, &ocl_status);
626  CL_SUCCESS != ocl_status, ocl_status, error_handler,
627  "%s: unable create sub-buffer (OpenCL error %d: %s).",
628  CCL_STRD, ocl_status, ccl_err(ocl_status));
629 
630  /* Wrap the OpenCL sub-buffer. */
631  subbuf = ccl_buffer_new_wrap(buffer);
632 
633 #endif
634 
635  /* If we got here, everything is OK. */
636  g_assert(err == NULL || *err == NULL);
637  goto finish;
638 
639 error_handler:
640  /* If we got here there was an error, verify that it is so. */
641  g_assert(err == NULL || *err != NULL);
642 
643  /* An error occurred, return NULL to signal it. */
644  subbuf = NULL;
645 
646 finish:
647 
648  /* Return sub-buffer. */
649  return subbuf;
650 
651 }
652 
689 CCL_EXPORT
691  cl_bool blocking_read, const size_t* buffer_origin,
692  const size_t* host_origin, const size_t* region,
693  size_t buffer_row_pitch, size_t buffer_slice_pitch,
694  size_t host_row_pitch, size_t host_slice_pitch, void *ptr,
695  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
696 
697  /* Make sure cq is not NULL. */
698  g_return_val_if_fail(cq != NULL, NULL);
699  /* Make sure buf is not NULL. */
700  g_return_val_if_fail(buf != NULL, NULL);
701  /* Make sure err is NULL or it is not set. */
702  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
703 
704  /* OpenCL function status. */
705  cl_int ocl_status;
706  /* OpenCL event object. */
707  cl_event event = NULL;
708  /* Event wrapper object. */
709  CCLEvent* evt = NULL;
710  /* OpenCL version of the underlying platform. */
711  double ocl_ver;
712  /* Internal error handling object. */
713  CCLErr* err_internal = NULL;
714 
715 #ifndef CL_VERSION_1_1
716 
717  CCL_UNUSED(blocking_read);
718  CCL_UNUSED(buffer_origin);
719  CCL_UNUSED(host_origin);
720  CCL_UNUSED(region);
721  CCL_UNUSED(buffer_row_pitch);
722  CCL_UNUSED(buffer_slice_pitch);
723  CCL_UNUSED(host_row_pitch);
724  CCL_UNUSED(host_slice_pitch);
725  CCL_UNUSED(ptr);
726  CCL_UNUSED(evt_wait_lst);
727  CCL_UNUSED(ocl_status);
728  CCL_UNUSED(event);
729  CCL_UNUSED(evt);
730  CCL_UNUSED(ocl_ver);
731  CCL_UNUSED(err_internal);
732 
733  /* If cf4ocl was not compiled with support for OpenCL >= 1.1, always throw
734  * error. */
735  ccl_if_err_create_goto(*err, CCL_ERROR, TRUE,
736  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
737  "%s: Rectangular buffer read requires cf4ocl to be deployed with "
738  "support for OpenCL version 1.1 or newer.",
739  CCL_STRD);
740 
741 #else
742 
743  /* Check that context platform is >= OpenCL 1.1 */
745  (CCLMemObj*) buf, &err_internal);
746  ccl_if_err_propagate_goto(err, err_internal, error_handler);
747 
748  /* If OpenCL version is not >= 1.1, throw error. */
749  ccl_if_err_create_goto(*err, CCL_ERROR, ocl_ver < 110,
750  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
751  "%s: rect. buffer reads require OpenCL version 1.1 or newer.",
752  CCL_STRD);
753 
754  /* Read rectangular region of buffer. */
755  ocl_status = clEnqueueReadBufferRect(ccl_queue_unwrap(cq),
756  ccl_memobj_unwrap(buf), blocking_read, buffer_origin,
757  host_origin, region, buffer_row_pitch, buffer_slice_pitch,
758  host_row_pitch, host_slice_pitch, ptr,
759  ccl_event_wait_list_get_num_events(evt_wait_lst),
760  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
762  CL_SUCCESS != ocl_status, ocl_status, error_handler,
763  "%s: unable to enqueue a rectangular buffer read (OpenCL error %d: %s).",
764  CCL_STRD, ocl_status, ccl_err(ocl_status));
765 
766  /* Wrap event and associate it with the respective command queue.
767  * The event object will be released automatically when the command
768  * queue is released. */
769  evt = ccl_queue_produce_event(cq, event);
770 
771  /* Clear event wait list. */
772  ccl_event_wait_list_clear(evt_wait_lst);
773 
774 #endif
775 
776  /* If we got here, everything is OK. */
777  g_assert(err == NULL || *err == NULL);
778  goto finish;
779 
780 error_handler:
781  /* If we got here there was an error, verify that it is so. */
782  g_assert(err == NULL || *err != NULL);
783 
784  /* An error occurred, return NULL to signal it. */
785  evt = NULL;
786 
787 finish:
788 
789  /* Return event. */
790  return evt;
791 
792 
793 }
794 
832 CCL_EXPORT
834  cl_bool blocking_write, const size_t* buffer_origin,
835  const size_t* host_origin, const size_t* region,
836  size_t buffer_row_pitch, size_t buffer_slice_pitch,
837  size_t host_row_pitch, size_t host_slice_pitch, void *ptr,
838  CCLEventWaitList* evt_wait_lst, CCLErr** err) {
839 
840  /* Make sure cq is not NULL. */
841  g_return_val_if_fail(cq != NULL, NULL);
842  /* Make sure buf is not NULL. */
843  g_return_val_if_fail(buf != NULL, NULL);
844  /* Make sure err is NULL or it is not set. */
845  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
846 
847  /* OpenCL function status. */
848  cl_int ocl_status;
849  /* OpenCL event object. */
850  cl_event event = NULL;
851  /* Event wrapper object. */
852  CCLEvent* evt = NULL;
853  /* OpenCL version of the underlying platform. */
854  double ocl_ver;
855  /* Internal error handling object. */
856  CCLErr* err_internal = NULL;
857 
858 #ifndef CL_VERSION_1_1
859 
860  CCL_UNUSED(blocking_write);
861  CCL_UNUSED(buffer_origin);
862  CCL_UNUSED(host_origin);
863  CCL_UNUSED(region);
864  CCL_UNUSED(buffer_row_pitch);
865  CCL_UNUSED(buffer_slice_pitch);
866  CCL_UNUSED(host_row_pitch);
867  CCL_UNUSED(host_slice_pitch);
868  CCL_UNUSED(ptr);
869  CCL_UNUSED(evt_wait_lst);
870  CCL_UNUSED(ocl_status);
871  CCL_UNUSED(event);
872  CCL_UNUSED(evt);
873  CCL_UNUSED(ocl_ver);
874  CCL_UNUSED(err_internal);
875 
876  /* If cf4ocl was not compiled with support for OpenCL >= 1.1, always throw
877  * error. */
878  ccl_if_err_create_goto(*err, CCL_ERROR, TRUE,
879  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
880  "%s: Rectangular buffer write requires cf4ocl to be deployed with "
881  "support for OpenCL version 1.1 or newer.",
882  CCL_STRD);
883 
884 #else
885 
886  /* Check that context platform is >= OpenCL 1.1 */
888  (CCLMemObj*) buf, &err_internal);
889  ccl_if_err_propagate_goto(err, err_internal, error_handler);
890 
891  /* If OpenCL version is not >= 1.1, throw error. */
892  ccl_if_err_create_goto(*err, CCL_ERROR, ocl_ver < 110,
893  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
894  "%s: rect. buffer writes require OpenCL version 1.1 or newer.",
895  CCL_STRD);
896 
897  /* Write rectangular region of buffer. */
898  ocl_status = clEnqueueWriteBufferRect(ccl_queue_unwrap(cq),
899  ccl_memobj_unwrap(buf), blocking_write, buffer_origin,
900  host_origin, region, buffer_row_pitch, buffer_slice_pitch,
901  host_row_pitch, host_slice_pitch, ptr,
902  ccl_event_wait_list_get_num_events(evt_wait_lst),
903  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
905  CL_SUCCESS != ocl_status, ocl_status, error_handler,
906  "%s: unable to enqueue a rectangular buffer write (OpenCL error %d: %s).",
907  CCL_STRD, ocl_status, ccl_err(ocl_status));
908 
909  /* Wrap event and associate it with the respective command queue.
910  * The event object will be released automatically when the command
911  * queue is released. */
912  evt = ccl_queue_produce_event(cq, event);
913 
914  /* Clear event wait list. */
915  ccl_event_wait_list_clear(evt_wait_lst);
916 
917 #endif
918 
919  /* If we got here, everything is OK. */
920  g_assert(err == NULL || *err == NULL);
921  goto finish;
922 
923 error_handler:
924  /* If we got here there was an error, verify that it is so. */
925  g_assert(err == NULL || *err != NULL);
926 
927  /* An error occurred, return NULL to signal it. */
928  evt = NULL;
929 
930 finish:
931 
932  /* Return event. */
933  return evt;
934 
935 }
936 
971 CCL_EXPORT
973  CCLBuffer* dst_buf, CCLQueue* cq, const size_t *src_origin,
974  const size_t *dst_origin, const size_t *region,
975  size_t src_row_pitch, size_t src_slice_pitch, size_t dst_row_pitch,
976  size_t dst_slice_pitch, CCLEventWaitList* evt_wait_lst,
977  CCLErr** err) {
978 
979  /* Make sure cq is not NULL. */
980  g_return_val_if_fail(cq != NULL, NULL);
981  /* Make sure src_buf is not NULL. */
982  g_return_val_if_fail(src_buf != NULL, NULL);
983  /* Make sure dst_buf is not NULL. */
984  g_return_val_if_fail(dst_buf != NULL, NULL);
985  /* Make sure err is NULL or it is not set. */
986  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
987 
988  /* OpenCL function status. */
989  cl_int ocl_status;
990  /* OpenCL event object. */
991  cl_event event = NULL;
992  /* Event wrapper object. */
993  CCLEvent* evt = NULL;
994  /* OpenCL version of the underlying platform. */
995  double ocl_ver;
996  /* Internal error handling object. */
997  CCLErr* err_internal = NULL;
998 
999 #ifndef CL_VERSION_1_1
1000 
1001  CCL_UNUSED(src_origin);
1002  CCL_UNUSED(dst_origin);
1003  CCL_UNUSED(region);
1004  CCL_UNUSED(src_row_pitch);
1005  CCL_UNUSED(src_slice_pitch);
1006  CCL_UNUSED(dst_row_pitch);
1007  CCL_UNUSED(dst_slice_pitch);
1008  CCL_UNUSED(evt_wait_lst);
1009  CCL_UNUSED(ocl_status);
1010  CCL_UNUSED(event);
1011  CCL_UNUSED(evt);
1012  CCL_UNUSED(ocl_ver);
1013  CCL_UNUSED(err_internal);
1014 
1015  /* If cf4ocl was not compiled with support for OpenCL >= 1.1, always throw
1016  * error. */
1017  ccl_if_err_create_goto(*err, CCL_ERROR, TRUE,
1018  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
1019  "%s: Rectangular buffer copy requires cf4ocl to be deployed with "
1020  "support for OpenCL version 1.1 or newer.",
1021  CCL_STRD);
1022 
1023 #else
1024 
1025  /* Check that context platform is >= OpenCL 1.1 */
1027  (CCLMemObj*) src_buf, &err_internal);
1028  ccl_if_err_propagate_goto(err, err_internal, error_handler);
1029 
1030  /* If OpenCL version is not >= 1.1, throw error. */
1031  ccl_if_err_create_goto(*err, CCL_ERROR, ocl_ver < 110,
1032  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
1033  "%s: rect. buffer copy requires OpenCL version 1.1 or newer.",
1034  CCL_STRD);
1035 
1036  /* Copy rectangular region between buffers. */
1037  ocl_status = clEnqueueCopyBufferRect(ccl_queue_unwrap(cq),
1038  ccl_memobj_unwrap(src_buf), ccl_memobj_unwrap(dst_buf),
1039  src_origin, dst_origin, region, src_row_pitch, src_slice_pitch,
1040  dst_row_pitch, dst_slice_pitch,
1041  ccl_event_wait_list_get_num_events(evt_wait_lst),
1042  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
1044  CL_SUCCESS != ocl_status, ocl_status, error_handler,
1045  "%s: unable to enqueue a rectangular buffer copy (OpenCL error %d: %s).",
1046  CCL_STRD, ocl_status, ccl_err(ocl_status));
1047 
1048  /* Wrap event and associate it with the respective command queue.
1049  * The event object will be released automatically when the command
1050  * queue is released. */
1051  evt = ccl_queue_produce_event(cq, event);
1052 
1053  /* Clear event wait list. */
1054  ccl_event_wait_list_clear(evt_wait_lst);
1055 
1056 #endif
1057 
1058  /* If we got here, everything is OK. */
1059  g_assert(err == NULL || *err == NULL);
1060  goto finish;
1061 
1062 error_handler:
1063  /* If we got here there was an error, verify that it is so. */
1064  g_assert(err == NULL || *err != NULL);
1065 
1066  /* An error occurred, return NULL to signal it. */
1067  evt = NULL;
1068 
1069 finish:
1070 
1071  /* Return event. */
1072  return evt;
1073 
1074 }
1075 
1099 CCL_EXPORT
1101  const void *pattern, size_t pattern_size, size_t offset,
1102  size_t size, CCLEventWaitList* evt_wait_lst, CCLErr** err) {
1103 
1104  /* Make sure cq is not NULL. */
1105  g_return_val_if_fail(cq != NULL, NULL);
1106  /* Make sure buf is not NULL. */
1107  g_return_val_if_fail(buf != NULL, NULL);
1108  /* Make sure err is NULL or it is not set. */
1109  g_return_val_if_fail(err == NULL || *err == NULL, NULL);
1110 
1111  /* OpenCL function status. */
1112  cl_int ocl_status;
1113  /* OpenCL event object. */
1114  cl_event event = NULL;
1115  /* Event wrapper object. */
1116  CCLEvent* evt = NULL;
1117  /* OpenCL version of the underlying platform. */
1118  double ocl_ver;
1119  /* Internal error handling object. */
1120  CCLErr* err_internal = NULL;
1121 
1122 #ifndef CL_VERSION_1_2
1123 
1124  CCL_UNUSED(pattern);
1125  CCL_UNUSED(pattern_size);
1126  CCL_UNUSED(offset);
1127  CCL_UNUSED(size);
1128  CCL_UNUSED(evt_wait_lst);
1129  CCL_UNUSED(ocl_status);
1130  CCL_UNUSED(event);
1131  CCL_UNUSED(evt);
1132  CCL_UNUSED(ocl_ver);
1133  CCL_UNUSED(err_internal);
1134 
1135  /* If cf4ocl was not compiled with support for OpenCL >= 1.2, always throw
1136  * error. */
1137  ccl_if_err_create_goto(*err, CCL_ERROR, TRUE,
1138  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
1139  "%s: Buffer fill requires cf4ocl to be deployed with "
1140  "support for OpenCL version 1.1 or newer.",
1141  CCL_STRD);
1142 
1143 #else
1144 
1145  /* Check that context platform is >= OpenCL 1.2 */
1147  (CCLMemObj*) buf, &err_internal);
1148  ccl_if_err_propagate_goto(err, err_internal, error_handler);
1149 
1150  /* If OpenCL version is not >= 1.2, throw error. */
1151  ccl_if_err_create_goto(*err, CCL_ERROR, ocl_ver < 120,
1152  CCL_ERROR_UNSUPPORTED_OCL, error_handler,
1153  "%s: Buffer fill requires OpenCL version 1.2 or newer.",
1154  CCL_STRD);
1155 
1156  /* Fill buffer. */
1157  ocl_status = clEnqueueFillBuffer(ccl_queue_unwrap(cq),
1158  ccl_memobj_unwrap(buf), pattern, pattern_size, offset, size,
1159  ccl_event_wait_list_get_num_events(evt_wait_lst),
1160  ccl_event_wait_list_get_clevents(evt_wait_lst), &event);
1162  CL_SUCCESS != ocl_status, ocl_status, error_handler,
1163  "%s: unable to enqueue a fill buffer command (OpenCL error %d: %s).",
1164  CCL_STRD, ocl_status, ccl_err(ocl_status));
1165 
1166  /* Wrap event and associate it with the respective command queue.
1167  * The event object will be released automatically when the command
1168  * queue is released. */
1169  evt = ccl_queue_produce_event(cq, event);
1170 
1171  /* Clear event wait list. */
1172  ccl_event_wait_list_clear(evt_wait_lst);
1173 
1174 #endif
1175 
1176  /* If we got here, everything is OK. */
1177  g_assert(err == NULL || *err == NULL);
1178  goto finish;
1179 
1180 error_handler:
1181  /* If we got here there was an error, verify that it is so. */
1182  g_assert(err == NULL || *err != NULL);
1183 
1184  /* An error occurred, return NULL to signal it. */
1185  evt = NULL;
1186 
1187 finish:
1188 
1189  /* Return event. */
1190  return evt;
1191 
1192 }
1193 
#define CCL_OCL_ERROR
Resolves to error category identifying string, in this case an error in the OpenCL library...
Definition: ccl_common.h:324
CCLEvent * ccl_buffer_enqueue_copy_to_image(CCLBuffer *src_buf, CCLImage *dst_img, CCLQueue *cq, size_t src_offset, const size_t *dst_origin, const size_t *region, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Copy a buffer object to an image object.
Image wrapper class.
#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
CCLEvent * ccl_buffer_enqueue_write_rect(CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_write, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Write a 2D or 3D rectangular region to a buffer object from host memory.
#define ccl_context_unwrap(ctx)
Get the OpenCL context object.
GPtrArray * CCLEventWaitList
A list of event objects on which enqueued commands can wait.
Buffer wrapper class.
Useful definitions used internally by cf4ocl.
#define ccl_memobj_unwrap(mo)
Get the OpenCL cl_mem object.
CCLEvent * ccl_buffer_enqueue_read_rect(CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_read, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Read from a 2D or 3D rectangular region from a buffer object to host memory.
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
Base class for memory object wrappers, i.e., CCLBuffer and CCLImage.
Definition of a wrapper class and its methods for OpenCL image objects.
Command queue wrapper class.
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.
CCLEvent * ccl_buffer_enqueue_write(CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_write, size_t offset, size_t size, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Write to a buffer object from host memory.
#define CCL_ERROR
Resolves to error category identifying string, in this case an error in cf4ocl.
Definition: ccl_common.h:320
CCLBuffer * ccl_buffer_new_from_region(CCLBuffer *buf, cl_mem_flags flags, size_t origin, size_t size, CCLErr **err)
Creates a sub-buffer that represents a specific region in the given buffer.
CCLEvent * ccl_buffer_enqueue_read(CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_read, size_t offset, size_t size, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Read from a buffer object to host memory.
Event wrapper class.
CCLBuffer * ccl_buffer_new_wrap(cl_mem mem_object)
Get the buffer wrapper for the given OpenCL buffer.
Base class for all OpenCL wrappers.
#define CCL_UNUSED(x)
Macro to avoid warning in unused variables.
Definition: ccl_common.h:86
cl_uint ccl_memobj_get_opencl_version(CCLMemObj *mo, CCLErr **err)
Get the OpenCL version of the platform associated with this memory object.
CCLEvent * ccl_buffer_enqueue_fill(CCLBuffer *buf, CCLQueue *cq, const void *pattern, size_t pattern_size, size_t offset, size_t size, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Fill a buffer object with a pattern of a given pattern size.
CCLEvent * ccl_buffer_enqueue_copy_rect(CCLBuffer *src_buf, CCLBuffer *dst_buf, CCLQueue *cq, const size_t *src_origin, const size_t *dst_origin, const size_t *region, size_t src_row_pitch, size_t src_slice_pitch, size_t dst_row_pitch, size_t dst_slice_pitch, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Copy a 2D or 3D rectangular region from a buffer object to another buffer object. ...
Buffer object.
Definition: ccl_common.h:94
void ccl_buffer_destroy(CCLBuffer *buf)
Decrements the reference count of the wrapper object.
void * ccl_buffer_enqueue_map(CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_map, cl_map_flags map_flags, size_t offset, size_t size, CCLEventWaitList *evt_wait_lst, CCLEvent **evt, CCLErr **err)
Map a region of a buffer into the host address space and return a pointer to this mapped region...
CCLEvent * ccl_buffer_enqueue_copy(CCLBuffer *src_buf, CCLBuffer *dst_buf, CCLQueue *cq, size_t src_offset, size_t dst_offset, size_t size, CCLEventWaitList *evt_wait_lst, CCLErr **err)
Copy from one buffer object to another.
GError CCLErr
Error handling class.
Definition: ccl_common.h:291
#define ccl_queue_unwrap(cq)
Get the OpenCL command queue object.
Definition of a wrapper class and its methods for OpenCL buffer objects.
CCLBuffer * ccl_buffer_new(CCLContext *ctx, cl_mem_flags flags, size_t size, void *host_ptr, CCLErr **err)
Create a CCLBuffer wrapper object.
The operation is not supported by the version of the selected OpenCL platform.
Definition: ccl_common.h:311