ocl/standard/
queue.rs

1//! An `OpenCL` command queue.
2
3use crate::core::{
4    self, ClContextPtr, ClWaitListPtr, CommandQueue as CommandQueueCore, CommandQueueInfo,
5    CommandQueueInfoResult, CommandQueueProperties, OpenclVersion, Result as OclCoreResult,
6};
7use crate::error::{Error as OclError, Result as OclResult};
8use crate::standard::{Context, Device, Event};
9use std;
10use std::ops::{Deref, DerefMut};
11
12/// A command queue which manages all actions taken on kernels, buffers, and
13/// images.
14///
15///
16//
17// * TODO: Consider implementing a constructor which accepts a DeviceIdCore and
18// creates a context and queue from it.
19//
20//
21#[derive(Clone, Debug)]
22pub struct Queue {
23    obj_core: CommandQueueCore,
24    device_version: OpenclVersion,
25}
26
27impl Queue {
28    /// Returns a new Queue on the device specified by `device`.
29    pub fn new(
30        context: &Context,
31        device: Device,
32        properties: Option<CommandQueueProperties>,
33    ) -> OclResult<Queue> {
34        let obj_core = core::create_command_queue(context, &device, properties)?;
35        let device_version = device.version()?;
36
37        Ok(Queue {
38            obj_core,
39            device_version,
40        })
41    }
42
43    /// Issues all previously queued OpenCL commands to the device.
44    pub fn flush(&self) -> OclResult<()> {
45        core::flush(&self.obj_core).map_err(OclError::from)
46    }
47
48    /// Blocks until all commands in this queue have completed before returning.
49    pub fn finish(&self) -> OclResult<()> {
50        core::finish(&self.obj_core).map_err(OclError::from)
51    }
52
53    /// Enqueues a marker command which waits for either a list of events to
54    /// complete, or all previously enqueued commands to complete.
55    pub fn enqueue_marker<Ewl>(&self, ewait: Option<Ewl>) -> OclResult<Event>
56    where
57        Ewl: ClWaitListPtr,
58    {
59        let mut marker_event = Event::empty();
60        core::enqueue_marker_with_wait_list(
61            &self.obj_core,
62            ewait,
63            Some(&mut marker_event),
64            Some(&self.device_version),
65        )
66        .map(|_| marker_event)
67        .map_err(OclError::from)
68    }
69
70    /// Returns a reference to the core pointer wrapper, usable by functions in
71    /// the `core` module.
72    #[inline]
73    pub fn as_core(&self) -> &CommandQueueCore {
74        &self.obj_core
75    }
76
77    /// Returns a copy of the Context associated with this queue.
78    pub fn context(&self) -> Context {
79        self.obj_core.context().map(Context::from).unwrap()
80    }
81
82    /// Returns the `OpenCL` device associated with this queue.
83    pub fn device(&self) -> Device {
84        self.obj_core.device().map(Device::from).unwrap()
85    }
86
87    /// Returns the cached device version.
88    pub fn device_version(&self) -> OpenclVersion {
89        self.device_version
90    }
91
92    /// Returns info about this queue.
93    pub fn info(&self, info_kind: CommandQueueInfo) -> OclCoreResult<CommandQueueInfoResult> {
94        core::get_command_queue_info(&self.obj_core, info_kind)
95    }
96
97    fn fmt_info(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
98        f.debug_struct("Queue")
99            .field("Context", &self.info(CommandQueueInfo::Context))
100            .field("Device", &self.info(CommandQueueInfo::Device))
101            .field(
102                "ReferenceCount",
103                &self.info(CommandQueueInfo::ReferenceCount),
104            )
105            .field("Properties", &self.info(CommandQueueInfo::Properties))
106            .finish()
107    }
108}
109
110impl std::fmt::Display for Queue {
111    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
112        self.fmt_info(f)
113    }
114}
115
116impl AsRef<Queue> for Queue {
117    fn as_ref(&self) -> &Queue {
118        self
119    }
120}
121
122impl AsRef<CommandQueueCore> for Queue {
123    fn as_ref(&self) -> &CommandQueueCore {
124        &self.obj_core
125    }
126}
127
128impl Deref for Queue {
129    type Target = CommandQueueCore;
130
131    fn deref(&self) -> &CommandQueueCore {
132        &self.obj_core
133    }
134}
135
136impl DerefMut for Queue {
137    fn deref_mut(&mut self) -> &mut CommandQueueCore {
138        &mut self.obj_core
139    }
140}
141
142unsafe impl<'a> ClContextPtr for &'a Queue {
143    fn as_ptr(&self) -> crate::ffi::cl_context {
144        self.context_ptr().expect(
145            "<&Queue as ClContextPtr>::as_ptr: \
146            Unable to obtain a context pointer.",
147        )
148    }
149}