Skip to content

Commit 9514647

Browse files
committed
Merge pull request #59 from 9prady9/af3.3.0
API Catchup to 3.3.0 version
2 parents b40c7db + 21972e7 commit 9514647

File tree

19 files changed

+615
-110
lines changed

19 files changed

+615
-110
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.2.0"
4+
version = "3.3.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 459 files

examples/helloworld.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn main() {
1010
let num_rows: u64 = 5;
1111
let num_cols: u64 = 3;
1212
let values: &[f32] = &[1.0, 2.0, 3.0];
13-
let indices = Array::new(Dim4::new(&[3, 1, 1, 1]), values, Aftype::F32).unwrap();
13+
let indices = Array::new(values, Dim4::new(&[3, 1, 1, 1])).unwrap();
1414

1515
let dims = Dim4::new(&[num_rows, num_cols, 1, 1]);
1616

@@ -74,13 +74,13 @@ fn main() {
7474
println!("Set last row to 1's");
7575
let r_dims = Dim4::new(&[3, 1, 1, 1]);
7676
let r_input: [f32; 3] = [1.0, 1.0, 1.0];
77-
let r = Array::new(r_dims, &r_input, Aftype::F32).unwrap();
77+
let r = Array::new(&r_input, r_dims).unwrap();
7878
print(&set_row(&a, &r, num_rows - 1).unwrap());
7979

8080
println!("Create 2-by-3 matrix from host data");
8181
let d_dims = Dim4::new(&[2, 3, 1, 1]);
8282
let d_input: [i32; 6] = [1, 2, 3, 4, 5, 6];
83-
let d = &Array::new(d_dims, &d_input, Aftype::S32).unwrap();
83+
let d = &Array::new(&d_input, d_dims).unwrap();
8484
print(d);
8585

8686
// printf("Copy last column onto first\n");

examples/pi.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#[macro_use(mem_info)]
12
extern crate arrayfire as af;
23
extern crate time;
34

@@ -12,11 +13,13 @@ fn main() {
1213
let samples = 20_000_000;
1314
let dims = Dim4::new(&[samples, 1, 1, 1]);
1415

15-
let x = &randu(dims, Aftype::F32).unwrap();
16-
let y = &randu(dims, Aftype::F32).unwrap();
16+
let x = &randu::<f32>(dims).unwrap();
17+
let y = &randu::<f32>(dims).unwrap();
1718

1819
let start = PreciseTime::now();
1920

21+
mem_info!("Before benchmark");
22+
2023
for bench_iter in 0..100 {
2124
let pi_val = add(&mul(x, x, false).unwrap(), &mul(y, y, false).unwrap(), false)
2225
.and_then( |z| sqrt(&z) )
@@ -29,4 +32,6 @@ fn main() {
2932
let end = PreciseTime::now();
3033

3134
println!("Estimated Pi Value in {} seconds", start.to(end) / 100);
35+
36+
mem_info!("After benchmark");
3237
}

examples/snow.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn main() {
1616
let dims = Dim4::new(&[1280, 720, 3, 1]);
1717

1818
loop {
19-
randu(dims, Aftype::F32).as_ref()
19+
randu::<f32>(dims).as_ref()
2020
.map(|arr| wnd.draw_image(arr, None));
2121

2222
if wnd.is_closed().unwrap() == true { break; }

examples/unified.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn test_backend(){
1111
let dims = Dim4::new(&[num_rows, num_cols, 1, 1]);
1212

1313
println!("Create a 10-by-10 matrix of random floats on the compute device");
14-
let a = match randu(dims, Aftype::F32) {
14+
let a = match randu::<f32>(dims) {
1515
Ok(value) => value,
1616
Err(error) => panic!("{}", error),
1717
};
@@ -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(&Backend::AF_BACKEND_CPU){
27+
if available.contains(&Backend::CPU){
2828
println!("Evaluating CPU Backend...");
29-
let err = set_backend(Backend::AF_BACKEND_CPU);
29+
let err = set_backend(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(&Backend::AF_BACKEND_CUDA){
37+
if available.contains(&Backend::CUDA){
3838
println!("Evaluating CUDA Backend...");
39-
let err = set_backend(Backend::AF_BACKEND_CUDA);
39+
let err = set_backend(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(&Backend::AF_BACKEND_OPENCL){
47+
if available.contains(&Backend::OPENCL){
4848
println!("Evaluating OpenCL Backend...");
49-
let err = set_backend(Backend::AF_BACKEND_OPENCL);
49+
let err = set_backend(Backend::OPENCL);
5050
println!("There are {} OpenCL compute devices", device_count().unwrap());
5151
match err {
5252
Ok(_) => test_backend(),

src/array.rs

Lines changed: 103 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ extern crate libc;
22

33
use dim4::Dim4;
44
use defines::{AfError, Aftype, Backend};
5+
use util::HasAfEnum;
56
use self::libc::{uint8_t, c_void, c_int, c_uint, c_longlong};
67

78
type MutAfArray = *mut self::libc::c_longlong;
@@ -72,6 +73,21 @@ extern {
7273
fn af_cast(out: MutAfArray, arr: AfArray, aftype: uint8_t) -> c_int;
7374

7475
fn af_get_backend_id(backend: *mut c_int, input: AfArray) -> c_int;
76+
77+
fn af_get_device_id(device: *mut c_int, input: AfArray) -> c_int;
78+
79+
fn af_create_strided_array(arr: MutAfArray, data: *const c_void, offset: DimT,
80+
ndims: c_uint, dims: *const DimT, strides: *const DimT,
81+
aftype: uint8_t) -> c_int;
82+
83+
fn af_get_strides(s0: *mut DimT, s1: *mut DimT, s2: *mut DimT, s3: *mut DimT,
84+
arr: AfArray) -> c_int;
85+
86+
fn af_get_offset(offset: *mut DimT, arr: AfArray) -> c_int;
87+
88+
fn af_is_linear(result: *mut c_int, arr: AfArray) -> c_int;
89+
90+
fn af_is_owner(result: *mut c_int, arr: AfArray) -> c_int;
7591
}
7692

7793
/// A multidimensional data container
@@ -104,11 +120,12 @@ impl Array {
104120
///
105121
/// ```
106122
/// let values: &[f32] = &[1.0, 2.0, 3.0];
107-
/// let indices = Array::new(Dim4::new(&[3, 1, 1, 1]), values, Aftype::F32).unwrap();
123+
/// let indices = Array::new(values, Dim4::new(&[3, 1, 1, 1])).unwrap();
108124
/// ```
109125
#[allow(unused_mut)]
110-
pub fn new<T>(dims: Dim4, slice: &[T], aftype: Aftype) -> Result<Array, AfError> {
126+
pub fn new<T: HasAfEnum>(slice: &[T], dims: Dim4) -> Result<Array, AfError> {
111127
unsafe {
128+
let aftype = T::get_af_dtype();
112129
let mut temp: i64 = 0;
113130
let err_val = af_create_array(&mut temp as MutAfArray,
114131
slice.as_ptr() as *const c_void,
@@ -122,21 +139,61 @@ impl Array {
122139
}
123140
}
124141

142+
/// Constructs a new Array object from strided data
143+
///
144+
/// The data pointed by the slice passed to this function can possibily be offseted using an additional `offset` parameter.
145+
#[allow(unused_mut)]
146+
pub fn new_strided<T: HasAfEnum>(slice: &[T], offset: i64,
147+
dims: Dim4, strides: Dim4) -> Result<Array, AfError> {
148+
unsafe {
149+
let aftype = T::get_af_dtype();
150+
let mut temp: i64 = 0;
151+
let err_val = af_create_strided_array(&mut temp as MutAfArray,
152+
slice.as_ptr() as *const c_void,
153+
offset as DimT,
154+
dims.ndims() as c_uint,
155+
dims.get().as_ptr() as * const c_longlong,
156+
strides.get().as_ptr() as * const c_longlong,
157+
aftype as uint8_t);
158+
match err_val {
159+
0 => Ok(Array {handle: temp}),
160+
_ => Err(AfError::from(err_val)),
161+
}
162+
}
163+
}
164+
125165
/// Returns the backend of the Array
126166
///
127167
/// # Return Values
128168
///
129169
/// Returns an value of type `Backend` which indicates which backend
130170
/// was active when Array was created.
131-
pub fn get_backend(&self) -> Backend {
171+
pub fn get_backend(&self) -> Result<Backend, AfError> {
132172
unsafe {
133173
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,
174+
let err_val = af_get_backend_id(&mut ret_val as *mut c_int, self.handle as AfArray);
175+
match (err_val, ret_val) {
176+
(0, 1) => Ok(Backend::CPU),
177+
(0, 2) => Ok(Backend::CUDA),
178+
(0, 3) => Ok(Backend::OPENCL),
179+
_ => Err(AfError::from(err_val)),
180+
}
181+
}
182+
}
183+
184+
/// Returns the device identifier(integer) on which the Array was created
185+
///
186+
/// # Return Values
187+
///
188+
/// Return the device id on which Array was created.
189+
pub fn get_device_id(&self) -> Result<i32, AfError> {
190+
unsafe {
191+
let mut ret_val: i32 = 0;
192+
let err_val = af_get_device_id(&mut ret_val as *mut c_int, self.handle as AfArray);
193+
match err_val {
194+
0 => Ok(ret_val),
195+
_ => Err(AfError::from(err_val)),
196+
140197
}
141198
}
142199
}
@@ -172,8 +229,8 @@ impl Array {
172229
let mut ret1: i64 = 0;
173230
let mut ret2: i64 = 0;
174231
let mut ret3: i64 = 0;
175-
let err_val = af_get_dims(&mut ret0 as *mut c_longlong, &mut ret1 as *mut c_longlong,
176-
&mut ret2 as *mut c_longlong, &mut ret3 as *mut c_longlong,
232+
let err_val = af_get_dims(&mut ret0 as *mut DimT, &mut ret1 as *mut DimT,
233+
&mut ret2 as *mut DimT, &mut ret3 as *mut DimT,
177234
self.handle as AfArray);
178235
match err_val {
179236
0 => Ok(Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64])),
@@ -182,6 +239,23 @@ impl Array {
182239
}
183240
}
184241

242+
/// Returns the strides of the Array
243+
pub fn strides(&self) -> Result<Dim4, AfError> {
244+
unsafe {
245+
let mut ret0: i64 = 0;
246+
let mut ret1: i64 = 0;
247+
let mut ret2: i64 = 0;
248+
let mut ret3: i64 = 0;
249+
let err_val = af_get_strides(&mut ret0 as *mut DimT, &mut ret1 as *mut DimT,
250+
&mut ret2 as *mut DimT, &mut ret3 as *mut DimT,
251+
self.handle as AfArray);
252+
match err_val {
253+
0 => Ok(Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64])),
254+
_ => Err(AfError::from(err_val)),
255+
}
256+
}
257+
}
258+
185259
/// Returns the number of dimensions of the Array
186260
pub fn numdims(&self) -> Result<u32, AfError> {
187261
unsafe {
@@ -194,6 +268,18 @@ impl Array {
194268
}
195269
}
196270

271+
/// Returns the offset to the pointer from where data begins
272+
pub fn offset(&self) -> Result<i64, AfError> {
273+
unsafe {
274+
let mut ret_val: i64 = 0;
275+
let err_val = af_get_offset(&mut ret_val as *mut DimT, self.handle as AfArray);
276+
match err_val {
277+
0 => Ok(ret_val),
278+
_ => Err(AfError::from(err_val)),
279+
}
280+
}
281+
}
282+
197283
/// Returns the native FFI handle for Rust object `Array`
198284
pub fn get(&self) -> i64 {
199285
self.handle
@@ -247,12 +333,15 @@ impl Array {
247333
is_func!(is_floating, af_is_floating);
248334
is_func!(is_integer, af_is_integer);
249335
is_func!(is_bool, af_is_bool);
336+
is_func!(is_linear, af_is_linear);
337+
is_func!(is_owner, af_is_owner);
250338

251339
/// Cast the Array data type to `target_type`
252-
pub fn cast(&self, target_type: Aftype) -> Result<Array, AfError> {
340+
pub fn cast<T: HasAfEnum>(&self) -> Result<Array, AfError> {
253341
unsafe {
342+
let trgt_type = T::get_af_dtype();
254343
let mut temp: i64 = 0;
255-
let err_val = af_cast(&mut temp as MutAfArray, self.handle as AfArray, target_type as uint8_t);
344+
let err_val = af_cast(&mut temp as MutAfArray, self.handle as AfArray, trgt_type as uint8_t);
256345
match err_val {
257346
0 => Ok(Array::from(temp)),
258347
_ => Err(AfError::from(err_val)),
@@ -301,7 +390,7 @@ impl Drop for Array {
301390
///
302391
/// ```
303392
/// println!("Create a 5-by-3 matrix of random floats on the GPU");
304-
/// let a = match randu(dims, Aftype::F32) {
393+
/// let a = match randu::<f32>(dims) {
305394
/// Ok(value) => value,
306395
/// Err(error) => panic!("{}", error),
307396
/// };

src/backend.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extern {
77
fn af_set_backend(bknd: uint8_t) -> c_int;
88
fn af_get_backend_count(num_backends: *mut c_uint) -> c_int;
99
fn af_get_available_backends(backends: *mut c_int) -> c_int;
10+
fn af_get_active_backend(backend: *mut c_int) -> c_int;
1011
}
1112

1213
/// Toggle backends between cuda, opencl or cpu
@@ -47,12 +48,28 @@ pub fn get_available_backends() -> Result<Vec<Backend>, AfError> {
4748
match err_val {
4849
0 => {
4950
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); }
51+
if temp & 0b0100 == 0b0100 { b.push(Backend::OPENCL); }
52+
if temp & 0b0010 == 0b0010 { b.push(Backend::CUDA); }
53+
if temp & 0b0001 == 0b0001 { b.push(Backend::CPU); }
5354
Ok(b)
5455
},
5556
_ => Err(AfError::from(err_val)),
5657
}
5758
}
5859
}
60+
61+
/// Get current active backend
62+
#[allow(unused_mut)]
63+
pub fn get_active_backend() -> Result<Backend, AfError> {
64+
unsafe {
65+
let mut temp: i32 = 0;
66+
let err_val = af_get_active_backend(&mut temp as *mut c_int);
67+
match (err_val, temp) {
68+
(0, 0) => Ok(Backend::DEFAULT),
69+
(0, 1) => Ok(Backend::CPU),
70+
(0, 2) => Ok(Backend::CUDA),
71+
(0, 4) => Ok(Backend::OPENCL),
72+
_ => Err(AfError::from(err_val)),
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)