1#![allow(unused_unsafe)]
18#![allow(non_camel_case_types)]
19#![allow(clippy::not_unsafe_ptr_arg_deref)]
20
21pub use opencl_sys::{
22 CL_COMMAND_ACQUIRE_GL_OBJECTS, CL_COMMAND_BARRIER, CL_COMMAND_COMMAND_BUFFER_KHR,
23 CL_COMMAND_COPY_BUFFER, CL_COMMAND_COPY_BUFFER_RECT, CL_COMMAND_COPY_BUFFER_TO_IMAGE,
24 CL_COMMAND_COPY_IMAGE, CL_COMMAND_COPY_IMAGE_TO_BUFFER, CL_COMMAND_FILL_BUFFER,
25 CL_COMMAND_FILL_IMAGE, CL_COMMAND_MAP_BUFFER, CL_COMMAND_MAP_IMAGE, CL_COMMAND_MARKER,
26 CL_COMMAND_MEMADVISE_INTEL, CL_COMMAND_MEMCPY_INTEL, CL_COMMAND_MEMFILL_INTEL,
27 CL_COMMAND_MIGRATE_MEM_OBJECTS, CL_COMMAND_MIGRATEMEM_INTEL, CL_COMMAND_NATIVE_KERNEL,
28 CL_COMMAND_NDRANGE_KERNEL, CL_COMMAND_READ_BUFFER, CL_COMMAND_READ_BUFFER_RECT,
29 CL_COMMAND_READ_IMAGE, CL_COMMAND_RELEASE_GL_OBJECTS, CL_COMMAND_SVM_FREE, CL_COMMAND_SVM_MAP,
30 CL_COMMAND_SVM_MEMCPY, CL_COMMAND_SVM_MEMFILL, CL_COMMAND_SVM_MIGRATE_MEM,
31 CL_COMMAND_SVM_UNMAP, CL_COMMAND_TASK, CL_COMMAND_UNMAP_MEM_OBJECT, CL_COMMAND_USER,
32 CL_COMMAND_WRITE_BUFFER, CL_COMMAND_WRITE_BUFFER_RECT, CL_COMMAND_WRITE_IMAGE, CL_COMPLETE,
33 CL_EVENT_COMMAND_EXECUTION_STATUS, CL_EVENT_COMMAND_QUEUE, CL_EVENT_COMMAND_TYPE,
34 CL_EVENT_CONTEXT, CL_EVENT_REFERENCE_COUNT, CL_INVALID_VALUE, CL_PROFILING_COMMAND_COMPLETE,
35 CL_PROFILING_COMMAND_END, CL_PROFILING_COMMAND_QUEUED, CL_PROFILING_COMMAND_START,
36 CL_PROFILING_COMMAND_SUBMIT, CL_QUEUED, CL_RUNNING, CL_SUBMITTED, CL_SUCCESS, cl_command_queue,
37 cl_command_type, cl_context, cl_event, cl_event_info, cl_int, cl_profiling_info, cl_uint,
38 cl_ulong,
39};
40
41pub use opencl_sys::cl_egl::{
42 CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR, CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR,
43 CL_COMMAND_RELEASE_EGL_OBJECTS_KHR,
44};
45
46use super::info_type::InfoType;
47use super::{api_info_size, api_info_value, api_info_vector};
48use libc::{c_void, intptr_t, size_t};
49use std::fmt;
50use std::mem;
51use std::ptr;
52
53#[inline]
60#[allow(clippy::cast_possible_truncation)]
61pub fn wait_for_events(events: &[cl_event]) -> Result<(), cl_int> {
62 let status: cl_int =
63 unsafe { cl_call!(clWaitForEvents(events.len() as cl_uint, events.as_ptr())) };
64 if CL_SUCCESS == status {
65 Ok(())
66 } else {
67 Err(status)
68 }
69}
70
71pub fn get_event_data(event: cl_event, param_name: cl_event_info) -> Result<Vec<u8>, cl_int> {
74 api_info_size!(get_size, clGetEventInfo);
75 let size = get_size(event, param_name)?;
76 api_info_vector!(get_vector, u8, clGetEventInfo);
77 get_vector(event, param_name, size)
78}
79
80pub fn get_event_info(event: cl_event, param_name: cl_event_info) -> Result<InfoType, cl_int> {
90 match param_name {
91 CL_EVENT_COMMAND_EXECUTION_STATUS => {
92 api_info_value!(get_value, cl_int, clGetEventInfo);
93 Ok(InfoType::Int(get_value(event, param_name)?))
94 }
95
96 CL_EVENT_COMMAND_TYPE | CL_EVENT_REFERENCE_COUNT => {
97 api_info_value!(get_value, cl_uint, clGetEventInfo);
98 Ok(InfoType::Uint(get_value(event, param_name)?))
99 }
100
101 CL_EVENT_COMMAND_QUEUE | CL_EVENT_CONTEXT => {
102 api_info_value!(get_value, intptr_t, clGetEventInfo);
103 Ok(InfoType::Ptr(get_value(event, param_name)?))
104 }
105
106 _ => Ok(InfoType::VecUchar(get_event_data(event, param_name)?)),
107 }
108}
109
110#[inline]
118pub fn create_user_event(context: cl_context) -> Result<cl_event, cl_int> {
119 let mut status: cl_int = CL_INVALID_VALUE;
120 let event: cl_event = unsafe { cl_call!(clCreateUserEvent(context, &raw mut status)) };
121 if CL_SUCCESS == status {
122 Ok(event)
123 } else {
124 Err(status)
125 }
126}
127
128#[inline]
139pub unsafe fn retain_event(event: cl_event) -> Result<(), cl_int> {
140 let status: cl_int = cl_call!(clRetainEvent(event));
141 if CL_SUCCESS == status {
142 Ok(())
143 } else {
144 Err(status)
145 }
146}
147
148#[inline]
159pub unsafe fn release_event(event: cl_event) -> Result<(), cl_int> {
160 let status: cl_int = cl_call!(clReleaseEvent(event));
161 if CL_SUCCESS == status {
162 Ok(())
163 } else {
164 Err(status)
165 }
166}
167
168#[inline]
176pub fn set_user_event_status(event: cl_event, execution_status: cl_int) -> Result<(), cl_int> {
177 let status: cl_int = unsafe { cl_call!(clSetUserEventStatus(event, execution_status)) };
178 if CL_SUCCESS == status {
179 Ok(())
180 } else {
181 Err(status)
182 }
183}
184
185#[inline]
194pub fn set_event_callback(
195 event: cl_event,
196 command_exec_callback_type: cl_int,
197 pfn_notify: extern "C" fn(cl_event, cl_int, *mut c_void),
198 user_data: *mut c_void,
199) -> Result<(), cl_int> {
200 let status: cl_int = unsafe {
201 cl_call!(clSetEventCallback(
202 event,
203 command_exec_callback_type,
204 Some(pfn_notify),
205 user_data,
206 ))
207 };
208 if CL_SUCCESS == status {
209 Ok(())
210 } else {
211 Err(status)
212 }
213}
214
215pub fn get_event_profiling_data(
218 event: cl_event,
219 param_name: cl_profiling_info,
220) -> Result<Vec<u8>, cl_int> {
221 api_info_size!(get_size, clGetEventProfilingInfo);
222 let size = get_size(event, param_name)?;
223 api_info_vector!(get_vector, u8, clGetEventProfilingInfo);
224 get_vector(event, param_name, size)
225}
226
227pub fn get_event_profiling_info(
238 event: cl_event,
239 param_name: cl_profiling_info,
240) -> Result<InfoType, cl_int> {
241 match param_name {
242 CL_PROFILING_COMMAND_QUEUED
243 | CL_PROFILING_COMMAND_SUBMIT
244 | CL_PROFILING_COMMAND_START
245 | CL_PROFILING_COMMAND_END
246 | CL_PROFILING_COMMAND_COMPLETE => {
248 api_info_value!(get_value, cl_ulong, clGetEventProfilingInfo);
249 Ok(InfoType::Ulong(get_value(event, param_name)?))
250 }
251
252 _ => Ok(InfoType::VecUchar(get_event_profiling_data(event, param_name)?))
253 }
254}
255
256#[must_use]
257pub const fn status_text(status: cl_int) -> &'static str {
258 match status {
259 CL_COMPLETE => "CL_COMPLETE",
260 CL_RUNNING => "CL_RUNNING",
261 CL_SUBMITTED => "CL_SUBMITTED",
262 CL_QUEUED => "CL_QUEUED",
263 _ => "UNKNOWN_STATUS",
264 }
265}
266
267#[derive(Debug)]
268pub struct CommandExecutionStatus(pub cl_int);
270
271impl From<cl_int> for CommandExecutionStatus {
273 fn from(status: cl_int) -> Self {
274 Self(status)
275 }
276}
277
278impl fmt::Display for CommandExecutionStatus {
280 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
281 write!(f, "{}", status_text(self.0))
282 }
283}
284
285#[must_use]
286pub const fn command_type_text(command_type: cl_command_type) -> &'static str {
287 match command_type {
288 CL_COMMAND_NDRANGE_KERNEL => "CL_COMMAND_NDRANGE_KERNEL",
289 CL_COMMAND_TASK => "CL_COMMAND_TASK",
290 CL_COMMAND_NATIVE_KERNEL => "CL_COMMAND_NATIVE_KERNEL",
291 CL_COMMAND_READ_BUFFER => "CL_COMMAND_READ_BUFFER",
292 CL_COMMAND_WRITE_BUFFER => "CL_COMMAND_WRITE_BUFFER",
293 CL_COMMAND_COPY_BUFFER => "CL_COMMAND_COPY_BUFFER",
294 CL_COMMAND_READ_IMAGE => "CL_COMMAND_READ_IMAGE",
295 CL_COMMAND_WRITE_IMAGE => "CL_COMMAND_WRITE_IMAGE",
296 CL_COMMAND_COPY_IMAGE => "CL_COMMAND_COPY_IMAGE",
297 CL_COMMAND_COPY_IMAGE_TO_BUFFER => "CL_COMMAND_COPY_IMAGE_TO_BUFFER",
298 CL_COMMAND_COPY_BUFFER_TO_IMAGE => "CL_COMMAND_COPY_BUFFER_TO_IMAGE",
299 CL_COMMAND_MAP_BUFFER => "CL_COMMAND_MAP_BUFFER",
300 CL_COMMAND_MAP_IMAGE => "CL_COMMAND_MAP_IMAGE",
301 CL_COMMAND_UNMAP_MEM_OBJECT => "CL_COMMAND_UNMAP_MEM_OBJECT",
302 CL_COMMAND_MARKER => "CL_COMMAND_MARKER",
303 CL_COMMAND_ACQUIRE_GL_OBJECTS => "CL_COMMAND_ACQUIRE_GL_OBJECTS",
304 CL_COMMAND_RELEASE_GL_OBJECTS => "CL_COMMAND_RELEASE_GL_OBJECTS",
305 CL_COMMAND_READ_BUFFER_RECT => "CL_COMMAND_READ_BUFFER_RECT",
306 CL_COMMAND_WRITE_BUFFER_RECT => "CL_COMMAND_WRITE_BUFFER_RECT",
307 CL_COMMAND_COPY_BUFFER_RECT => "CL_COMMAND_COPY_BUFFER_RECT",
308 CL_COMMAND_USER => "CL_COMMAND_USER",
309 CL_COMMAND_BARRIER => "CL_COMMAND_BARRIER",
310 CL_COMMAND_MIGRATE_MEM_OBJECTS => "CL_COMMAND_MIGRATE_MEM_OBJECTS",
311 CL_COMMAND_FILL_BUFFER => "CL_COMMAND_FILL_BUFFER",
312 CL_COMMAND_FILL_IMAGE => "CL_COMMAND_FILL_IMAGE",
313 CL_COMMAND_SVM_FREE => "CL_COMMAND_SVM_FREE",
314 CL_COMMAND_SVM_MEMCPY => "CL_COMMAND_SVM_MEMCPY",
315 CL_COMMAND_SVM_MEMFILL => "CL_COMMAND_SVM_MEMFILL",
316 CL_COMMAND_SVM_MAP => "CL_COMMAND_SVM_MAP",
317 CL_COMMAND_SVM_UNMAP => "CL_COMMAND_SVM_UNMAP",
318 CL_COMMAND_SVM_MIGRATE_MEM => "CL_COMMAND_SVM_MIGRATE_MEM",
319
320 CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR => "CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR",
322 CL_COMMAND_RELEASE_EGL_OBJECTS_KHR => "CL_COMMAND_RELEASE_EGL_OBJECTS_KHR",
323 CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR => "CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR",
324
325 CL_COMMAND_MEMFILL_INTEL => "CL_COMMAND_MEMFILL_INTEL",
327 CL_COMMAND_MEMCPY_INTEL => "CL_COMMAND_MEMCPY_INTEL",
328 CL_COMMAND_MIGRATEMEM_INTEL => "CL_COMMAND_MIGRATEMEM_INTEL",
329 CL_COMMAND_MEMADVISE_INTEL => "CL_COMMAND_MEMADVISE_INTEL",
330
331 CL_COMMAND_COMMAND_BUFFER_KHR => "CL_COMMAND_COMMAND_BUFFER_KHR",
333
334 _ => "UNKNOWN_COMMAND_TYPE",
335 }
336}
337
338#[derive(Debug)]
339pub struct EventCommandType(pub cl_command_type);
341
342impl From<cl_command_type> for EventCommandType {
344 fn from(command_type: cl_command_type) -> Self {
345 Self(command_type)
346 }
347}
348
349impl fmt::Display for EventCommandType {
351 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
352 write!(f, "{}", command_type_text(self.0))
353 }
354}
355
356#[cfg(test)]
357mod tests {
358 use super::*;
359
360 #[test]
361 fn test_status_text() {
362 let text = status_text(CL_COMPLETE);
363 assert_eq!("CL_COMPLETE", text);
364
365 let text = status_text(CL_RUNNING);
366 assert_eq!("CL_RUNNING", text);
367
368 let text = status_text(CL_SUBMITTED);
369 assert_eq!("CL_SUBMITTED", text);
370
371 let text = status_text(CL_QUEUED);
372 assert_eq!("CL_QUEUED", text);
373
374 let text = status_text(CL_QUEUED + 1);
375 assert_eq!("UNKNOWN_STATUS", text);
376 }
377
378 #[test]
379 fn test_command_type_text() {
380 let text = command_type_text(CL_COMMAND_NDRANGE_KERNEL);
381 assert_eq!("CL_COMMAND_NDRANGE_KERNEL", text);
382
383 let text = command_type_text(CL_COMMAND_COPY_IMAGE);
384 assert_eq!("CL_COMMAND_COPY_IMAGE", text);
385
386 let text = command_type_text(CL_COMMAND_READ_BUFFER_RECT);
387 assert_eq!("CL_COMMAND_READ_BUFFER_RECT", text);
388
389 let text = command_type_text(CL_COMMAND_BARRIER);
390 assert_eq!("CL_COMMAND_BARRIER", text);
391
392 let text = command_type_text(CL_COMMAND_SVM_FREE);
393 assert_eq!("CL_COMMAND_SVM_FREE", text);
394
395 let text = command_type_text(CL_COMMAND_SVM_MIGRATE_MEM + 1);
396 assert_eq!("UNKNOWN_COMMAND_TYPE", text);
397 }
398}