1use crate::objects::bitfields::CommandQueueProperties;
22use crate::objects::enums::{ParamValue, Size};
23use crate::objects::functions::status_update;
24use crate::objects::structs::{CommandQueueInfo, StatusCode};
25use crate::objects::traits::GetSetGo;
26use crate::objects::types::{APIResult, ContextPtr, DevicePtr, LongProperties, QueuePtr};
27use crate::{gen_param_value, size_getter};
28use libc::c_void;
29use opencl_heads::ffi;
30use opencl_heads::ffi::clGetCommandQueueInfo;
31use opencl_heads::types::*;
32use std::ptr;
33
34pub fn create_command_queue(
36 context: &ContextPtr,
37 device: &DevicePtr,
38 properties: &CommandQueueProperties,
39) -> APIResult<QueuePtr> {
40 let fn_name = "clCreateCommandQueue";
41 let mut status_code: cl_int = StatusCode::INVALID_COMMAND_QUEUE;
42 let queue_ptr = unsafe {
43 ffi::clCreateCommandQueue(
44 context.unwrap(),
45 device.unwrap(),
46 properties.get(),
47 &mut status_code,
48 )
49 };
50 status_update(
51 status_code,
52 fn_name,
53 QueuePtr::from_ptr(queue_ptr, fn_name)?,
54 )
55}
56
57pub fn create_command_queue_with_properties(
58 context: &ContextPtr,
59 device: &DevicePtr,
60 properties: &LongProperties,
61) -> APIResult<QueuePtr> {
62 let fn_name = "clCreateCommandQueueWithProperties";
63 let mut status_code: cl_int = StatusCode::INVALID_COMMAND_QUEUE;
64 let properties = match properties {
65 Some(x) => x.as_ptr(),
66 None => ptr::null(),
67 };
68 let queue_ptr = unsafe {
69 ffi::clCreateCommandQueueWithProperties(
70 context.unwrap(),
71 device.unwrap(),
72 properties,
73 &mut status_code,
74 )
75 };
76 status_update(
77 status_code,
78 fn_name,
79 QueuePtr::from_ptr(queue_ptr, fn_name)?,
80 )
81}
82
83pub fn set_default_device_command_queue(
84 context: &ContextPtr,
85 device: &DevicePtr,
86 command_queue: &QueuePtr,
87) -> APIResult<()> {
88 let status_code = unsafe {
89 ffi::clSetDefaultDeviceCommandQueue(
90 context.unwrap(),
91 device.unwrap(),
92 command_queue.unwrap(),
93 )
94 };
95 status_update(status_code, "clSetDefaultDeviceCommandQueue", ())
96}
97
98pub fn retain_command_queue(command_queue: &QueuePtr) -> APIResult<()> {
99 let status_code = unsafe { ffi::clRetainCommandQueue(command_queue.unwrap()) };
100 status_update(status_code, "clRetainCommandQueue", ())
101}
102
103pub fn release_command_queue(command_queue: QueuePtr) -> APIResult<()> {
104 let status_code = unsafe { ffi::clReleaseCommandQueue(command_queue.unwrap()) };
105 status_update(status_code, "clReleaseCommandQueue", ())
106}
107
108pub fn get_command_queue_info(
109 command_queue: &QueuePtr,
110 param_name: cl_command_queue_info,
111) -> APIResult<ParamValue> {
112 let command_queue = command_queue.unwrap();
113 size_getter!(get_command_queue_info_size, clGetCommandQueueInfo);
114 match param_name {
115 CommandQueueInfo::CONTEXT | CommandQueueInfo::DEVICE | CommandQueueInfo::DEVICE_DEFAULT => {
116 let param_value =
117 gen_param_value!(clGetCommandQueueInfo, isize, command_queue, param_name);
118 Ok(ParamValue::CPtr(param_value))
119 }
120 CommandQueueInfo::REFERENCE_COUNT | CommandQueueInfo::SIZE => {
121 let param_value =
122 gen_param_value!(clGetCommandQueueInfo, u32, command_queue, param_name);
123 Ok(ParamValue::UInt(param_value))
124 }
125 CommandQueueInfo::PROPERTIES => {
126 let param_value =
127 gen_param_value!(clGetCommandQueueInfo, u64, command_queue, param_name);
128 Ok(ParamValue::ULong(param_value))
129 }
130 CommandQueueInfo::PROPERTIES_ARRAY => {
132 let size = get_command_queue_info_size(command_queue, param_name)?;
133 let param_value =
134 gen_param_value!(clGetCommandQueueInfo, u64, command_queue, param_name, size);
135 Ok(ParamValue::ArrULong(param_value))
136 }
137 _ => status_update(40404, "clGetContextInfo", ParamValue::default()),
138 }
139}
140
141#[cfg(feature = "depr_1_0")]
142pub fn set_command_queue_property(
143 command_queue: &QueuePtr,
144 properties: &CommandQueueProperties,
145 enable: cl_bool,
146) -> APIResult<()> {
147 let status_code = unsafe {
148 ffi::clSetCommandQueueProperty(command_queue.unwrap(), properties, enable, ptr::null_mut())
149 };
150 status_update(status_code, "clSetCommandQueueProperty", ())
151}
152
153pub fn flush(command_queue: &QueuePtr) -> APIResult<()> {
154 let status_code = unsafe { ffi::clFlush(command_queue.unwrap()) };
155 status_update(status_code, "clFlush", ())
156}
157
158pub fn finish(command_queue: &QueuePtr) -> APIResult<()> {
159 let status_code = unsafe { ffi::clFinish(command_queue.unwrap()) };
160 status_update(status_code, "clFinish", ())
161}
162
163#[cfg(test)]
173mod tests {
174 use super::*;
175 use crate::api::context::{create_context, release_context};
176 use crate::api::device::get_device_ids;
177 use crate::api::platform::get_platform_ids;
178 use crate::objects::bitfields::{CommandQueueProperties, DeviceType};
179 use crate::objects::property::{ContextProperties, QueueProperties};
180 use crate::objects::structs::{CommandQueueInfo};
181 use crate::objects::traits::GetSetGo;
182 use crate::objects::types::{DevicePtr, PlatformPtr, WrapMutPtr};
183
184 #[test]
185 fn test_command_queue() {
186 let platform_ids = get_platform_ids().unwrap();
187
188 let platform_id = PlatformPtr::from_ptr(platform_ids[0], "test_fn").unwrap();
192
193 let device_ids = get_device_ids(
194 &platform_id,
195 DeviceType::new(DeviceType::DEFAULT + DeviceType::CPU + DeviceType::GPU).unwrap(),
196 )
197 .unwrap();
198 assert!(0 < device_ids.len());
199
200 let device_id = DevicePtr::from_ptr(device_ids[0], "test_fn").unwrap();
203
204 let properties = ContextProperties.gen(Some(&platform_id), None);
205 let context = create_context(&properties, device_ids, None, WrapMutPtr::null());
208 let context = context.unwrap();
209
210 let properties =
212 CommandQueueProperties::new(CommandQueueProperties::PROFILING_ENABLE).unwrap();
213 let queue = create_command_queue(&context, &device_id, &properties).unwrap();
214
215 release_command_queue(queue).unwrap();
216
217 let properties = QueueProperties.gen(
222 Some(CommandQueueProperties::new(CommandQueueProperties::PROFILING_ENABLE).unwrap()),
223 None,
224 );
225 eprintln!("{:?}", properties);
226 let queue = create_command_queue_with_properties(&context, &device_id, &None).unwrap();
227
228 release_command_queue(queue).unwrap();
229
230 release_context(context).unwrap();
231 }
232
233 #[test]
234 fn test_get_command_queue_info() {
235 let platform_ids = get_platform_ids().unwrap();
236
237 let platform_id = PlatformPtr::from_ptr(platform_ids[0], "test_fn").unwrap();
241
242 let device_ids =
243 get_device_ids(&platform_id, DeviceType::new(DeviceType::DEFAULT).unwrap()).unwrap();
244 assert!(0 < device_ids.len());
245
246 let device_id = DevicePtr::from_ptr(device_ids[0], "test_fn").unwrap();
248
249 let properties = ContextProperties.gen(Some(&platform_id), Some(false));
250 let context = create_context(&properties, device_ids, None, WrapMutPtr::null());
255 let context = context.unwrap();
256
257 let properties =
259 CommandQueueProperties::new(CommandQueueProperties::PROFILING_ENABLE).unwrap();
260 let queue = create_command_queue(&context, &device_id, &properties).unwrap();
261 let command_info = get_command_queue_info(&queue, CommandQueueInfo::PROPERTIES).unwrap();
263 assert_eq!(properties.get(), command_info.unwrap_ulong().unwrap());
264
265 release_command_queue(queue).unwrap();
266
267 let properties = QueueProperties.gen(
272 Some(
273 CommandQueueProperties::new(
274 CommandQueueProperties::PROFILING_ENABLE
275 )
277 .unwrap(),
278 ),
279 None,
280 );
282 eprintln!("{:?}", properties);
283 let queue =
284 create_command_queue_with_properties(&context, &device_id, &properties).unwrap();
285
286 let command_info = get_command_queue_info(&queue, CommandQueueInfo::PROPERTIES).unwrap();
287 assert_eq!(properties.unwrap()[1], command_info.unwrap_ulong().unwrap());
288
289 release_command_queue(queue).unwrap();
290
291 release_context(context).unwrap();
292 }
293}