Struct Session

Source
pub struct Session { /* private fields */ }
Expand description

Session is the structure that is responsible for Dropping Low-Level OpenCL pointer wrappers in the correct order. Dropping OpenCL pointers in the wrong order can lead to undefined behavior.

Implementations§

Source§

impl Session

Source

pub fn create_with_devices<'a, D>(devices: D, src: &str) -> Output<Session>
where D: Into<VecOrSlice<'a, ClDeviceID>>,

Source

pub fn create(src: &str) -> Output<Session>

Given a string slice of OpenCL source code this function creates a session for all available platforms and devices. A Session consists of:

one or more devices one context (for sharing mem objects between devices) one program (build on each of the devices) one or more queues (each queue belongs to exactly one of the devices)

Source

pub unsafe fn decompose( self, ) -> (Vec<ClDeviceID>, ClContext, ClProgram, Vec<ClCommandQueue>)

Consumes the session returning the parts as individual parts.

§Safety

Moving the components of a Session out of the Session can easily lead to undefined behavior. The Session has a carefully implemented drop that ensures the an Object is dropped before it’s dependencies. If any of the dependencies of an object are ever dropped in the incorrect order or any dependency of an object is dropped and the object is then used the result is undefined behavior.

Source

pub fn devices(&self) -> &[ClDeviceID]

A slice of the ClDeviceIDs of this Session.

Source

pub fn context(&self) -> &ClContext

A reference to the ClContext of this Session.

Source

pub fn program(&self) -> &ClProgram

A reference to the ClProgram of this Session.

Source

pub fn queues(&self) -> &[ClCommandQueue]

A slice of the ClCommandQueues of this Session.

Source

pub unsafe fn create_kernel(&self, kernel_name: &str) -> Output<ClKernel>

Creates a ClKernel from the session’s program.

§Safety

Note: This function may, in fact, be safe. However, creating a kernel with a program object that is in an invalid state can lead to undefined behavior. Using the ClKernel after the session has been released can lead to undefined behavior. Using the ClKernel outside it’s own context/program can lead to undefined behavior.

Examples found in repository?
examples/ll_simple_add/main.rs (line 139)
127fn run_with_session() {
128    let src = include_str!("simple_add.ocl");
129    unsafe {
130        let mut session = SessionBuilder::new().with_program_src(src).build().unwrap();
131
132        let vec_a = vec![1i64, 2, 3];
133        let vec_b = vec![0i64, -1, -2];
134
135        let mut mem_a = session.create_mem(&vec_a[..]).unwrap();
136        let mut mem_b = session.create_mem(&vec_b[..]).unwrap();
137        let mut mem_c: ClMem = session.create_mem::<i64, usize>(vec_a.len()).unwrap();
138
139        let mut simple_add = session.create_kernel("simple_add").unwrap();
140
141        simple_add.set_arg(0, &mut mem_a).unwrap();
142        simple_add.set_arg(1, &mut mem_b).unwrap();
143        simple_add.set_arg(2, &mut mem_c).unwrap();
144        let work: Work = Work::new(vec_a.len());
145
146        let mut vec_c = vec_a.clone();
147
148        let enqueue_event = session
149            .enqueue_kernel(0, &mut simple_add, &work, None)
150            .unwrap();
151        let () = enqueue_event.wait().unwrap();
152        let mut read_event = session
153            .read_buffer(0, &mut mem_c, &mut vec_c[..], None)
154            .unwrap();
155        let read_output = read_event.wait().unwrap();
156        assert_eq!(read_output, None);
157
158        // at this point vec_c *should* be the result of calling simple_add and reading from mem_c;
159        println!("  {}", string_from_slice(&vec_a[..]));
160        println!("+ {}", string_from_slice(&vec_b[..]));
161        println!("= {}", string_from_slice(&vec_c[..]));
162    }
163}
Source

pub unsafe fn create_mem<T: ClNumber, B: BufferCreator<T>>( &self, buffer_creator: B, ) -> Output<ClMem>

Creates a ClMem object in the given context, with the given buffer creator (either a length or some data). This function uses the BufferCreator’s implementation to retrieve the appropriate MemConfig.

§Safety

This function can cause undefined behavior if the OpenCL context object that is passed is not in a valid state (null, released, etc.)

Examples found in repository?
examples/ll_simple_add/main.rs (line 135)
127fn run_with_session() {
128    let src = include_str!("simple_add.ocl");
129    unsafe {
130        let mut session = SessionBuilder::new().with_program_src(src).build().unwrap();
131
132        let vec_a = vec![1i64, 2, 3];
133        let vec_b = vec![0i64, -1, -2];
134
135        let mut mem_a = session.create_mem(&vec_a[..]).unwrap();
136        let mut mem_b = session.create_mem(&vec_b[..]).unwrap();
137        let mut mem_c: ClMem = session.create_mem::<i64, usize>(vec_a.len()).unwrap();
138
139        let mut simple_add = session.create_kernel("simple_add").unwrap();
140
141        simple_add.set_arg(0, &mut mem_a).unwrap();
142        simple_add.set_arg(1, &mut mem_b).unwrap();
143        simple_add.set_arg(2, &mut mem_c).unwrap();
144        let work: Work = Work::new(vec_a.len());
145
146        let mut vec_c = vec_a.clone();
147
148        let enqueue_event = session
149            .enqueue_kernel(0, &mut simple_add, &work, None)
150            .unwrap();
151        let () = enqueue_event.wait().unwrap();
152        let mut read_event = session
153            .read_buffer(0, &mut mem_c, &mut vec_c[..], None)
154            .unwrap();
155        let read_output = read_event.wait().unwrap();
156        assert_eq!(read_output, None);
157
158        // at this point vec_c *should* be the result of calling simple_add and reading from mem_c;
159        println!("  {}", string_from_slice(&vec_a[..]));
160        println!("+ {}", string_from_slice(&vec_b[..]));
161        println!("= {}", string_from_slice(&vec_c[..]));
162    }
163}
Source

pub unsafe fn create_mem_with_config<T: ClNumber, B: BufferCreator<T>>( &self, buffer_creator: B, mem_config: MemConfig, ) -> Output<ClMem>

Creates a ClMem object in the given context, with the given buffer creator (either a length or some data) and a given MemConfig.

§Safety

This function can cause undefined behavior if the OpenCL context object that is passed is not in a valid state (null, released, etc.)

Source

pub unsafe fn write_buffer<'a, T: ClNumber, H: Into<VecOrSlice<'a, T>>>( &mut self, queue_index: usize, mem: &mut ClMem, host_buffer: H, opts: Option<CommandQueueOptions>, ) -> Output<ClEvent>

This function copies data from the host buffer into the device mem buffer. The host buffer must be a mutable slice or a vector to ensure the safety of the read_Buffer operation.

§Safety

This function call is safe only if the ClMem object’s dependencies are still valid, if the ClMem is valid, if the ClCommandQueue’s dependencies are valid, if the ClCommandQueue’s object itself still valid, if the device’s size and type exactly match the host buffer’s size and type, if the waitlist’s events are in a valid state and the list goes on…

Source

pub unsafe fn read_buffer<'a, T: ClNumber, H: Into<MutVecOrSlice<'a, T>>>( &mut self, queue_index: usize, mem: &mut ClMem, host_buffer: H, opts: Option<CommandQueueOptions>, ) -> Output<BufferReadEvent<T>>

This function copies data from a device mem buffer into a host buffer. The host buffer must be a mutable slice or a vector. For the moment the device mem must also be passed as mutable; I don’t trust OpenCL.

§Safety

This function call is safe only if the ClMem object’s dependencies are still valid, if the ClMem is valid, if the ClCommandQueue’s dependencies are valid, if the ClCommandQueue’s object itself still valid, if the device’s size and type exactly match the host buffer’s size and type, if the waitlist’s events are in a valid state and the list goes on…

Examples found in repository?
examples/ll_simple_add/main.rs (line 153)
127fn run_with_session() {
128    let src = include_str!("simple_add.ocl");
129    unsafe {
130        let mut session = SessionBuilder::new().with_program_src(src).build().unwrap();
131
132        let vec_a = vec![1i64, 2, 3];
133        let vec_b = vec![0i64, -1, -2];
134
135        let mut mem_a = session.create_mem(&vec_a[..]).unwrap();
136        let mut mem_b = session.create_mem(&vec_b[..]).unwrap();
137        let mut mem_c: ClMem = session.create_mem::<i64, usize>(vec_a.len()).unwrap();
138
139        let mut simple_add = session.create_kernel("simple_add").unwrap();
140
141        simple_add.set_arg(0, &mut mem_a).unwrap();
142        simple_add.set_arg(1, &mut mem_b).unwrap();
143        simple_add.set_arg(2, &mut mem_c).unwrap();
144        let work: Work = Work::new(vec_a.len());
145
146        let mut vec_c = vec_a.clone();
147
148        let enqueue_event = session
149            .enqueue_kernel(0, &mut simple_add, &work, None)
150            .unwrap();
151        let () = enqueue_event.wait().unwrap();
152        let mut read_event = session
153            .read_buffer(0, &mut mem_c, &mut vec_c[..], None)
154            .unwrap();
155        let read_output = read_event.wait().unwrap();
156        assert_eq!(read_output, None);
157
158        // at this point vec_c *should* be the result of calling simple_add and reading from mem_c;
159        println!("  {}", string_from_slice(&vec_a[..]));
160        println!("+ {}", string_from_slice(&vec_b[..]));
161        println!("= {}", string_from_slice(&vec_c[..]));
162    }
163}
Source

pub unsafe fn enqueue_kernel( &mut self, queue_index: usize, kernel: &mut ClKernel, work: &Work, opts: Option<CommandQueueOptions>, ) -> Output<ClEvent>

This function enqueues a CLKernel into a command queue

§Safety

If the ClKernel is not in a usable state or any of the Kernel’s dependent object has been release, or the kernel belongs to a different session, or the ClKernel’s pointer is a null pointer, then calling this function will cause undefined behavior.

Examples found in repository?
examples/ll_simple_add/main.rs (line 149)
127fn run_with_session() {
128    let src = include_str!("simple_add.ocl");
129    unsafe {
130        let mut session = SessionBuilder::new().with_program_src(src).build().unwrap();
131
132        let vec_a = vec![1i64, 2, 3];
133        let vec_b = vec![0i64, -1, -2];
134
135        let mut mem_a = session.create_mem(&vec_a[..]).unwrap();
136        let mut mem_b = session.create_mem(&vec_b[..]).unwrap();
137        let mut mem_c: ClMem = session.create_mem::<i64, usize>(vec_a.len()).unwrap();
138
139        let mut simple_add = session.create_kernel("simple_add").unwrap();
140
141        simple_add.set_arg(0, &mut mem_a).unwrap();
142        simple_add.set_arg(1, &mut mem_b).unwrap();
143        simple_add.set_arg(2, &mut mem_c).unwrap();
144        let work: Work = Work::new(vec_a.len());
145
146        let mut vec_c = vec_a.clone();
147
148        let enqueue_event = session
149            .enqueue_kernel(0, &mut simple_add, &work, None)
150            .unwrap();
151        let () = enqueue_event.wait().unwrap();
152        let mut read_event = session
153            .read_buffer(0, &mut mem_c, &mut vec_c[..], None)
154            .unwrap();
155        let read_output = read_event.wait().unwrap();
156        assert_eq!(read_output, None);
157
158        // at this point vec_c *should* be the result of calling simple_add and reading from mem_c;
159        println!("  {}", string_from_slice(&vec_a[..]));
160        println!("+ {}", string_from_slice(&vec_b[..]));
161        println!("= {}", string_from_slice(&vec_c[..]));
162    }
163}
Source

pub fn execute_sync_kernel_operation( &mut self, queue_index: usize, kernel_op: KernelOperation, ) -> Output<()>

Trait Implementations§

Source§

impl Debug for Session

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for Session

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Send for Session

Session can be safely sent between threads.

§Safety

All the contained OpenCL objects Session are Send so Session is Send. However, The low level Session has ZERO Synchronization for mutable objects Program and CommandQueue. Therefore the low level Session is not Sync. If a Sync Session is required, the Session of opencl_core is Sync by synchronizing mutations of it’s objects via RwLocks.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.