1use super::defines::AfError;
2use super::error::HANDLE_ERROR;
3use super::util::{dim_t, free_host, void_ptr};
4
5use libc::{c_char, c_int, size_t};
6use std::borrow::Cow;
7use std::ffi::{CStr, CString};
8
9extern "C" {
10 fn af_get_version(major: *mut c_int, minor: *mut c_int, patch: *mut c_int) -> c_int;
11 fn af_get_revision() -> *const c_char;
12 fn af_info() -> c_int;
13 fn af_info_string(str: *mut *mut c_char, verbose: bool) -> c_int;
14 fn af_device_info(
15 d_name: *mut c_char,
16 d_platform: *mut c_char,
17 d_toolkit: *mut c_char,
18 d_compute: *mut c_char,
19 ) -> c_int;
20 fn af_init() -> c_int;
21 fn af_get_device_count(nDevices: *mut c_int) -> c_int;
22 fn af_get_dbl_support(available: *mut c_int, device: c_int) -> c_int;
23 fn af_set_device(device: c_int) -> c_int;
24 fn af_get_device(device: *mut c_int) -> c_int;
25 fn af_device_mem_info(
26 alloc_bytes: *mut size_t,
27 alloc_buffers: *mut size_t,
28 lock_bytes: *mut size_t,
29 lock_buffers: *mut size_t,
30 ) -> c_int;
31 fn af_print_mem_info(msg: *const c_char, device_id: c_int) -> c_int;
32 fn af_set_mem_step_size(step_bytes: size_t) -> c_int;
33 fn af_get_mem_step_size(step_bytes: *mut size_t) -> c_int;
34 fn af_device_gc() -> c_int;
35 fn af_sync(device: c_int) -> c_int;
36
37 fn af_alloc_pinned(non_pagable_ptr: *mut void_ptr, bytes: dim_t) -> c_int;
38 fn af_free_pinned(non_pagable_ptr: void_ptr) -> c_int;
39 fn af_get_half_support(available: *mut c_int, device: c_int) -> c_int;
40}
41
42pub fn get_version() -> (i32, i32, i32) {
47 unsafe {
48 let mut maj: i32 = 0;
49 let mut min: i32 = 0;
50 let mut pat: i32 = 0;
51 let err_val = af_get_version(
52 &mut maj as *mut c_int,
53 &mut min as *mut c_int,
54 &mut pat as *mut c_int,
55 );
56 HANDLE_ERROR(AfError::from(err_val));
57 (maj, min, pat)
58 }
59}
60
61pub fn get_revision() -> Cow<'static, str> {
66 unsafe { CStr::from_ptr(af_get_revision()).to_string_lossy() }
67}
68
69pub fn info() {
81 unsafe {
82 let err_val = af_info();
83 HANDLE_ERROR(AfError::from(err_val));
84 }
85}
86
87pub fn info_string(verbose: bool) -> String {
99 let result: String;
100 unsafe {
101 let mut tmp: *mut c_char = ::std::ptr::null_mut();
102 let err_val = af_info_string(&mut tmp, verbose);
103 HANDLE_ERROR(AfError::from(err_val));
104 result = CStr::from_ptr(tmp).to_string_lossy().into_owned();
105 free_host(tmp);
106 }
107 result
108}
109
110pub fn device_info() -> (String, String, String, String) {
115 let mut name = [0 as c_char; 64];
116 let mut platform = [0 as c_char; 10];
117 let mut toolkit = [0 as c_char; 64];
118 let mut compute = [0 as c_char; 10];
119 unsafe {
120 let err_val = af_device_info(
121 &mut name[0],
122 &mut platform[0],
123 &mut toolkit[0],
124 &mut compute[0],
125 );
126 HANDLE_ERROR(AfError::from(err_val));
127 (
128 CStr::from_ptr(name.as_mut_ptr())
129 .to_string_lossy()
130 .into_owned(),
131 CStr::from_ptr(platform.as_mut_ptr())
132 .to_string_lossy()
133 .into_owned(),
134 CStr::from_ptr(toolkit.as_mut_ptr())
135 .to_string_lossy()
136 .into_owned(),
137 CStr::from_ptr(compute.as_mut_ptr())
138 .to_string_lossy()
139 .into_owned(),
140 )
141 }
142}
143
144pub fn init() {
149 unsafe {
150 let err_val = af_init();
151 HANDLE_ERROR(AfError::from(err_val));
152 }
153}
154
155pub fn device_count() -> i32 {
157 unsafe {
158 let mut temp: i32 = 0;
159 let err_val = af_get_device_count(&mut temp as *mut c_int);
160 HANDLE_ERROR(AfError::from(err_val));
161 temp
162 }
163}
164
165pub fn is_double_available(device: i32) -> bool {
175 unsafe {
176 let mut temp: i32 = 0;
177 let err_val = af_get_dbl_support(&mut temp as *mut c_int, device as c_int);
178 HANDLE_ERROR(AfError::from(err_val));
179 temp > 0
180 }
181}
182
183pub fn set_device(device: i32) {
189 unsafe {
190 let err_val = af_set_device(device as c_int);
191 HANDLE_ERROR(AfError::from(err_val));
192 }
193}
194
195pub fn get_device() -> i32 {
197 unsafe {
198 let mut temp: i32 = 0;
199 let err_val = af_get_device(&mut temp as *mut c_int);
200 HANDLE_ERROR(AfError::from(err_val));
201 temp
202 }
203}
204
205pub fn device_mem_info() -> (usize, usize, usize, usize) {
220 unsafe {
221 let mut o0: usize = 0;
222 let mut o1: usize = 0;
223 let mut o2: usize = 0;
224 let mut o3: usize = 0;
225 let err_val = af_device_mem_info(
226 &mut o0 as *mut size_t,
227 &mut o1 as *mut size_t,
228 &mut o2 as *mut size_t,
229 &mut o3 as *mut size_t,
230 );
231 HANDLE_ERROR(AfError::from(err_val));
232 (o0, o1, o2, o3)
233 }
234}
235
236pub fn print_mem_info(msg: String, device: i32) {
249 unsafe {
250 let cmsg = CString::new(msg.as_bytes());
251 match cmsg {
252 Ok(v) => {
253 let err_val = af_print_mem_info(
254 v.to_bytes_with_nul().as_ptr() as *const c_char,
255 device as c_int,
256 );
257 HANDLE_ERROR(AfError::from(err_val));
258 }
259 Err(_) => HANDLE_ERROR(AfError::ERR_INTERNAL),
260 }
261 }
262}
263
264pub fn set_mem_step_size(step_bytes: usize) {
274 unsafe {
275 let err_val = af_set_mem_step_size(step_bytes as size_t);
276 HANDLE_ERROR(AfError::from(err_val));
277 }
278}
279
280pub fn get_mem_step_size() -> usize {
290 unsafe {
291 let mut temp: usize = 0;
292 let err_val = af_get_mem_step_size(&mut temp as *mut size_t);
293 HANDLE_ERROR(AfError::from(err_val));
294 temp
295 }
296}
297
298pub fn device_gc() {
300 unsafe {
301 let err_val = af_device_gc();
302 HANDLE_ERROR(AfError::from(err_val));
303 }
304}
305
306pub fn sync(device: i32) {
316 unsafe {
317 let err_val = af_sync(device as c_int);
318 HANDLE_ERROR(AfError::from(err_val));
319 }
320}
321
322pub unsafe fn alloc_pinned(bytes: usize) -> void_ptr {
324 let mut out: void_ptr = std::ptr::null_mut();
325 let err_val = af_alloc_pinned(&mut out as *mut void_ptr, bytes as dim_t);
326 HANDLE_ERROR(AfError::from(err_val));
327 out
328}
329
330pub unsafe fn free_pinned(ptr: void_ptr) {
332 let err_val = af_free_pinned(ptr);
333 HANDLE_ERROR(AfError::from(err_val));
334}
335
336pub fn is_half_available(device: i32) -> bool {
346 unsafe {
347 let mut temp: i32 = 0;
348 let err_val = af_get_half_support(&mut temp as *mut c_int, device as c_int);
349 HANDLE_ERROR(AfError::from(err_val));
350 temp > 0
351 }
352}