Skip to content

Commit 237f3cd

Browse files
committed
Updated wrapper to be compliant with ArrayFire 3.2.0
Fixes #31 This change includes the following modifications: * Update ArrayFire version to 3.2.0 in Cargo file * Update for ArrayFire submodule * Refactor of enum AfBackend to Backend * Added following new functions: - load_image_native - save_image_native - homography - Window::draw_plot3 - Window::draw_surface
1 parent 3cfda5a commit 237f3cd

File tree

11 files changed

+327
-88
lines changed

11 files changed

+327
-88
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "arrayfire"
33
description = "ArrayFire is a high performance software library for parallel computing with an easy-to-use API. Its array based function set makes parallel programming simple. ArrayFire's multiple backends (CUDA, OpenCL and native CPU) make it platform independent and highly portable. A few lines of code in ArrayFire can replace dozens of lines of parallel computing code, saving you valuable time and lowering development costs. This crate provides Rust bindings for ArrayFire library."
4-
version = "3.1.3"
4+
version = "3.2.0"
55
documentation = "http://arrayfire.github.io/arrayfire-rust/arrayfire/index.html"
66
homepage = "https://github.com/arrayfire/arrayfire"
77
repository = "https://github.com/arrayfire/arrayfire-rust"

arrayfire

Submodule arrayfire updated 188 files

examples/unified.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,29 @@ fn main() {
2424
println!("There are {:?} available backends", get_backend_count().unwrap());
2525
let available = get_available_backends().unwrap();
2626

27-
if available.contains(&AfBackend::AF_BACKEND_CPU){
27+
if available.contains(&Backend::AF_BACKEND_CPU){
2828
println!("Evaluating CPU Backend...");
29-
let err = set_backend(AfBackend::AF_BACKEND_CPU);
29+
let err = set_backend(Backend::AF_BACKEND_CPU);
3030
println!("There are {} CPU compute devices", device_count().unwrap());
3131
match err {
3232
Ok(_) => test_backend(),
3333
Err(e) => println!("CPU backend error: {}", e),
3434
};
3535
}
3636

37-
if available.contains(&AfBackend::AF_BACKEND_CUDA){
37+
if available.contains(&Backend::AF_BACKEND_CUDA){
3838
println!("Evaluating CUDA Backend...");
39-
let err = set_backend(AfBackend::AF_BACKEND_CUDA);
39+
let err = set_backend(Backend::AF_BACKEND_CUDA);
4040
println!("There are {} CUDA compute devices", device_count().unwrap());
4141
match err {
4242
Ok(_) => test_backend(),
4343
Err(e) => println!("CUDA backend error: {}", e),
4444
};
4545
}
4646

47-
if available.contains(&AfBackend::AF_BACKEND_OPENCL){
47+
if available.contains(&Backend::AF_BACKEND_OPENCL){
4848
println!("Evaluating OpenCL Backend...");
49-
let err = set_backend(AfBackend::AF_BACKEND_OPENCL);
49+
let err = set_backend(Backend::AF_BACKEND_OPENCL);
5050
println!("There are {} OpenCL compute devices", device_count().unwrap());
5151
match err {
5252
Ok(_) => test_backend(),

src/array.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
extern crate libc;
22

33
use dim4::Dim4;
4-
use defines::AfError;
5-
use defines::Aftype;
4+
use defines::{AfError, Aftype, Backend};
65
use self::libc::{uint8_t, c_void, c_int, c_uint, c_longlong};
76

87
type MutAfArray = *mut self::libc::c_longlong;
@@ -11,6 +10,13 @@ type MutUint = *mut self::libc::c_uint;
1110
type AfArray = self::libc::c_longlong;
1211
type DimT = self::libc::c_longlong;
1312

13+
// Some unused functions from array.h in C-API of ArrayFire
14+
// af_create_handle
15+
// af_copy_array
16+
// af_write_array
17+
// af_get_data_ptr
18+
// af_get_data_ref_count
19+
1420
#[allow(dead_code)]
1521
extern {
1622
fn af_create_array(out: MutAfArray, data: *const c_void,
@@ -64,6 +70,8 @@ extern {
6470
fn af_print_array(arr: AfArray) -> c_int;
6571

6672
fn af_cast(out: MutAfArray, arr: AfArray, aftype: uint8_t) -> c_int;
73+
74+
fn af_get_backend_id(backend: *mut c_int, input: AfArray) -> c_int;
6775
}
6876

6977
/// A multidimensional data container
@@ -114,6 +122,25 @@ impl Array {
114122
}
115123
}
116124

125+
/// Returns the backend of the Array
126+
///
127+
/// # Return Values
128+
///
129+
/// Returns an value of type `Backend` which indicates which backend
130+
/// was active when Array was created.
131+
pub fn get_backend(&self) -> Backend {
132+
unsafe {
133+
let mut ret_val: i32 = 0;
134+
af_get_backend_id(&mut ret_val as *mut c_int, self.handle as AfArray);
135+
match ret_val {
136+
1 => Backend::AF_BACKEND_CPU,
137+
2 => Backend::AF_BACKEND_CUDA,
138+
3 => Backend::AF_BACKEND_OPENCL,
139+
_ => Backend::AF_BACKEND_DEFAULT,
140+
}
141+
}
142+
}
143+
117144
/// Returns the number of elements in the Array
118145
pub fn elements(&self) -> Result<i64, AfError> {
119146
unsafe {

src/backend.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
extern crate libc;
2+
3+
use defines::{AfError, Backend};
4+
use self::libc::{c_int, c_uint, uint8_t};
5+
6+
extern {
7+
fn af_set_backend(bknd: uint8_t) -> c_int;
8+
fn af_get_backend_count(num_backends: *mut c_uint) -> c_int;
9+
fn af_get_available_backends(backends: *mut c_int) -> c_int;
10+
}
11+
12+
/// Toggle backends between cuda, opencl or cpu
13+
///
14+
/// # Parameters
15+
///
16+
/// - `backend` to which to switch to
17+
pub fn set_backend(backend: Backend) -> Result<(), AfError> {
18+
unsafe {
19+
let err_val = af_set_backend(backend as uint8_t);
20+
match err_val {
21+
0 => Ok(()),
22+
_ => Err(AfError::from(err_val)),
23+
}
24+
}
25+
}
26+
27+
/// Get the available backend count
28+
#[allow(unused_mut)]
29+
pub fn get_backend_count() -> Result<u32, AfError> {
30+
unsafe {
31+
let mut temp: u32 = 0;
32+
let err_val = af_get_backend_count(&mut temp as *mut c_uint);
33+
match err_val {
34+
0 => Ok(temp),
35+
_ => Err(AfError::from(err_val)),
36+
}
37+
}
38+
}
39+
40+
41+
/// Get the available backends
42+
#[allow(unused_mut)]
43+
pub fn get_available_backends() -> Result<Vec<Backend>, AfError> {
44+
unsafe {
45+
let mut temp: i32 = 0;
46+
let err_val = af_get_available_backends(&mut temp as *mut c_int);
47+
match err_val {
48+
0 => {
49+
let mut b = Vec::new();
50+
if temp & 0b0100 == 0b0100 { b.push(Backend::AF_BACKEND_OPENCL); }
51+
if temp & 0b0010 == 0b0010 { b.push(Backend::AF_BACKEND_CUDA); }
52+
if temp & 0b0001 == 0b0001 { b.push(Backend::AF_BACKEND_CPU); }
53+
Ok(b)
54+
},
55+
_ => Err(AfError::from(err_val)),
56+
}
57+
}
58+
}

src/defines.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub enum AfError {
4949

5050
#[repr(C)]
5151
#[derive(Clone, Copy, Debug, PartialEq)]
52-
pub enum AfBackend {
52+
pub enum Backend {
5353
/// Default backend order: OpenCL -> CUDA -> CPU
5454
AF_BACKEND_DEFAULT = 0,
5555
/// CPU a.k.a sequential algorithms
@@ -60,13 +60,13 @@ pub enum AfBackend {
6060
AF_BACKEND_OPENCL = 4
6161
}
6262

63-
impl Display for AfBackend {
63+
impl Display for Backend {
6464
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
6565
let text = match *self {
66-
AfBackend::AF_BACKEND_OPENCL => "OpenCL",
67-
AfBackend::AF_BACKEND_CUDA => "Cuda",
68-
AfBackend::AF_BACKEND_CPU => "CPU",
69-
AfBackend::AF_BACKEND_DEFAULT => "Default",
66+
Backend::AF_BACKEND_OPENCL => "OpenCL",
67+
Backend::AF_BACKEND_CUDA => "Cuda",
68+
Backend::AF_BACKEND_CPU => "CPU",
69+
Backend::AF_BACKEND_DEFAULT => "Default",
7070
};
7171
write!(f, "{}", text)
7272
}
@@ -124,6 +124,10 @@ pub enum Aftype {
124124
S64 = 8,
125125
/// 64 bit unsigned integer
126126
U64 = 9,
127+
/// 16 bit signed integer
128+
S16 = 10,
129+
/// 16 bit unsigned integer
130+
U16 = 11,
127131
}
128132

129133
/// Dictates the interpolation method to be used by a function
@@ -291,3 +295,13 @@ pub enum YCCStd {
291295
/// ITU-R BT.2020 standard
292296
YCC_2020 = 2020,
293297
}
298+
299+
/// Homography type
300+
#[repr(C)]
301+
#[derive(Copy, Clone)]
302+
pub enum HomographyType {
303+
/// RANdom SAmple Consensus algorithm
304+
RANSAC = 0,
305+
/// Least Median of Squares
306+
LMEDS = 1,
307+
}

src/device/mod.rs

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
extern crate libc;
22

3-
use defines::{AfError, AfBackend};
4-
use self::libc::{c_int, c_uint, uint8_t};
5-
3+
use defines::AfError;
4+
use self::libc::c_int;
65

76
extern {
87
fn af_get_version(major: *mut c_int, minor: *mut c_int, patch: *mut c_int) -> c_int;
98
fn af_info() -> c_int;
109
fn af_get_device_count(nDevices: *mut c_int) -> c_int;
1110
fn af_get_dbl_support(available: *mut c_int, device: c_int) -> c_int;
1211
fn af_set_device(device: c_int) -> c_int;
13-
fn af_set_backend(bknd: uint8_t) -> c_int;
14-
fn af_get_backend_count(num_backends: *mut c_uint) -> c_int;
15-
fn af_get_available_backends(backends: *mut c_int) -> c_int;
1612
fn af_get_device(device: *mut c_int) -> c_int;
1713
fn af_sync(device: c_int) -> c_int;
1814
}
@@ -133,51 +129,3 @@ pub fn sync(device: i32) -> Result<(), AfError> {
133129
}
134130
}
135131
}
136-
137-
/// Toggle backends between cuda, opencl or cpu
138-
///
139-
/// # Parameters
140-
///
141-
/// - `backend` to which to switch to
142-
pub fn set_backend(backend: AfBackend) -> Result<(), AfError> {
143-
unsafe {
144-
let err_val = af_set_backend(backend as uint8_t);
145-
match err_val {
146-
0 => Ok(()),
147-
_ => Err(AfError::from(err_val)),
148-
}
149-
}
150-
}
151-
152-
/// Get the available backend count
153-
#[allow(unused_mut)]
154-
pub fn get_backend_count() -> Result<u32, AfError> {
155-
unsafe {
156-
let mut temp: u32 = 0;
157-
let err_val = af_get_backend_count(&mut temp as *mut c_uint);
158-
match err_val {
159-
0 => Ok(temp),
160-
_ => Err(AfError::from(err_val)),
161-
}
162-
}
163-
}
164-
165-
166-
/// Get the available backends
167-
#[allow(unused_mut)]
168-
pub fn get_available_backends() -> Result<Vec<AfBackend>, AfError> {
169-
unsafe {
170-
let mut temp: i32 = 0;
171-
let err_val = af_get_available_backends(&mut temp as *mut c_int);
172-
match err_val {
173-
0 => {
174-
let mut b = Vec::new();
175-
if temp & 0b0100 == 0b0100 { b.push(AfBackend::AF_BACKEND_OPENCL); }
176-
if temp & 0b0010 == 0b0010 { b.push(AfBackend::AF_BACKEND_CUDA); }
177-
if temp & 0b0001 == 0b0001 { b.push(AfBackend::AF_BACKEND_CPU); }
178-
Ok(b)
179-
},
180-
_ => Err(AfError::from(err_val)),
181-
}
182-
}
183-
}

src/graphics.rs

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,18 @@ extern {
1616
fn af_create_window(out: MutWndHandle, w: c_int, h: c_int, title: *const c_char) -> c_int;
1717
fn af_set_position(wnd: WndHandle, x: c_uint, y: c_uint) -> c_int;
1818
fn af_set_title(wnd: WndHandle, title: *const c_char) -> c_int;
19+
fn af_set_size(wnd: WndHandle, w: c_uint, h: c_uint) -> c_int;
1920
fn af_draw_image(wnd: WndHandle, arr: AfArray, props: CellPtr) -> c_int;
2021
fn af_draw_plot(wnd: WndHandle, x: AfArray, y: AfArray, props: CellPtr) -> c_int;
22+
fn af_draw_plot3(wnd: WndHandle, P: AfArray, props: CellPtr) -> c_int;
23+
fn af_draw_hist(wnd: WndHandle, x: AfArray,
24+
minval: c_double, maxval: c_double, props: CellPtr) -> c_int;
25+
fn af_draw_surface(wnd: WndHandle, xvals: AfArray, yvals: AfArray, S: AfArray,
26+
props: CellPtr) -> c_int;
2127
fn af_grid(wnd: WndHandle, rows: c_int, cols: c_int) -> c_int;
2228
fn af_show(wnd: WndHandle) -> c_int;
2329
fn af_is_window_closed(out: *mut c_int, wnd: WndHandle) -> c_int;
2430
fn af_destroy_window(wnd: WndHandle) -> c_int;
25-
fn af_draw_hist(wnd: WndHandle, x: AfArray,
26-
minval: c_double, maxval: c_double, props: CellPtr) -> c_int;
2731
}
2832

2933
/// Represents a sub-view of Window
@@ -147,6 +151,22 @@ impl Window {
147151
}
148152
}
149153

154+
/// Set window size
155+
///
156+
/// # Parameters
157+
///
158+
/// - `w` is the target width of window
159+
/// - `h` is the target height of window
160+
pub fn set_size(&self, w: u32, h: u32) -> Result<(), AfError> {
161+
unsafe {
162+
let err_val = af_set_size(self.handle as WndHandle, w as c_uint, h as c_uint);
163+
match err_val {
164+
0 => Ok(()),
165+
_ => Err(AfError::from(err_val)),
166+
}
167+
}
168+
}
169+
150170
/// Set color map to be used for rendering image, it can take one of the values of enum
151171
/// [ColorMap](./enum.ColorMap.html)
152172
pub fn set_colormap(&mut self, cmap: ColorMap) {
@@ -228,7 +248,24 @@ impl Window {
228248
cprops as *const Cell as CellPtr);
229249
match err_val {
230250
0 => (),
231-
_ => panic!("Rendering the image failed: {}", err_val),
251+
_ => panic!("Rendering 2d line plot failed: {}", err_val),
252+
}
253+
}
254+
}
255+
256+
/// Render give Arrays of points as a 3d line plot
257+
pub fn draw_plot3(&self, points: &Array, title: Option<String>) {
258+
let tstr = match title {
259+
Some(s) => s,
260+
None => format!("Cell({},{}))", self.col, self.row)
261+
};
262+
let cprops = &Cell {row: self.row, col: self.col, title: tstr.clone(), cmap: self.cmap};
263+
unsafe {
264+
let err_val = af_draw_plot3(self.handle as WndHandle, points.get() as AfArray,
265+
cprops as *const Cell as CellPtr);
266+
match err_val {
267+
0 => (),
268+
_ => panic!("Rendering 3d line plot failed: {}", err_val),
232269
}
233270
}
234271
}
@@ -246,7 +283,27 @@ impl Window {
246283
cprops as *const Cell as CellPtr);
247284
match err_val {
248285
0 => (),
249-
_ => panic!("Rendering the image failed: {}", err_val),
286+
_ => panic!("Rendering histogram failed: {}", err_val),
287+
}
288+
}
289+
}
290+
291+
/// Render give Arrays as 3d surface
292+
pub fn draw_surface(&self, xvals: &Array, yvals: &Array, zvals: &Array, title: Option<String>) {
293+
let tstr = match title {
294+
Some(s) => s,
295+
None => format!("Cell({},{}))", self.col, self.row)
296+
};
297+
let cprops = &Cell {row: self.row, col: self.col, title: tstr.clone(), cmap: self.cmap};
298+
unsafe {
299+
let err_val = af_draw_surface(self.handle as WndHandle,
300+
xvals.get() as AfArray,
301+
yvals.get() as AfArray,
302+
zvals.get() as AfArray,
303+
cprops as *const Cell as CellPtr);
304+
match err_val {
305+
0 => (),
306+
_ => panic!("Rendering surface failed: {}", err_val),
250307
}
251308
}
252309
}

0 commit comments

Comments
 (0)