open_cl_low_level/
cl_helpers.rs

1// use std::marker::PhantomData;
2// use std::fmt;
3
4pub use crate::{build_output, utils, ClPointer, Output, StatusCodeError};
5
6use crate::ffi::cl_int;
7
8use libc::{c_void, size_t};
9
10type ObjFunc<Obj, Flag, Obj2> = unsafe extern "C" fn(Obj, Flag, u32, *mut Obj2, *mut u32) -> cl_int;
11
12pub unsafe fn cl_get_object_count<Obj, Flag, Obj2>(
13    cl_object: Obj,
14    flag: Flag,
15    func: ObjFunc<Obj, Flag, Obj2>,
16) -> Output<u32>
17where
18    Obj: Copy,
19    Flag: Copy,
20    Obj2: Copy,
21{
22    let mut output_size: u32 = 0;
23
24    let err_code = func(
25        cl_object,
26        flag,
27        0 as u32,
28        std::ptr::null_mut(),
29        &mut output_size as *mut u32,
30    );
31
32    build_output(output_size, err_code)
33}
34
35pub unsafe fn cl_get_object<Obj: Copy, Flag: Copy, Obj2: Copy>(
36    cl_object: Obj,
37    flag: Flag,
38    func: ObjFunc<Obj, Flag, Obj2>,
39) -> Output<ClPointer<Obj2>> {
40    let output_count: u32 = cl_get_object_count(cl_object, flag, func)?;
41
42    if output_count == 0 {
43        return Ok(ClPointer::new_empty());
44    }
45
46    let output_size = output_count * (std::mem::size_of::<Obj2>() as u32);
47    let mut bytes = utils::vec_filled_with(0u8, output_size as usize);
48    let output = bytes.as_mut_ptr() as *mut _ as *mut Obj2;
49
50    let err_code = func(cl_object, flag, output_count, output, std::ptr::null_mut());
51
52    build_output((), err_code)?;
53    // everything worked, but we dont want the `bytes` vec to be dropped so we forget it.
54    std::mem::forget(bytes);
55    Ok(ClPointer::new(output_count as usize, output))
56}
57
58type InfoFunc5<Obj, Flag> =
59    unsafe extern "C" fn(Obj, Flag, size_t, *mut c_void, *mut size_t) -> cl_int;
60
61pub unsafe fn cl_get_info_byte_count5<Obj: Copy, Flag: Copy>(
62    cl_object: Obj,
63    flag: Flag,
64    func: InfoFunc5<Obj, Flag>,
65) -> Output<size_t> {
66    let mut output_size = 0 as size_t;
67
68    let err_code = func(
69        cl_object,
70        flag,
71        0 as size_t,
72        std::ptr::null_mut(),
73        &mut output_size as *mut size_t,
74    );
75
76    build_output(output_size, err_code)
77}
78
79pub unsafe fn cl_get_info5<Obj: Copy, Flag: Copy, Ret: Copy>(
80    cl_object: Obj,
81    flag: Flag,
82    func: InfoFunc5<Obj, Flag>,
83) -> Output<ClPointer<Ret>> {
84    let num_bytes: size_t = cl_get_info_byte_count5(cl_object, flag, func)?;
85
86    if num_bytes == 0 {
87        return Ok(ClPointer::new_empty());
88    }
89
90    let mut bytes = utils::vec_filled_with(0u8, num_bytes as usize);
91
92    let output = bytes.as_mut_ptr() as *mut _ as *mut libc::c_void;
93
94    let err_code = func(cl_object, flag, num_bytes, output, std::ptr::null_mut());
95
96    build_output((), err_code)?;
97    // Everything above worked so we don't want the `bytes` vec to be freed
98    // Therefore we forget it.
99    std::mem::forget(bytes);
100
101    let output_count = num_bytes / std::mem::size_of::<Ret>();
102    Ok(ClPointer::new(output_count, output as *mut Ret))
103}
104
105type InfoFunc6<Obj, Obj2, Flag> =
106    unsafe extern "C" fn(Obj, Obj2, Flag, size_t, *mut c_void, *mut size_t) -> cl_int;
107
108pub unsafe fn cl_get_info_byte_count6<Obj1: Copy, Obj2: Copy, Flag: Copy>(
109    cl_obj1: Obj1,
110    cl_obj2: Obj2,
111    flag: Flag,
112    func: InfoFunc6<Obj1, Obj2, Flag>,
113) -> Output<size_t> {
114    let mut output_size = 0 as size_t;
115
116    let err_code = func(
117        cl_obj1,
118        cl_obj2,
119        flag,
120        0 as size_t,
121        std::ptr::null_mut(),
122        &mut output_size as *mut size_t,
123    );
124
125    build_output(output_size, err_code)
126}
127
128pub unsafe fn cl_get_info6<Obj1: Copy, Obj2: Copy, Flag: Copy, Ret: Copy>(
129    cl_obj1: Obj1,
130    cl_obj2: Obj2,
131    flag: Flag,
132    func: InfoFunc6<Obj1, Obj2, Flag>,
133) -> Output<ClPointer<Ret>> {
134    let byte_count: size_t = cl_get_info_byte_count6(cl_obj1, cl_obj2, flag, func)?;
135
136    if byte_count == 0 {
137        return Ok(ClPointer::new_empty());
138    }
139
140    let mut bytes = utils::vec_filled_with(0u8, byte_count as usize);
141    let output = bytes.as_mut_ptr() as *mut _ as *mut libc::c_void;
142
143    let err_code = func(
144        cl_obj1,
145        cl_obj2,
146        flag,
147        byte_count,
148        output,
149        std::ptr::null_mut(),
150    );
151
152    build_output((), err_code)?;
153    // Everything above worked so we don't want the `bytes` vec to be freed
154    // Therefore we forget it.
155    std::mem::forget(bytes);
156    let output_count = byte_count / std::mem::size_of::<Ret>();
157    Ok(ClPointer::new(output_count, output as *mut Ret))
158}