1#![allow(unused_unsafe)]
18#![allow(non_camel_case_types, deprecated)]
19#![allow(
20 clippy::too_many_arguments,
21 clippy::not_unsafe_ptr_arg_deref,
22 clippy::missing_safety_doc
23)]
24
25pub use opencl_sys::{
26 CL_BLOCKING, CL_INVALID_VALUE, CL_NON_BLOCKING, CL_QUEUE_CONTEXT, CL_QUEUE_DEVICE,
27 CL_QUEUE_DEVICE_DEFAULT, CL_QUEUE_ON_DEVICE, CL_QUEUE_ON_DEVICE_DEFAULT,
28 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, CL_QUEUE_PROFILING_ENABLE, CL_QUEUE_PROPERTIES,
29 CL_QUEUE_PROPERTIES_ARRAY, CL_QUEUE_REFERENCE_COUNT, CL_QUEUE_SIZE, CL_SUCCESS, cl_bool,
30 cl_command_queue, cl_command_queue_info, cl_command_queue_properties, cl_context, cl_device_id,
31 cl_event, cl_int, cl_kernel, cl_map_flags, cl_mem, cl_mem_migration_flags, cl_queue_properties,
32 cl_uint, cl_ulong,
33};
34
35use super::info_type::InfoType;
36use super::{api_info_size, api_info_value, api_info_vector};
37use libc::{c_void, intptr_t, size_t};
38use std::mem;
39use std::ptr;
40
41#[cfg_attr(
58 any(
59 feature = "CL_VERSION_2_0",
60 feature = "CL_VERSION_2_1",
61 feature = "CL_VERSION_2_2",
62 feature = "CL_VERSION_3_0"
63 ),
64 deprecated(
65 since = "0.1.0",
66 note = "From CL_VERSION_2_0 use create_command_queue_with_properties"
67 )
68)]
69#[inline]
70pub unsafe fn create_command_queue(
71 context: cl_context,
72 device: cl_device_id,
73 properties: cl_command_queue_properties,
74) -> Result<cl_command_queue, cl_int> {
75 let mut status: cl_int = CL_INVALID_VALUE;
76 let queue: cl_command_queue = cl_call!(clCreateCommandQueue(
77 context,
78 device,
79 properties,
80 &raw mut status
81 ));
82 if CL_SUCCESS == status {
83 Ok(queue)
84 } else {
85 Err(status)
86 }
87}
88
89#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
106#[inline]
107pub unsafe fn create_command_queue_with_properties(
108 context: cl_context,
109 device: cl_device_id,
110 properties: *const cl_queue_properties,
111) -> Result<cl_command_queue, cl_int> {
112 let mut status: cl_int = CL_INVALID_VALUE;
113 let queue: cl_command_queue = cl_call!(clCreateCommandQueueWithProperties(
114 context,
115 device,
116 properties,
117 &raw mut status
118 ));
119 if CL_SUCCESS == status {
120 Ok(queue)
121 } else {
122 Err(status)
123 }
124}
125
126#[inline]
137pub unsafe fn retain_command_queue(command_queue: cl_command_queue) -> Result<(), cl_int> {
138 let status: cl_int = cl_call!(clRetainCommandQueue(command_queue));
139 if CL_SUCCESS == status {
140 Ok(())
141 } else {
142 Err(status)
143 }
144}
145
146#[inline]
157pub unsafe fn release_command_queue(command_queue: cl_command_queue) -> Result<(), cl_int> {
158 let status: cl_int = cl_call!(clReleaseCommandQueue(command_queue));
159 if CL_SUCCESS == status {
160 Ok(())
161 } else {
162 Err(status)
163 }
164}
165
166pub fn get_command_queue_data(
169 command_queue: cl_command_queue,
170 param_name: cl_command_queue_info,
171) -> Result<Vec<u8>, cl_int> {
172 api_info_size!(get_size, clGetCommandQueueInfo);
173 let size = get_size(command_queue, param_name)?;
174 api_info_vector!(get_vector, u8, clGetCommandQueueInfo);
175 get_vector(command_queue, param_name, size)
176}
177
178pub fn get_command_queue_info(
188 command_queue: cl_command_queue,
189 param_name: cl_command_queue_info,
190) -> Result<InfoType, cl_int> {
191 match param_name {
192 CL_QUEUE_REFERENCE_COUNT
193 | CL_QUEUE_SIZE => {
195 api_info_value!(get_value, cl_uint, clGetCommandQueueInfo);
196 Ok(InfoType::Uint(get_value(command_queue, param_name)?))
197 }
198
199 CL_QUEUE_PROPERTIES => {
200 api_info_value!(get_value, cl_ulong, clGetCommandQueueInfo);
201 Ok(InfoType::Ulong(get_value(command_queue, param_name)?))
202 }
203
204 CL_QUEUE_CONTEXT
205 | CL_QUEUE_DEVICE
206 | CL_QUEUE_DEVICE_DEFAULT => {
208 api_info_value!(get_value, intptr_t, clGetCommandQueueInfo);
209 Ok(InfoType::Ptr(get_value(command_queue, param_name)?))
210 }
211
212 CL_QUEUE_PROPERTIES_ARRAY => {
214 api_info_size!(get_size, clGetCommandQueueInfo);
215 api_info_vector!(get_vec, cl_ulong, clGetCommandQueueInfo);
216 let size = get_size(command_queue, param_name)?;
217 Ok(InfoType::VecUlong(get_vec(
218 command_queue,
219 param_name,
220 size,
221 )?))
222 }
223
224 | _ => {
225 Ok(InfoType::VecUchar(get_command_queue_data(command_queue, param_name)?))
226 }
227 }
228}
229
230#[inline]
237pub fn flush(command_queue: cl_command_queue) -> Result<(), cl_int> {
238 let status: cl_int = unsafe { cl_call!(clFlush(command_queue)) };
239 if CL_SUCCESS == status {
240 Ok(())
241 } else {
242 Err(status)
243 }
244}
245
246#[inline]
253pub fn finish(command_queue: cl_command_queue) -> Result<(), cl_int> {
254 let status: cl_int = unsafe { cl_call!(clFinish(command_queue)) };
255 if CL_SUCCESS == status {
256 Ok(())
257 } else {
258 Err(status)
259 }
260}
261
262#[inline]
265pub unsafe fn enqueue_read_buffer(
266 command_queue: cl_command_queue,
267 buffer: cl_mem,
268 blocking_read: cl_bool,
269 offset: size_t,
270 size: size_t,
271 ptr: *mut c_void,
272 num_events_in_wait_list: cl_uint,
273 event_wait_list: *const cl_event,
274) -> Result<cl_event, cl_int> {
275 let mut event: cl_event = ptr::null_mut();
276 let status: cl_int = cl_call!(clEnqueueReadBuffer(
277 command_queue,
278 buffer,
279 blocking_read,
280 offset,
281 size,
282 ptr,
283 num_events_in_wait_list,
284 event_wait_list,
285 &raw mut event,
286 ));
287 if CL_SUCCESS == status {
288 Ok(event)
289 } else {
290 Err(status)
291 }
292}
293
294#[inline]
295pub unsafe fn enqueue_read_buffer_rect(
296 command_queue: cl_command_queue,
297 buffer: cl_mem,
298 blocking_read: cl_bool,
299 buffer_origin: *const size_t,
300 host_origin: *const size_t,
301 region: *const size_t,
302 buffer_row_pitch: size_t,
303 buffer_slice_pitch: size_t,
304 host_row_pitch: size_t,
305 host_slice_pitch: size_t,
306 ptr: *mut c_void,
307 num_events_in_wait_list: cl_uint,
308 event_wait_list: *const cl_event,
309) -> Result<cl_event, cl_int> {
310 let mut event: cl_event = ptr::null_mut();
311 let status: cl_int = cl_call!(clEnqueueReadBufferRect(
312 command_queue,
313 buffer,
314 blocking_read,
315 buffer_origin,
316 host_origin,
317 region,
318 buffer_row_pitch,
319 buffer_slice_pitch,
320 host_row_pitch,
321 host_slice_pitch,
322 ptr,
323 num_events_in_wait_list,
324 event_wait_list,
325 &raw mut event,
326 ));
327 if CL_SUCCESS == status {
328 Ok(event)
329 } else {
330 Err(status)
331 }
332}
333
334#[inline]
335pub unsafe fn enqueue_write_buffer(
336 command_queue: cl_command_queue,
337 buffer: cl_mem,
338 blocking_write: cl_bool,
339 offset: size_t,
340 size: size_t,
341 ptr: *const c_void,
342 num_events_in_wait_list: cl_uint,
343 event_wait_list: *const cl_event,
344) -> Result<cl_event, cl_int> {
345 let mut event: cl_event = ptr::null_mut();
346 let status: cl_int = cl_call!(clEnqueueWriteBuffer(
347 command_queue,
348 buffer,
349 blocking_write,
350 offset,
351 size,
352 ptr,
353 num_events_in_wait_list,
354 event_wait_list,
355 &raw mut event,
356 ));
357 if CL_SUCCESS == status {
358 Ok(event)
359 } else {
360 Err(status)
361 }
362}
363
364#[inline]
365pub unsafe fn enqueue_write_buffer_rect(
366 command_queue: cl_command_queue,
367 buffer: cl_mem,
368 blocking_write: cl_bool,
369 buffer_origin: *const size_t,
370 host_origin: *const size_t,
371 region: *const size_t,
372 buffer_row_pitch: size_t,
373 buffer_slice_pitch: size_t,
374 host_row_pitch: size_t,
375 host_slice_pitch: size_t,
376 ptr: *const c_void,
377 num_events_in_wait_list: cl_uint,
378 event_wait_list: *const cl_event,
379) -> Result<cl_event, cl_int> {
380 let mut event: cl_event = ptr::null_mut();
381 let status: cl_int = cl_call!(clEnqueueWriteBufferRect(
382 command_queue,
383 buffer,
384 blocking_write,
385 buffer_origin,
386 host_origin,
387 region,
388 buffer_row_pitch,
389 buffer_slice_pitch,
390 host_row_pitch,
391 host_slice_pitch,
392 ptr,
393 num_events_in_wait_list,
394 event_wait_list,
395 &raw mut event,
396 ));
397 if CL_SUCCESS == status {
398 Ok(event)
399 } else {
400 Err(status)
401 }
402}
403
404#[cfg(any(feature = "CL_VERSION_1_2", feature = "dynamic"))]
405#[inline]
406pub unsafe fn enqueue_fill_buffer(
407 command_queue: cl_command_queue,
408 buffer: cl_mem,
409 pattern: *const c_void,
410 pattern_size: size_t,
411 offset: size_t,
412 size: size_t,
413 num_events_in_wait_list: cl_uint,
414 event_wait_list: *const cl_event,
415) -> Result<cl_event, cl_int> {
416 let mut event: cl_event = ptr::null_mut();
417 let status: cl_int = cl_call!(clEnqueueFillBuffer(
418 command_queue,
419 buffer,
420 pattern,
421 pattern_size,
422 offset,
423 size,
424 num_events_in_wait_list,
425 event_wait_list,
426 &raw mut event,
427 ));
428 if CL_SUCCESS == status {
429 Ok(event)
430 } else {
431 Err(status)
432 }
433}
434
435#[inline]
436pub unsafe fn enqueue_copy_buffer(
437 command_queue: cl_command_queue,
438 src_buffer: cl_mem,
439 dst_buffer: cl_mem,
440 src_offset: size_t,
441 dst_offset: size_t,
442 size: size_t,
443 num_events_in_wait_list: cl_uint,
444 event_wait_list: *const cl_event,
445) -> Result<cl_event, cl_int> {
446 let mut event: cl_event = ptr::null_mut();
447 let status: cl_int = cl_call!(clEnqueueCopyBuffer(
448 command_queue,
449 src_buffer,
450 dst_buffer,
451 src_offset,
452 dst_offset,
453 size,
454 num_events_in_wait_list,
455 event_wait_list,
456 &raw mut event,
457 ));
458 if CL_SUCCESS == status {
459 Ok(event)
460 } else {
461 Err(status)
462 }
463}
464
465#[inline]
466pub unsafe fn enqueue_copy_buffer_rect(
467 command_queue: cl_command_queue,
468 src_buffer: cl_mem,
469 dst_buffer: cl_mem,
470 src_origin: *const size_t,
471 dst_origin: *const size_t,
472 region: *const size_t,
473 src_row_pitch: size_t,
474 src_slice_pitch: size_t,
475 dst_row_pitch: size_t,
476 dst_slice_pitch: size_t,
477 num_events_in_wait_list: cl_uint,
478 event_wait_list: *const cl_event,
479) -> Result<cl_event, cl_int> {
480 let mut event: cl_event = ptr::null_mut();
481 let status: cl_int = cl_call!(clEnqueueCopyBufferRect(
482 command_queue,
483 src_buffer,
484 dst_buffer,
485 src_origin,
486 dst_origin,
487 region,
488 src_row_pitch,
489 src_slice_pitch,
490 dst_row_pitch,
491 dst_slice_pitch,
492 num_events_in_wait_list,
493 event_wait_list,
494 &raw mut event,
495 ));
496 if CL_SUCCESS == status {
497 Ok(event)
498 } else {
499 Err(status)
500 }
501}
502
503#[inline]
504pub unsafe fn enqueue_read_image(
505 command_queue: cl_command_queue,
506 image: cl_mem,
507 blocking_read: cl_bool,
508 origin: *const size_t,
509 region: *const size_t,
510 row_pitch: size_t,
511 slice_pitch: size_t,
512 ptr: *mut c_void,
513 num_events_in_wait_list: cl_uint,
514 event_wait_list: *const cl_event,
515) -> Result<cl_event, cl_int> {
516 let mut event: cl_event = ptr::null_mut();
517 let status: cl_int = cl_call!(clEnqueueReadImage(
518 command_queue,
519 image,
520 blocking_read,
521 origin,
522 region,
523 row_pitch,
524 slice_pitch,
525 ptr,
526 num_events_in_wait_list,
527 event_wait_list,
528 &raw mut event,
529 ));
530 if CL_SUCCESS == status {
531 Ok(event)
532 } else {
533 Err(status)
534 }
535}
536
537#[inline]
538pub unsafe fn enqueue_write_image(
539 command_queue: cl_command_queue,
540 image: cl_mem,
541 blocking_write: cl_bool,
542 origin: *const size_t,
543 region: *const size_t,
544 row_pitch: size_t,
545 slice_pitch: size_t,
546 ptr: *mut c_void,
547 num_events_in_wait_list: cl_uint,
548 event_wait_list: *const cl_event,
549) -> Result<cl_event, cl_int> {
550 let mut event: cl_event = ptr::null_mut();
551 let status: cl_int = cl_call!(clEnqueueWriteImage(
552 command_queue,
553 image,
554 blocking_write,
555 origin,
556 region,
557 row_pitch,
558 slice_pitch,
559 ptr,
560 num_events_in_wait_list,
561 event_wait_list,
562 &raw mut event,
563 ));
564 if CL_SUCCESS == status {
565 Ok(event)
566 } else {
567 Err(status)
568 }
569}
570
571#[cfg(any(feature = "CL_VERSION_1_2", feature = "dynamic"))]
572#[inline]
573pub unsafe fn enqueue_fill_image(
574 command_queue: cl_command_queue,
575 image: cl_mem,
576 fill_color: *const c_void,
577 origin: *const size_t,
578 region: *const size_t,
579 num_events_in_wait_list: cl_uint,
580 event_wait_list: *const cl_event,
581) -> Result<cl_event, cl_int> {
582 let mut event: cl_event = ptr::null_mut();
583 let status: cl_int = cl_call!(clEnqueueFillImage(
584 command_queue,
585 image,
586 fill_color,
587 origin,
588 region,
589 num_events_in_wait_list,
590 event_wait_list,
591 &raw mut event,
592 ));
593 if CL_SUCCESS == status {
594 Ok(event)
595 } else {
596 Err(status)
597 }
598}
599
600#[inline]
601pub unsafe fn enqueue_copy_image(
602 command_queue: cl_command_queue,
603 src_image: cl_mem,
604 dst_image: cl_mem,
605 src_origin: *const size_t,
606 dst_origin: *const size_t,
607 region: *const size_t,
608 num_events_in_wait_list: cl_uint,
609 event_wait_list: *const cl_event,
610) -> Result<cl_event, cl_int> {
611 let mut event: cl_event = ptr::null_mut();
612 let status: cl_int = cl_call!(clEnqueueCopyImage(
613 command_queue,
614 src_image,
615 dst_image,
616 src_origin,
617 dst_origin,
618 region,
619 num_events_in_wait_list,
620 event_wait_list,
621 &raw mut event,
622 ));
623 if CL_SUCCESS == status {
624 Ok(event)
625 } else {
626 Err(status)
627 }
628}
629
630#[inline]
631pub unsafe fn enqueue_copy_image_to_buffer(
632 command_queue: cl_command_queue,
633 src_image: cl_mem,
634 dst_buffer: cl_mem,
635 src_origin: *const size_t,
636 region: *const size_t,
637 dst_offset: size_t,
638 num_events_in_wait_list: cl_uint,
639 event_wait_list: *const cl_event,
640) -> Result<cl_event, cl_int> {
641 let mut event: cl_event = ptr::null_mut();
642 let status: cl_int = cl_call!(clEnqueueCopyImageToBuffer(
643 command_queue,
644 src_image,
645 dst_buffer,
646 src_origin,
647 region,
648 dst_offset,
649 num_events_in_wait_list,
650 event_wait_list,
651 &raw mut event,
652 ));
653 if CL_SUCCESS == status {
654 Ok(event)
655 } else {
656 Err(status)
657 }
658}
659
660#[inline]
661pub unsafe fn enqueue_copy_buffer_to_image(
662 command_queue: cl_command_queue,
663 src_buffer: cl_mem,
664 dst_image: cl_mem,
665 src_offset: size_t,
666 dst_origin: *const size_t,
667 region: *const size_t,
668 num_events_in_wait_list: cl_uint,
669 event_wait_list: *const cl_event,
670) -> Result<cl_event, cl_int> {
671 let mut event: cl_event = ptr::null_mut();
672 let status: cl_int = cl_call!(clEnqueueCopyBufferToImage(
673 command_queue,
674 src_buffer,
675 dst_image,
676 src_offset,
677 dst_origin,
678 region,
679 num_events_in_wait_list,
680 event_wait_list,
681 &raw mut event,
682 ));
683 if CL_SUCCESS == status {
684 Ok(event)
685 } else {
686 Err(status)
687 }
688}
689
690#[inline]
693pub unsafe fn enqueue_map_buffer(
694 command_queue: cl_command_queue,
695 buffer: cl_mem,
696 blocking_map: cl_bool,
697 map_flags: cl_map_flags,
698 offset: size_t,
699 size: size_t,
700 buffer_ptr: &mut cl_mem,
701 num_events_in_wait_list: cl_uint,
702 event_wait_list: *const cl_event,
703) -> Result<cl_event, cl_int> {
704 let mut event: cl_event = ptr::null_mut();
705 let mut status: cl_int = CL_INVALID_VALUE;
706 *buffer_ptr = cl_call!(clEnqueueMapBuffer(
707 command_queue,
708 buffer,
709 blocking_map,
710 map_flags,
711 offset,
712 size,
713 num_events_in_wait_list,
714 event_wait_list,
715 &raw mut event,
716 &raw mut status,
717 ));
718 if CL_SUCCESS == status {
719 Ok(event)
720 } else {
721 Err(status)
722 }
723}
724
725#[inline]
728pub unsafe fn enqueue_map_image(
729 command_queue: cl_command_queue,
730 image: cl_mem,
731 blocking_map: cl_bool,
732 map_flags: cl_map_flags,
733 origin: *const size_t,
734 region: *const size_t,
735 image_row_pitch: *mut size_t,
736 image_slice_pitch: *mut size_t,
737 image_ptr: &mut cl_mem,
738 num_events_in_wait_list: cl_uint,
739 event_wait_list: *const cl_event,
740) -> Result<*mut c_void, cl_int> {
741 let mut event: cl_event = ptr::null_mut();
742 let mut status: cl_int = CL_INVALID_VALUE;
743 *image_ptr = cl_call!(clEnqueueMapImage(
744 command_queue,
745 image,
746 blocking_map,
747 map_flags,
748 origin,
749 region,
750 image_row_pitch,
751 image_slice_pitch,
752 num_events_in_wait_list,
753 event_wait_list,
754 &raw mut event,
755 &raw mut status,
756 ));
757 if CL_SUCCESS == status {
758 Ok(event)
759 } else {
760 Err(status)
761 }
762}
763
764#[inline]
765pub unsafe fn enqueue_unmap_mem_object(
766 command_queue: cl_command_queue,
767 memobj: cl_mem,
768 mapped_ptr: *mut c_void,
769 num_events_in_wait_list: cl_uint,
770 event_wait_list: *const cl_event,
771) -> Result<cl_event, cl_int> {
772 let mut event: cl_event = ptr::null_mut();
773 let status: cl_int = cl_call!(clEnqueueUnmapMemObject(
774 command_queue,
775 memobj,
776 mapped_ptr,
777 num_events_in_wait_list,
778 event_wait_list,
779 &raw mut event,
780 ));
781 if CL_SUCCESS == status {
782 Ok(event)
783 } else {
784 Err(status)
785 }
786}
787
788#[cfg(any(feature = "CL_VERSION_1_2", feature = "dynamic"))]
789#[inline]
790pub unsafe fn enqueue_migrate_mem_object(
791 command_queue: cl_command_queue,
792 num_mem_objects: cl_uint,
793 mem_objects: *const cl_mem,
794 flags: cl_mem_migration_flags,
795 num_events_in_wait_list: cl_uint,
796 event_wait_list: *const cl_event,
797) -> Result<cl_event, cl_int> {
798 let mut event: cl_event = ptr::null_mut();
799 let status: cl_int = cl_call!(clEnqueueMigrateMemObjects(
800 command_queue,
801 num_mem_objects,
802 mem_objects,
803 flags,
804 num_events_in_wait_list,
805 event_wait_list,
806 &raw mut event,
807 ));
808 if CL_SUCCESS == status {
809 Ok(event)
810 } else {
811 Err(status)
812 }
813}
814
815#[inline]
816pub unsafe fn enqueue_nd_range_kernel(
817 command_queue: cl_command_queue,
818 kernel: cl_kernel,
819 work_dim: cl_uint,
820 global_work_offset: *const size_t,
821 global_work_dims: *const size_t,
822 local_work_dims: *const size_t,
823 num_events_in_wait_list: cl_uint,
824 event_wait_list: *const cl_event,
825) -> Result<cl_event, cl_int> {
826 let mut event: cl_event = ptr::null_mut();
827 let status: cl_int = cl_call!(clEnqueueNDRangeKernel(
828 command_queue,
829 kernel,
830 work_dim,
831 global_work_offset,
832 global_work_dims,
833 local_work_dims,
834 num_events_in_wait_list,
835 event_wait_list,
836 &raw mut event,
837 ));
838 if CL_SUCCESS == status {
839 Ok(event)
840 } else {
841 Err(status)
842 }
843}
844
845#[cfg_attr(
847 any(
848 feature = "CL_VERSION_2_0",
849 feature = "CL_VERSION_2_1",
850 feature = "CL_VERSION_2_2",
851 feature = "CL_VERSION_3_0"
852 ),
853 deprecated(
854 since = "0.1.0",
855 note = "From CL_VERSION_2_0 use enqueue_nd_range_kernel"
856 )
857)]
858#[inline]
859pub unsafe fn enqueue_task(
860 command_queue: cl_command_queue,
861 kernel: cl_kernel,
862 num_events_in_wait_list: cl_uint,
863 event_wait_list: *const cl_event,
864) -> Result<cl_event, cl_int> {
865 let mut event: cl_event = ptr::null_mut();
866 let status: cl_int = cl_call!(clEnqueueTask(
867 command_queue,
868 kernel,
869 num_events_in_wait_list,
870 event_wait_list,
871 &raw mut event,
872 ));
873 if CL_SUCCESS == status {
874 Ok(event)
875 } else {
876 Err(status)
877 }
878}
879
880#[inline]
881pub unsafe fn enqueue_native_kernel(
882 command_queue: cl_command_queue,
883 user_func: Option<unsafe extern "C" fn(*mut c_void)>,
884 args: *mut c_void,
885 cb_args: size_t,
886 num_mem_objects: cl_uint,
887 mem_list: *const cl_mem,
888 args_mem_loc: *const *const c_void,
889 num_events_in_wait_list: cl_uint,
890 event_wait_list: *const cl_event,
891) -> Result<cl_event, cl_int> {
892 let mut event: cl_event = ptr::null_mut();
893 let status: cl_int = cl_call!(clEnqueueNativeKernel(
894 command_queue,
895 user_func,
896 args,
897 cb_args,
898 num_mem_objects,
899 mem_list,
900 args_mem_loc,
901 num_events_in_wait_list,
902 event_wait_list,
903 &raw mut event,
904 ));
905 if CL_SUCCESS == status {
906 Ok(event)
907 } else {
908 Err(status)
909 }
910}
911
912#[cfg(any(feature = "CL_VERSION_1_2", feature = "dynamic"))]
913#[inline]
914pub unsafe fn enqueue_marker_with_wait_list(
915 command_queue: cl_command_queue,
916 num_events_in_wait_list: cl_uint,
917 event_wait_list: *const cl_event,
918) -> Result<cl_event, cl_int> {
919 let mut event: cl_event = ptr::null_mut();
920 let status: cl_int = cl_call!(clEnqueueMarkerWithWaitList(
921 command_queue,
922 num_events_in_wait_list,
923 event_wait_list,
924 &raw mut event,
925 ));
926 if CL_SUCCESS == status {
927 Ok(event)
928 } else {
929 Err(status)
930 }
931}
932
933#[cfg(any(feature = "CL_VERSION_1_2", feature = "dynamic"))]
934#[inline]
935pub unsafe fn enqueue_barrier_with_wait_list(
936 command_queue: cl_command_queue,
937 num_events_in_wait_list: cl_uint,
938 event_wait_list: *const cl_event,
939) -> Result<cl_event, cl_int> {
940 let mut event: cl_event = ptr::null_mut();
941 let status: cl_int = cl_call!(clEnqueueBarrierWithWaitList(
942 command_queue,
943 num_events_in_wait_list,
944 event_wait_list,
945 &raw mut event,
946 ));
947 if CL_SUCCESS == status {
948 Ok(event)
949 } else {
950 Err(status)
951 }
952}
953
954#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
955#[inline]
956pub unsafe fn enqueue_svm_free(
957 command_queue: cl_command_queue,
958 num_svm_pointers: cl_uint,
959 svm_pointers: *const *const c_void,
960 pfn_free_func: Option<
961 unsafe extern "C" fn(
962 queue: cl_command_queue,
963 num_svm_pointers: cl_uint,
964 svm_pointers: *mut *mut c_void,
965 user_data: *mut c_void,
966 ),
967 >,
968 user_data: *mut c_void,
969 num_events_in_wait_list: cl_uint,
970 event_wait_list: *const cl_event,
971) -> Result<cl_event, cl_int> {
972 let mut event: cl_event = ptr::null_mut();
973 let status: cl_int = cl_call!(clEnqueueSVMFree(
974 command_queue,
975 num_svm_pointers,
976 svm_pointers,
977 pfn_free_func,
978 user_data,
979 num_events_in_wait_list,
980 event_wait_list,
981 &raw mut event,
982 ));
983 if CL_SUCCESS == status {
984 Ok(event)
985 } else {
986 Err(status)
987 }
988}
989
990#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
991#[inline]
992pub unsafe fn enqueue_svm_mem_cpy(
993 command_queue: cl_command_queue,
994 blocking_copy: cl_bool,
995 dst_ptr: *mut c_void,
996 src_ptr: *const c_void,
997 size: size_t,
998 num_events_in_wait_list: cl_uint,
999 event_wait_list: *const cl_event,
1000) -> Result<cl_event, cl_int> {
1001 let mut event: cl_event = ptr::null_mut();
1002 let status: cl_int = cl_call!(clEnqueueSVMMemcpy(
1003 command_queue,
1004 blocking_copy,
1005 dst_ptr,
1006 src_ptr,
1007 size,
1008 num_events_in_wait_list,
1009 event_wait_list,
1010 &raw mut event,
1011 ));
1012 if CL_SUCCESS == status {
1013 Ok(event)
1014 } else {
1015 Err(status)
1016 }
1017}
1018
1019#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
1020#[inline]
1021pub unsafe fn enqueue_svm_mem_fill(
1022 command_queue: cl_command_queue,
1023 svm_ptr: *mut c_void,
1024 pattern: *const c_void,
1025 pattern_size: size_t,
1026 size: size_t,
1027 num_events_in_wait_list: cl_uint,
1028 event_wait_list: *const cl_event,
1029) -> Result<cl_event, cl_int> {
1030 let mut event: cl_event = ptr::null_mut();
1031 let status: cl_int = cl_call!(clEnqueueSVMMemFill(
1032 command_queue,
1033 svm_ptr,
1034 pattern,
1035 pattern_size,
1036 size,
1037 num_events_in_wait_list,
1038 event_wait_list,
1039 &raw mut event,
1040 ));
1041 if CL_SUCCESS == status {
1042 Ok(event)
1043 } else {
1044 Err(status)
1045 }
1046}
1047
1048#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
1049#[inline]
1050pub unsafe fn enqueue_svm_map(
1051 command_queue: cl_command_queue,
1052 blocking_map: cl_bool,
1053 flags: cl_map_flags,
1054 svm_ptr: *mut c_void,
1055 size: size_t,
1056 num_events_in_wait_list: cl_uint,
1057 event_wait_list: *const cl_event,
1058) -> Result<cl_event, cl_int> {
1059 let mut event: cl_event = ptr::null_mut();
1060 let status: cl_int = cl_call!(clEnqueueSVMMap(
1061 command_queue,
1062 blocking_map,
1063 flags,
1064 svm_ptr,
1065 size,
1066 num_events_in_wait_list,
1067 event_wait_list,
1068 &raw mut event,
1069 ));
1070 if CL_SUCCESS == status {
1071 Ok(event)
1072 } else {
1073 Err(status)
1074 }
1075}
1076
1077#[cfg(any(feature = "CL_VERSION_2_0", feature = "dynamic"))]
1078#[inline]
1079pub unsafe fn enqueue_svm_unmap(
1080 command_queue: cl_command_queue,
1081 svm_ptr: *mut c_void,
1082 num_events_in_wait_list: cl_uint,
1083 event_wait_list: *const cl_event,
1084) -> Result<cl_event, cl_int> {
1085 let mut event: cl_event = ptr::null_mut();
1086 let status: cl_int = cl_call!(clEnqueueSVMUnmap(
1087 command_queue,
1088 svm_ptr,
1089 num_events_in_wait_list,
1090 event_wait_list,
1091 &raw mut event,
1092 ));
1093 if CL_SUCCESS == status {
1094 Ok(event)
1095 } else {
1096 Err(status)
1097 }
1098}
1099
1100#[cfg(any(feature = "CL_VERSION_2_1", feature = "dynamic"))]
1101#[inline]
1102pub unsafe fn enqueue_svm_migrate_mem(
1103 command_queue: cl_command_queue,
1104 num_svm_pointers: cl_uint,
1105 svm_pointers: *const *const c_void,
1106 sizes: *const size_t,
1107 flags: cl_mem_migration_flags,
1108 num_events_in_wait_list: cl_uint,
1109 event_wait_list: *const cl_event,
1110) -> Result<cl_event, cl_int> {
1111 let mut event: cl_event = ptr::null_mut();
1112 let status: cl_int = cl_call!(clEnqueueSVMMigrateMem(
1113 command_queue,
1114 num_svm_pointers,
1115 svm_pointers,
1116 sizes,
1117 flags,
1118 num_events_in_wait_list,
1119 event_wait_list,
1120 &raw mut event,
1121 ));
1122 if CL_SUCCESS == status {
1123 Ok(event)
1124 } else {
1125 Err(status)
1126 }
1127}
1128
1129#[cfg(test)]
1130mod tests {
1131 use super::*;
1132 use crate::context::{create_context, release_context};
1133 use crate::device::{CL_DEVICE_TYPE_GPU, get_device_ids};
1134 use crate::error_codes::error_text;
1135 use crate::platform::get_platform_ids;
1136
1137 #[test]
1138 fn test_command_queue() {
1139 let platform_ids = get_platform_ids().unwrap();
1140
1141 let platform_id = platform_ids[0];
1143
1144 let device_ids = get_device_ids(platform_id, CL_DEVICE_TYPE_GPU).unwrap();
1145 assert!(0 < device_ids.len());
1146
1147 let device_id = device_ids[0];
1148
1149 let context = create_context(&device_ids, ptr::null(), None, ptr::null_mut());
1150 let context = context.unwrap();
1151
1152 let queue = unsafe {
1153 create_command_queue(
1154 context,
1155 device_id,
1156 CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,
1157 )
1158 .unwrap()
1159 };
1160
1161 let value = get_command_queue_info(queue, CL_QUEUE_CONTEXT).unwrap();
1162 let value = intptr_t::from(value);
1163 println!("CL_QUEUE_CONTEXT: {:X}", value);
1164 assert_eq!(context, value as cl_context);
1165
1166 let value = get_command_queue_info(queue, CL_QUEUE_DEVICE).unwrap();
1167 let value = intptr_t::from(value);
1168 println!("CL_QUEUE_DEVICE: {:X}", value);
1169 assert_eq!(device_id, value as cl_device_id);
1170
1171 let value = get_command_queue_info(queue, CL_QUEUE_REFERENCE_COUNT).unwrap();
1172 let value = cl_uint::from(value);
1173 println!("CL_QUEUE_REFERENCE_COUNT: {}", value);
1174 assert_eq!(1, value);
1175
1176 let value = get_command_queue_info(queue, CL_QUEUE_PROPERTIES).unwrap();
1177 let value = cl_ulong::from(value);
1178 println!("CL_QUEUE_PROPERTIES: {}", value);
1179
1180 match get_command_queue_info(queue, CL_QUEUE_SIZE) {
1182 Ok(value) => {
1183 let value = cl_uint::from(value);
1184 println!("CL_QUEUE_SIZE: {}", value);
1185 }
1186 Err(e) => println!("OpenCL error, CL_QUEUE_SIZE: {}", error_text(e)),
1187 };
1188
1189 match get_command_queue_info(queue, CL_QUEUE_DEVICE_DEFAULT) {
1191 Ok(value) => {
1192 let value = intptr_t::from(value);
1193 println!("CL_QUEUE_DEVICE_DEFAULT: {:X}", value);
1194 }
1195 Err(e) => println!("OpenCL error, CL_QUEUE_DEVICE_DEFAULT: {}", error_text(e)),
1196 };
1197
1198 match get_command_queue_info(queue, CL_QUEUE_PROPERTIES_ARRAY) {
1200 Ok(value) => {
1201 let value = Vec::<cl_ulong>::from(value);
1202 println!("CL_QUEUE_PROPERTIES_ARRAY: {}", value.len());
1203 }
1204 Err(e) => println!("OpenCL error, CL_QUEUE_PROPERTIES_ARRAY: {}", error_text(e)),
1205 };
1206
1207 unsafe {
1208 release_command_queue(queue).unwrap();
1209 release_context(context).unwrap();
1210 }
1211 }
1212}