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
impl Session
pub fn create_with_devices<'a, D>(devices: D, src: &str) -> Output<Session>
Sourcepub fn create(src: &str) -> Output<Session>
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)
Sourcepub unsafe fn decompose(
self,
) -> (Vec<ClDeviceID>, ClContext, ClProgram, Vec<ClCommandQueue>)
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.
Sourcepub fn devices(&self) -> &[ClDeviceID] ⓘ
pub fn devices(&self) -> &[ClDeviceID] ⓘ
A slice of the ClDeviceIDs of this Session.
Sourcepub fn queues(&self) -> &[ClCommandQueue] ⓘ
pub fn queues(&self) -> &[ClCommandQueue] ⓘ
A slice of the ClCommandQueues of this Session.
Sourcepub unsafe fn create_kernel(&self, kernel_name: &str) -> Output<ClKernel>
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?
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}Sourcepub unsafe fn create_mem<T: ClNumber, B: BufferCreator<T>>(
&self,
buffer_creator: B,
) -> Output<ClMem>
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?
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}Sourcepub unsafe fn create_mem_with_config<T: ClNumber, B: BufferCreator<T>>(
&self,
buffer_creator: B,
mem_config: MemConfig,
) -> Output<ClMem>
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.)
Sourcepub 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>
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…
Sourcepub 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>>
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?
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}Sourcepub unsafe fn enqueue_kernel(
&mut self,
queue_index: usize,
kernel: &mut ClKernel,
work: &Work,
opts: Option<CommandQueueOptions>,
) -> Output<ClEvent>
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?
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}pub fn execute_sync_kernel_operation( &mut self, queue_index: usize, kernel_op: KernelOperation, ) -> Output<()>
Trait Implementations§
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.