1#![allow(unused_unsafe)]
18#![allow(non_camel_case_types)]
19#![allow(clippy::not_unsafe_ptr_arg_deref)]
20
21pub use opencl_sys::{
22 CL_CONTEXT_DEVICES, CL_CONTEXT_INTEROP_USER_SYNC, CL_CONTEXT_NUM_DEVICES, CL_CONTEXT_PLATFORM,
23 CL_CONTEXT_PROPERTIES, CL_CONTEXT_REFERENCE_COUNT, CL_INVALID_VALUE, CL_SUCCESS, cl_context,
24 cl_context_info, cl_context_properties, cl_device_id, cl_device_type, cl_int, cl_uint,
25};
26
27use super::info_type::InfoType;
28use super::{api_info_size, api_info_value, api_info_vector};
29use libc::{c_char, c_void, intptr_t, size_t};
30use std::mem;
31use std::ptr;
32
33#[allow(unused_unsafe)]
45#[allow(clippy::cast_possible_truncation)]
46#[inline]
47pub fn create_context(
48 devices: &[cl_device_id],
49 properties: *const cl_context_properties,
50 pfn_notify: Option<unsafe extern "C" fn(*const c_char, *const c_void, size_t, *mut c_void)>,
51 user_data: *mut c_void,
52) -> Result<cl_context, cl_int> {
53 let mut status: cl_int = CL_INVALID_VALUE;
54 let context = unsafe {
55 cl_call!(clCreateContext(
56 properties,
57 devices.len() as cl_uint,
58 devices.as_ptr(),
59 pfn_notify,
60 user_data,
61 &raw mut status,
62 ))
63 };
64 if CL_SUCCESS == status {
65 Ok(context)
66 } else {
67 Err(status)
68 }
69}
70
71#[inline]
84pub fn create_context_from_type(
85 device_type: cl_device_type,
86 properties: *const cl_context_properties,
87 pfn_notify: Option<unsafe extern "C" fn(*const c_char, *const c_void, size_t, *mut c_void)>,
88 user_data: *mut c_void,
89) -> Result<cl_context, cl_int> {
90 let mut status: cl_int = CL_INVALID_VALUE;
91 let context = unsafe {
92 cl_call!(clCreateContextFromType(
93 properties,
94 device_type,
95 pfn_notify,
96 user_data,
97 &raw mut status
98 ))
99 };
100 if CL_SUCCESS == status {
101 Ok(context)
102 } else {
103 Err(status)
104 }
105}
106
107#[inline]
118pub unsafe fn retain_context(context: cl_context) -> Result<(), cl_int> {
119 let status: cl_int = cl_call!(clRetainContext(context));
120 if CL_SUCCESS == status {
121 Ok(())
122 } else {
123 Err(status)
124 }
125}
126
127#[inline]
138pub unsafe fn release_context(context: cl_context) -> Result<(), cl_int> {
139 let status: cl_int = cl_call!(clReleaseContext(context));
140 if CL_SUCCESS == status {
141 Ok(())
142 } else {
143 Err(status)
144 }
145}
146
147pub fn get_context_data(
150 context: cl_context,
151 param_name: cl_context_info,
152) -> Result<Vec<u8>, cl_int> {
153 api_info_size!(get_size, clGetContextInfo);
154 let size = get_size(context, param_name)?;
155 api_info_vector!(get_vector, u8, clGetContextInfo);
156 get_vector(context, param_name, size)
157}
158
159pub fn get_context_info(
169 context: cl_context,
170 param_name: cl_context_info,
171) -> Result<InfoType, cl_int> {
172 api_info_size!(get_size, clGetContextInfo);
173
174 match param_name {
175 CL_CONTEXT_REFERENCE_COUNT | CL_CONTEXT_NUM_DEVICES => {
176 api_info_value!(get_value, cl_uint, clGetContextInfo);
177 Ok(InfoType::Uint(get_value(context, param_name)?))
178 }
179
180 CL_CONTEXT_DEVICES | CL_CONTEXT_PROPERTIES => {
181 api_info_vector!(get_vec, intptr_t, clGetContextInfo);
182 let size = get_size(context, param_name)?;
183 Ok(InfoType::VecIntPtr(get_vec(context, param_name, size)?))
184 }
185
186 _ => Ok(InfoType::VecUchar(get_context_data(context, param_name)?)),
187 }
188}
189
190#[cfg(any(feature = "CL_VERSION_3_0", feature = "dynamic"))]
200#[inline]
201pub fn set_context_destructor_callback(
202 context: cl_context,
203 pfn_notify: Option<unsafe extern "C" fn(cl_context, *mut c_void)>,
204 user_data: *mut c_void,
205) -> Result<(), cl_int> {
206 let status: cl_int = unsafe {
207 cl_call!(clSetContextDestructorCallback(
208 context, pfn_notify, user_data
209 ))
210 };
211 if CL_SUCCESS == status {
212 Ok(())
213 } else {
214 Err(status)
215 }
216}
217#[cfg(test)]
220mod tests {
221 use super::*;
222 use crate::device::{CL_DEVICE_TYPE_GPU, get_device_ids};
223 use crate::platform::get_platform_ids;
224
225 #[test]
226 fn test_context() {
227 let platform_ids = get_platform_ids().unwrap();
228
229 let platform_id = platform_ids[0];
231
232 let device_ids = get_device_ids(platform_id, CL_DEVICE_TYPE_GPU).unwrap();
233 assert!(0 < device_ids.len());
234
235 let context = create_context(&device_ids, ptr::null(), None, ptr::null_mut());
236 let context = context.unwrap();
237
238 let value = get_context_info(context, CL_CONTEXT_REFERENCE_COUNT).unwrap();
239 let value = cl_uint::from(value);
240 println!("CL_CONTEXT_REFERENCE_COUNT: {}", value);
241 assert!(0 < value);
242
243 let value = get_context_info(context, CL_CONTEXT_DEVICES).unwrap();
244 let value = Vec::<intptr_t>::from(value);
245 println!("CL_CONTEXT_DEVICES: {}", value.len());
246 println!("CL_CONTEXT_DEVICES: {:?}", value);
247 assert!(0 < value.len());
248
249 let value = get_context_info(context, CL_CONTEXT_PROPERTIES).unwrap();
250 let value = Vec::<intptr_t>::from(value);
251 println!("CL_CONTEXT_PROPERTIES: {}", value.len());
252 println!("CL_CONTEXT_PROPERTIES: {:?}", value);
253 let value = get_context_info(context, CL_CONTEXT_NUM_DEVICES).unwrap();
256 let value = cl_uint::from(value);
257 println!("CL_CONTEXT_NUM_DEVICES: {}", value);
258 assert!(0 < value);
259
260 unsafe { release_context(context).unwrap() };
261 }
262}