1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! An `OpenCL` command queue.

use std;
use std::ops::{Deref, DerefMut};
use crate::core::{self, Result as OclCoreResult, CommandQueue as CommandQueueCore, CommandQueueInfo,
    CommandQueueInfoResult, OpenclVersion, CommandQueueProperties, ClWaitListPtr, ClContextPtr};
use crate::error::{Error as OclError, Result as OclResult};
use crate::standard::{Context, Device, Event};

/// A command queue which manages all actions taken on kernels, buffers, and
/// images.
///
///
//
// * TODO: Consider implementing a constructor which accepts a DeviceIdCore and
// creates a context and queue from it.
//
//
#[derive(Clone, Debug)]
pub struct Queue {
    obj_core: CommandQueueCore,
    device_version: OpenclVersion,
}

impl Queue {
    /// Returns a new Queue on the device specified by `device`.
    pub fn new(context: &Context, device: Device, properties: Option<CommandQueueProperties>)
            -> OclResult<Queue> {
        let obj_core = core::create_command_queue(context, &device, properties)?;
        let device_version = device.version()?;

        Ok(Queue {
            obj_core,
            device_version,
        })
    }

    /// Issues all previously queued OpenCL commands to the device.
    pub fn flush(&self) -> OclResult<()> {
        core::flush(&self.obj_core).map_err(OclError::from)
    }

    /// Blocks until all commands in this queue have completed before returning.
    pub fn finish(&self) -> OclResult<()> {
        core::finish(&self.obj_core).map_err(OclError::from)
    }

    /// Enqueues a marker command which waits for either a list of events to
    /// complete, or all previously enqueued commands to complete.
    pub fn enqueue_marker<Ewl>(&self, ewait: Option<Ewl>) -> OclResult<Event>
            where Ewl: ClWaitListPtr
    {
        let mut marker_event = Event::empty();
        core::enqueue_marker_with_wait_list(&self.obj_core, ewait, Some(&mut marker_event),
                Some(&self.device_version)).map(|_| marker_event)
            .map_err(OclError::from)
    }

    /// Returns a reference to the core pointer wrapper, usable by functions in
    /// the `core` module.
    #[inline]
    pub fn as_core(&self) -> &CommandQueueCore {
        &self.obj_core
    }

    /// Returns a copy of the Context associated with this queue.
    pub fn context(&self) -> Context {
        self.obj_core.context().map(Context::from).unwrap()
    }

    /// Returns the `OpenCL` device associated with this queue.
    pub fn device(&self) -> Device {
        self.obj_core.device().map(Device::from).unwrap()
    }

    /// Returns the cached device version.
    pub fn device_version(&self) -> OpenclVersion {
        self.device_version
    }

    /// Returns info about this queue.
    pub fn info(&self, info_kind: CommandQueueInfo) -> OclCoreResult<CommandQueueInfoResult> {
        core::get_command_queue_info(&self.obj_core, info_kind)
    }

    fn fmt_info(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        f.debug_struct("Queue")
            .field("Context", &self.info(CommandQueueInfo::Context))
            .field("Device", &self.info(CommandQueueInfo::Device))
            .field("ReferenceCount", &self.info(CommandQueueInfo::ReferenceCount))
            .field("Properties", &self.info(CommandQueueInfo::Properties))
            .finish()
    }
}

impl std::fmt::Display for Queue {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.fmt_info(f)
    }
}

impl AsRef<Queue> for Queue {
    fn as_ref(&self) -> &Queue {
        self
    }
}

impl AsRef<CommandQueueCore> for Queue {
    fn as_ref(&self) -> &CommandQueueCore {
        &self.obj_core
    }
}

impl Deref for Queue {
    type Target = CommandQueueCore;

    fn deref(&self) -> &CommandQueueCore {
        &self.obj_core
    }
}

impl DerefMut for Queue {
    fn deref_mut(&mut self) -> &mut CommandQueueCore {
        &mut self.obj_core
    }
}

unsafe impl<'a> ClContextPtr for &'a Queue {
    fn as_ptr(&self) -> crate::ffi::cl_context {
        self.context_ptr().expect("<&Queue as ClContextPtr>::as_ptr: \
            Unable to obtain a context pointer.")
    }
}