#![allow(non_camel_case_types)]
#![allow(clippy::not_unsafe_ptr_arg_deref)]
pub use opencl_sys::{
cl_command_queue, cl_command_type, cl_context, cl_event, cl_event_info, cl_int,
cl_profiling_info, cl_uint, cl_ulong, CL_COMMAND_ACQUIRE_GL_OBJECTS, CL_COMMAND_BARRIER,
CL_COMMAND_COMMAND_BUFFER_KHR, CL_COMMAND_COPY_BUFFER, CL_COMMAND_COPY_BUFFER_RECT,
CL_COMMAND_COPY_BUFFER_TO_IMAGE, CL_COMMAND_COPY_IMAGE, CL_COMMAND_COPY_IMAGE_TO_BUFFER,
CL_COMMAND_FILL_BUFFER, CL_COMMAND_FILL_IMAGE, CL_COMMAND_MAP_BUFFER, CL_COMMAND_MAP_IMAGE,
CL_COMMAND_MARKER, CL_COMMAND_MEMADVISE_INTEL, CL_COMMAND_MEMCPY_INTEL,
CL_COMMAND_MEMFILL_INTEL, CL_COMMAND_MIGRATEMEM_INTEL, CL_COMMAND_MIGRATE_MEM_OBJECTS,
CL_COMMAND_NATIVE_KERNEL, CL_COMMAND_NDRANGE_KERNEL, CL_COMMAND_READ_BUFFER,
CL_COMMAND_READ_BUFFER_RECT, CL_COMMAND_READ_IMAGE, CL_COMMAND_RELEASE_GL_OBJECTS,
CL_COMMAND_SVM_FREE, CL_COMMAND_SVM_MAP, CL_COMMAND_SVM_MEMCPY, CL_COMMAND_SVM_MEMFILL,
CL_COMMAND_SVM_MIGRATE_MEM, CL_COMMAND_SVM_UNMAP, CL_COMMAND_TASK, CL_COMMAND_UNMAP_MEM_OBJECT,
CL_COMMAND_USER, CL_COMMAND_WRITE_BUFFER, CL_COMMAND_WRITE_BUFFER_RECT, CL_COMMAND_WRITE_IMAGE,
CL_COMPLETE, CL_EVENT_COMMAND_EXECUTION_STATUS, CL_EVENT_COMMAND_QUEUE, CL_EVENT_COMMAND_TYPE,
CL_EVENT_CONTEXT, CL_EVENT_REFERENCE_COUNT, CL_INVALID_VALUE, CL_PROFILING_COMMAND_COMPLETE,
CL_PROFILING_COMMAND_END, CL_PROFILING_COMMAND_QUEUED, CL_PROFILING_COMMAND_START,
CL_PROFILING_COMMAND_SUBMIT, CL_QUEUED, CL_RUNNING, CL_SUBMITTED, CL_SUCCESS,
};
pub use opencl_sys::cl_egl::{
CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR, CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR,
CL_COMMAND_RELEASE_EGL_OBJECTS_KHR,
};
use opencl_sys::{
clCreateUserEvent, clGetEventInfo, clGetEventProfilingInfo, clReleaseEvent, clRetainEvent,
clSetEventCallback, clSetUserEventStatus, clWaitForEvents,
};
use super::info_type::InfoType;
use super::{api_info_size, api_info_value, api_info_vector};
use libc::{c_void, intptr_t, size_t};
use std::fmt;
use std::mem;
use std::ptr;
#[inline]
pub fn wait_for_events(events: &[cl_event]) -> Result<(), cl_int> {
let status: cl_int = unsafe { clWaitForEvents(events.len() as cl_uint, events.as_ptr()) };
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
pub fn get_event_data(event: cl_event, param_name: cl_event_info) -> Result<Vec<u8>, cl_int> {
api_info_size!(get_size, clGetEventInfo);
let size = get_size(event, param_name)?;
api_info_vector!(get_vector, u8, clGetEventInfo);
get_vector(event, param_name, size)
}
pub fn get_event_info(event: cl_event, param_name: cl_event_info) -> Result<InfoType, cl_int> {
match param_name {
CL_EVENT_COMMAND_EXECUTION_STATUS => {
api_info_value!(get_value, cl_int, clGetEventInfo);
Ok(InfoType::Int(get_value(event, param_name)?))
}
CL_EVENT_COMMAND_TYPE | CL_EVENT_REFERENCE_COUNT => {
api_info_value!(get_value, cl_uint, clGetEventInfo);
Ok(InfoType::Uint(get_value(event, param_name)?))
}
CL_EVENT_COMMAND_QUEUE | CL_EVENT_CONTEXT => {
api_info_value!(get_value, intptr_t, clGetEventInfo);
Ok(InfoType::Ptr(get_value(event, param_name)?))
}
_ => Ok(InfoType::VecUchar(get_event_data(event, param_name)?)),
}
}
#[inline]
pub fn create_user_event(context: cl_context) -> Result<cl_event, cl_int> {
let mut status: cl_int = CL_INVALID_VALUE;
let event: cl_event = unsafe { clCreateUserEvent(context, &mut status) };
if CL_SUCCESS != status {
Err(status)
} else {
Ok(event)
}
}
#[inline]
pub unsafe fn retain_event(event: cl_event) -> Result<(), cl_int> {
let status: cl_int = clRetainEvent(event);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
#[inline]
pub unsafe fn release_event(event: cl_event) -> Result<(), cl_int> {
let status: cl_int = clReleaseEvent(event);
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
#[inline]
pub fn set_user_event_status(event: cl_event, execution_status: cl_int) -> Result<(), cl_int> {
let status: cl_int = unsafe { clSetUserEventStatus(event, execution_status) };
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
#[inline]
pub fn set_event_callback(
event: cl_event,
command_exec_callback_type: cl_int,
pfn_notify: extern "C" fn(cl_event, cl_int, *mut c_void),
user_data: *mut c_void,
) -> Result<(), cl_int> {
let status: cl_int = unsafe {
clSetEventCallback(
event,
command_exec_callback_type,
Some(pfn_notify),
user_data,
)
};
if CL_SUCCESS != status {
Err(status)
} else {
Ok(())
}
}
pub fn get_event_profiling_data(
event: cl_event,
param_name: cl_profiling_info,
) -> Result<Vec<u8>, cl_int> {
api_info_size!(get_size, clGetEventProfilingInfo);
let size = get_size(event, param_name)?;
api_info_vector!(get_vector, u8, clGetEventProfilingInfo);
get_vector(event, param_name, size)
}
pub fn get_event_profiling_info(
event: cl_event,
param_name: cl_profiling_info,
) -> Result<InfoType, cl_int> {
match param_name {
CL_PROFILING_COMMAND_QUEUED
| CL_PROFILING_COMMAND_SUBMIT
| CL_PROFILING_COMMAND_START
| CL_PROFILING_COMMAND_END
| CL_PROFILING_COMMAND_COMPLETE => {
api_info_value!(get_value, cl_ulong, clGetEventProfilingInfo);
Ok(InfoType::Ulong(get_value(event, param_name)?))
}
_ => Ok(InfoType::VecUchar(get_event_profiling_data(event, param_name)?))
}
}
pub fn status_text(status: cl_int) -> &'static str {
match status {
CL_COMPLETE => "CL_COMPLETE",
CL_RUNNING => "CL_RUNNING",
CL_SUBMITTED => "CL_SUBMITTED",
CL_QUEUED => "CL_QUEUED",
_ => "UNKNOWN_STATUS",
}
}
#[derive(Debug)]
pub struct CommandExecutionStatus(pub cl_int);
impl From<cl_int> for CommandExecutionStatus {
fn from(status: cl_int) -> Self {
CommandExecutionStatus(status)
}
}
impl fmt::Display for CommandExecutionStatus {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", status_text(self.0))
}
}
pub fn command_type_text(command_type: cl_command_type) -> &'static str {
match command_type {
CL_COMMAND_NDRANGE_KERNEL => "CL_COMMAND_NDRANGE_KERNEL",
CL_COMMAND_TASK => "CL_COMMAND_TASK",
CL_COMMAND_NATIVE_KERNEL => "CL_COMMAND_NATIVE_KERNEL",
CL_COMMAND_READ_BUFFER => "CL_COMMAND_READ_BUFFER",
CL_COMMAND_WRITE_BUFFER => "CL_COMMAND_WRITE_BUFFER",
CL_COMMAND_COPY_BUFFER => "CL_COMMAND_COPY_BUFFER",
CL_COMMAND_READ_IMAGE => "CL_COMMAND_READ_IMAGE",
CL_COMMAND_WRITE_IMAGE => "CL_COMMAND_WRITE_IMAGE",
CL_COMMAND_COPY_IMAGE => "CL_COMMAND_COPY_IMAGE",
CL_COMMAND_COPY_IMAGE_TO_BUFFER => "CL_COMMAND_COPY_IMAGE_TO_BUFFER",
CL_COMMAND_COPY_BUFFER_TO_IMAGE => "CL_COMMAND_COPY_BUFFER_TO_IMAGE",
CL_COMMAND_MAP_BUFFER => "CL_COMMAND_MAP_BUFFER",
CL_COMMAND_MAP_IMAGE => "CL_COMMAND_MAP_IMAGE",
CL_COMMAND_UNMAP_MEM_OBJECT => "CL_COMMAND_UNMAP_MEM_OBJECT",
CL_COMMAND_MARKER => "CL_COMMAND_MARKER",
CL_COMMAND_ACQUIRE_GL_OBJECTS => "CL_COMMAND_ACQUIRE_GL_OBJECTS",
CL_COMMAND_RELEASE_GL_OBJECTS => "CL_COMMAND_RELEASE_GL_OBJECTS",
CL_COMMAND_READ_BUFFER_RECT => "CL_COMMAND_READ_BUFFER_RECT",
CL_COMMAND_WRITE_BUFFER_RECT => "CL_COMMAND_WRITE_BUFFER_RECT",
CL_COMMAND_COPY_BUFFER_RECT => "CL_COMMAND_COPY_BUFFER_RECT",
CL_COMMAND_USER => "CL_COMMAND_USER",
CL_COMMAND_BARRIER => "CL_COMMAND_BARRIER",
CL_COMMAND_MIGRATE_MEM_OBJECTS => "CL_COMMAND_MIGRATE_MEM_OBJECTS",
CL_COMMAND_FILL_BUFFER => "CL_COMMAND_FILL_BUFFER",
CL_COMMAND_FILL_IMAGE => "CL_COMMAND_FILL_IMAGE",
CL_COMMAND_SVM_FREE => "CL_COMMAND_SVM_FREE",
CL_COMMAND_SVM_MEMCPY => "CL_COMMAND_SVM_MEMCPY",
CL_COMMAND_SVM_MEMFILL => "CL_COMMAND_SVM_MEMFILL",
CL_COMMAND_SVM_MAP => "CL_COMMAND_SVM_MAP",
CL_COMMAND_SVM_UNMAP => "CL_COMMAND_SVM_UNMAP",
CL_COMMAND_SVM_MIGRATE_MEM => "CL_COMMAND_SVM_MIGRATE_MEM",
CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR => "CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR",
CL_COMMAND_RELEASE_EGL_OBJECTS_KHR => "CL_COMMAND_RELEASE_EGL_OBJECTS_KHR",
CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR => "CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR",
CL_COMMAND_MEMFILL_INTEL => "CL_COMMAND_MEMFILL_INTEL",
CL_COMMAND_MEMCPY_INTEL => "CL_COMMAND_MEMCPY_INTEL",
CL_COMMAND_MIGRATEMEM_INTEL => "CL_COMMAND_MIGRATEMEM_INTEL",
CL_COMMAND_MEMADVISE_INTEL => "CL_COMMAND_MEMADVISE_INTEL",
CL_COMMAND_COMMAND_BUFFER_KHR => "CL_COMMAND_COMMAND_BUFFER_KHR",
_ => "UNKNOWN_COMMAND_TYPE",
}
}
#[derive(Debug)]
pub struct EventCommandType(pub cl_command_type);
impl From<cl_command_type> for EventCommandType {
fn from(command_type: cl_command_type) -> Self {
EventCommandType(command_type)
}
}
impl fmt::Display for EventCommandType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", command_type_text(self.0))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_status_text() {
let text = status_text(CL_COMPLETE);
assert_eq!("CL_COMPLETE", text);
let text = status_text(CL_RUNNING);
assert_eq!("CL_RUNNING", text);
let text = status_text(CL_SUBMITTED);
assert_eq!("CL_SUBMITTED", text);
let text = status_text(CL_QUEUED);
assert_eq!("CL_QUEUED", text);
let text = status_text(CL_QUEUED + 1);
assert_eq!("UNKNOWN_STATUS", text);
}
#[test]
fn test_command_type_text() {
let text = command_type_text(CL_COMMAND_NDRANGE_KERNEL);
assert_eq!("CL_COMMAND_NDRANGE_KERNEL", text);
let text = command_type_text(CL_COMMAND_COPY_IMAGE);
assert_eq!("CL_COMMAND_COPY_IMAGE", text);
let text = command_type_text(CL_COMMAND_READ_BUFFER_RECT);
assert_eq!("CL_COMMAND_READ_BUFFER_RECT", text);
let text = command_type_text(CL_COMMAND_BARRIER);
assert_eq!("CL_COMMAND_BARRIER", text);
let text = command_type_text(CL_COMMAND_SVM_FREE);
assert_eq!("CL_COMMAND_SVM_FREE", text);
let text = command_type_text(CL_COMMAND_SVM_MIGRATE_MEM + 1);
assert_eq!("UNKNOWN_COMMAND_TYPE", text);
}
}