diff --git a/Cargo.toml b/Cargo.toml index f84eab929..e5cea8a44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "arrayfire" 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." -version = "3.4.1" +version = "3.4.2" documentation = "http://arrayfire.github.io/arrayfire-rust/arrayfire/index.html" homepage = "https://github.com/arrayfire/arrayfire" repository = "https://github.com/arrayfire/arrayfire-rust" diff --git a/README.md b/README.md index 11c9b6afc..6f379fbe6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,14 @@ |:-------:|:-------:|:---:| | [![Build Status](http://ci.arrayfire.org/buildStatus/icon?job=arrayfire-wrappers/rust-linux)](http://ci.arrayfire.org/view/All/job/arrayfire-wrappers/job/rust-linux/) | [![Build Status](http://ci.arrayfire.org/buildStatus/icon?job=arrayfire-wrappers/rust-windows)](http://ci.arrayfire.org/view/All/job/arrayfire-wrappers/job/rust-windows/) | [![Build Status](http://ci.arrayfire.org/buildStatus/icon?job=arrayfire-wrappers/rust-osx)](http://ci.arrayfire.org/view/All/job/arrayfire-wrappers/job/rust-osx/) | -[ArrayFire](https://github.com/arrayfire/arrayfire) is a high performance library for parallel computing with an easy-to-use API. It enables users to write scientific computing code that is portable across CUDA, OpenCL and CPU devices. This project provides Rust bindings for the ArrayFire library. The wrapper is currently compliant with ArrayFire 3.4.x API. If you find any bugs, please report them [here](https://github.com/arrayfire/arrayfire-rust/issues). +[ArrayFire](https://github.com/arrayfire/arrayfire) is a high performance library for parallel computing with an easy-to-use API. It enables users to write scientific computing code that is portable across CUDA, OpenCL and CPU devices. This project provides Rust bindings for the ArrayFire library. Given below table shows the rust bindings compatability with ArrayFire. If you find any bugs, please report them [here](https://github.com/arrayfire/arrayfire-rust/issues). + +| ArrayFire Upstream | Rust Crate | +|:------------------:|:---------------:| +| 3.3.x | 3.3.x | +| 3.4.x | 3.4.x | + +Only, Major & Minor version numbers need to match. ## Documentation @@ -30,7 +37,8 @@ first. 3. Make sure you add the path to library files to your path environment variables. - On Linux & OSX: do `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AF_PATH/lib` - On Windows: Add `%AF_PATH%\lib` to your PATH environment variable. -4. Add `arrayfire = "3.4.1"` to the dependencies section of your project's Cargo.toml file. +4. Add `arrayfire = "3.4.2"` to the dependencies section of your project's Cargo.toml file - 3.4.2 + is the lastest version of crate. Once step (4) is over, you should be able to use ArrayFire in your Rust project. If you find any bugs, please report them [here](https://github.com/arrayfire/arrayfire-rust/issues). @@ -68,10 +76,6 @@ af_print!("Create a 5-by-3 matrix of random floats on the GPU", a); ~/p/arrayfire_rust> cargo run --example helloworld ... running 1 test -ArrayFire v3.4.0 (CUDA, 64-bit Linux, build 10d9716) -Platform: CUDA Toolkit 7.5, Driver: 361.42 -[0] GeForce GT 650M, 2048 MB, CUDA Compute 3.0 - Create a 5-by-3 matrix of random floats on the GPU [5 3 1 1] 0.7402 0.4464 0.7762 diff --git a/examples/helloworld.rs b/examples/helloworld.rs index be21558cd..53cf75eb1 100644 --- a/examples/helloworld.rs +++ b/examples/helloworld.rs @@ -7,6 +7,11 @@ use af::*; fn main() { set_device(0); info(); + print!("Info String:\n{}", info_string(true)); + println!("Arrayfire version: {:?}", get_version()); + let (name, platform, toolkit, compute) = device_info(); + print!("Name: {}\nPlatform: {}\nToolkit: {}\nCompute: {}\n", name, platform, toolkit, compute); + println!("Revision: {}", get_revision()); let num_rows: u64 = 5; let num_cols: u64 = 3; diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs index 87379ed6e..49f53dbb4 100644 --- a/src/algorithm/mod.rs +++ b/src/algorithm/mod.rs @@ -4,11 +4,7 @@ use array::Array; use defines::{AfError, BinaryOp}; use error::HANDLE_ERROR; use self::libc::{c_int, uint8_t, c_uint, c_double}; - -type MutAfArray = *mut self::libc::c_longlong; -type MutDouble = *mut self::libc::c_double; -type MutUint = *mut self::libc::c_uint; -type AfArray = self::libc::c_longlong; +use util::{AfArray, MutAfArray, MutDouble, MutUint}; #[allow(dead_code)] extern { diff --git a/src/arith/mod.rs b/src/arith/mod.rs index 32e291dd9..7e77df60d 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -8,16 +8,8 @@ use error::HANDLE_ERROR; use self::libc::{c_int}; use data::{constant, constant_t, tile}; use self::num::Complex; - +use util::{AfArray, Complex32, Complex64, MutAfArray}; use std::ops::Neg; - -type Complex32 = Complex; -type Complex64 = Complex; -type MutAfArray = *mut self::libc::c_longlong; -type MutDouble = *mut self::libc::c_double; -type MutUint = *mut self::libc::c_uint; -type AfArray = self::libc::c_longlong; - use std::ops::{Add, Sub, Div, Mul, BitAnd, BitOr, BitXor, Not, Rem, Shl, Shr}; #[allow(dead_code)] @@ -180,12 +172,12 @@ macro_rules! binary_func { /// /// This is an element wise binary operation. #[allow(unused_mut)] - pub fn $fn_name(lhs: &Array, rhs: &Array) -> Array { + pub fn $fn_name(lhs: &Array, rhs: &Array, batch: bool) -> Array { unsafe { let mut temp: i64 = 0; let err_val = $ffi_fn(&mut temp as MutAfArray, lhs.get() as AfArray, rhs.get() as AfArray, - 0); + batch as c_int); HANDLE_ERROR(AfError::from(err_val)); Array::from(temp) } @@ -217,6 +209,8 @@ macro_rules! convertable_type_def { ) } +convertable_type_def!(Complex); +convertable_type_def!(Complex); convertable_type_def!(u64); convertable_type_def!(i64); convertable_type_def!(f64); @@ -350,19 +344,13 @@ pub fn clamp (input: &Array, arg1: &T, arg2: &U, batch: bool) -> Array } macro_rules! arith_scalar_func { - ($rust_type: ty, $op_name:ident, $fn_name: ident, $ffi_fn: ident) => ( + ($rust_type: ty, $op_name:ident, $fn_name: ident) => ( impl<'f> $op_name<$rust_type> for &'f Array { type Output = Array; fn $fn_name(self, rhs: $rust_type) -> Array { - let cnst_arr = constant(rhs, self.dims()); - unsafe { - let mut temp: i64 = 0; - let err_val = $ffi_fn(&mut temp as MutAfArray, self.get() as AfArray, - cnst_arr.get() as AfArray, 0); - HANDLE_ERROR(AfError::from(err_val)); - Array::from(temp) - } + let temp = rhs.clone(); + $fn_name(self, &temp, false) } } @@ -370,14 +358,8 @@ macro_rules! arith_scalar_func { type Output = Array; fn $fn_name(self, rhs: $rust_type) -> Array { - let cnst_arr = constant(rhs, self.dims()); - unsafe { - let mut temp: i64 = 0; - let err_val = $ffi_fn(&mut temp as MutAfArray, self.get() as AfArray, - cnst_arr.get() as AfArray, 0); - HANDLE_ERROR(AfError::from(err_val)); - Array::from(temp) - } + let temp = rhs.clone(); + $fn_name(&self, &temp, false) } } ) @@ -385,10 +367,10 @@ macro_rules! arith_scalar_func { macro_rules! arith_scalar_spec { ($ty_name:ty) => ( - arith_scalar_func!($ty_name, Add, add, af_add); - arith_scalar_func!($ty_name, Sub, sub, af_sub); - arith_scalar_func!($ty_name, Mul, mul, af_mul); - arith_scalar_func!($ty_name, Div, div, af_div); + arith_scalar_func!($ty_name, Add, add); + arith_scalar_func!($ty_name, Sub, sub); + arith_scalar_func!($ty_name, Mul, mul); + arith_scalar_func!($ty_name, Div, div); ) } @@ -403,33 +385,51 @@ arith_scalar_spec!(i32); arith_scalar_spec!(u8); macro_rules! arith_func { - ($op_name:ident, $fn_name:ident, $ffi_fn: ident) => ( + ($op_name:ident, $fn_name:ident, $delegate:ident) => ( impl $op_name for Array { type Output = Array; fn $fn_name(self, rhs: Array) -> Array { - unsafe { - let mut temp: i64 = 0; - let err_val = $ffi_fn(&mut temp as MutAfArray, - self.get() as AfArray, rhs.get() as AfArray, 0); - HANDLE_ERROR(AfError::from(err_val)); - Array::from(temp) - } + $delegate(&self, &rhs, false) + } + } + + impl<'a> $op_name<&'a Array> for Array { + type Output = Array; + + fn $fn_name(self, rhs: &'a Array) -> Array { + $delegate(&self, rhs, false) + } + } + + impl<'a> $op_name for &'a Array { + type Output = Array; + + fn $fn_name(self, rhs: Array) -> Array { + $delegate(self, &rhs, false) + } + } + + impl<'a, 'b> $op_name<&'a Array> for &'b Array { + type Output = Array; + + fn $fn_name(self, rhs: &'a Array) -> Array { + $delegate(self, rhs, false) } } ) } -arith_func!(Add, add, af_add); -arith_func!(Sub, sub, af_sub); -arith_func!(Mul, mul, af_mul); -arith_func!(Div, div, af_div); -arith_func!(Rem, rem, af_rem); -arith_func!(BitAnd, bitand, af_bitand); -arith_func!(BitOr, bitor, af_bitor); -arith_func!(BitXor, bitxor, af_bitxor); -arith_func!(Shl, shl, af_bitshiftl); -arith_func!(Shr, shr, af_bitshiftr); +arith_func!(Add , add , add ); +arith_func!(Sub , sub , sub ); +arith_func!(Mul , mul , mul ); +arith_func!(Div , div , div ); +arith_func!(Rem , rem , rem ); +arith_func!(Shl , shl , shiftl); +arith_func!(Shr , shr , shiftr); +arith_func!(BitAnd, bitand, bitand); +arith_func!(BitOr , bitor , bitor ); +arith_func!(BitXor, bitxor, bitxor); #[cfg(op_assign)] mod op_assign { @@ -450,8 +450,9 @@ macro_rules! arith_assign_func { #[allow(unused_variables)] fn $fn_name(&mut self, rhs: Array) { let mut idxrs = Indexer::new(); - idxrs.set_index(&Seq::::default(), 0, Some(false)); - idxrs.set_index(&Seq::::default(), 1, Some(false)); + for n in 0..self.numdims() { + idxrs.set_index(&Seq::::default(), n, Some(false)); + } let tmp = assign_gen(self as &Array, &idxrs, & $func(self as &Array, &rhs, false)); mem::replace(self, tmp); @@ -477,7 +478,7 @@ macro_rules! bit_assign_func { let mut idxrs = Indexer::new(); idxrs.set_index(&Seq::::default(), 0, Some(false)); idxrs.set_index(&Seq::::default(), 1, Some(false)); - let tmp = assign_gen(self as &Array, &idxrs, & $func(self as &Array, &rhs)); + let tmp = assign_gen(self as &Array, &idxrs, & $func(self as &Array, &rhs, false)); mem::replace(self, tmp); } } diff --git a/src/array.rs b/src/array.rs index aa6df0b46..14ace7ade 100644 --- a/src/array.rs +++ b/src/array.rs @@ -3,18 +3,10 @@ extern crate libc; use dim4::Dim4; use defines::{AfError, DType, Backend}; use error::HANDLE_ERROR; -use util::HasAfEnum; +use util::{AfArray, DimT, HasAfEnum, MutAfArray, MutVoidPtr}; use self::libc::{uint8_t, c_void, c_int, c_uint, c_longlong, c_char}; use std::ffi::CString; -type MutAfArray = *mut self::libc::c_longlong; -type MutDouble = *mut self::libc::c_double; -type MutUint = *mut self::libc::c_uint; -type AfArray = self::libc::c_longlong; -type DimT = self::libc::c_longlong; -type MutVoidPtr = *mut self::libc::c_ulonglong; -type VoidPtr = self::libc::c_ulonglong; - // Some unused functions from array.h in C-API of ArrayFire // af_create_handle // af_copy_array diff --git a/src/blas/mod.rs b/src/blas/mod.rs index 49bad1c69..5255a1167 100644 --- a/src/blas/mod.rs +++ b/src/blas/mod.rs @@ -5,10 +5,7 @@ use defines::AfError; use defines::MatProp; use error::HANDLE_ERROR; use self::libc::{c_uint, c_int}; -use util::to_u32; - -type MutAfArray = *mut self::libc::c_longlong; -type AfArray = self::libc::c_longlong; +use util::{AfArray, MutAfArray, to_u32}; #[allow(dead_code)] extern { diff --git a/src/data/mod.rs b/src/data/mod.rs index a85f0382a..71981e756 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -7,17 +7,9 @@ use defines::{AfError, DType, Scalar}; use error::HANDLE_ERROR; use self::libc::{uint8_t, c_int, c_uint, c_double}; use self::num::Complex; -use util::HasAfEnum; +use util::{AfArray, DimT, HasAfEnum, Intl, MutAfArray, Uintl}; use std::vec::Vec; -type MutAfArray = *mut self::libc::c_longlong; -type MutDouble = *mut self::libc::c_double; -type MutUint = *mut self::libc::c_uint; -type AfArray = self::libc::c_longlong; -type DimT = self::libc::c_longlong; -type Intl = self::libc::c_longlong; -type Uintl = self::libc::c_ulonglong; - #[allow(dead_code)] extern { fn af_constant(out: MutAfArray, val: c_double, diff --git a/src/device/mod.rs b/src/device/mod.rs index d8a8a0081..b806d8634 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -1,13 +1,19 @@ extern crate libc; -use defines::AfError; +use defines::{AfError}; use error::HANDLE_ERROR; use self::libc::{c_int, size_t, c_char}; -use std::ffi::CString; +use std::ffi::{CStr, CString}; +use std::borrow::Cow; +use util::free_host; extern { fn af_get_version(major: *mut c_int, minor: *mut c_int, patch: *mut c_int) -> c_int; + fn af_get_revision() -> *const c_char; fn af_info() -> c_int; + fn af_info_string(str: *mut *mut c_char, verbose: bool) -> c_int; + fn af_device_info(d_name: *mut c_char, d_platform: *mut c_char, + d_toolkit: *mut c_char, d_compute: *mut c_char) -> c_int; fn af_init() -> c_int; fn af_get_device_count(nDevices: *mut c_int) -> c_int; fn af_get_dbl_support(available: *mut c_int, device: c_int) -> c_int; @@ -38,6 +44,16 @@ pub fn get_version() -> (i32, i32, i32) { } } +/// Get ArrayFire Revision (commit) information of the library. +/// +/// # Return Values +/// This returns a `Cow<'static, str>` as the string is constructed at compile time. +pub fn get_revision() -> Cow<'static, str> { + unsafe { + CStr::from_ptr(af_get_revision()).to_string_lossy() + } +} + /// Print library meta-info /// /// # Examples @@ -56,6 +72,51 @@ pub fn info() { } } +/// Return library meta-info as `String` +/// +/// # Examples +/// +/// An example output of `af::info_string` call looks like below +/// +/// ```text +/// ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38) +/// Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000 +/// [0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0 +/// ``` +pub fn info_string(verbose: bool) -> String { + let result: String; + unsafe { + let mut tmp: *mut c_char = ::std::ptr::null_mut(); + let err_val = af_info_string(&mut tmp, verbose); + HANDLE_ERROR(AfError::from(err_val)); + result = CStr::from_ptr(tmp).to_string_lossy().into_owned(); + free_host(tmp); + } + result +} + +/// Gets the information about device and platform as strings. +/// +/// # Return Values +/// A tuple of `String` indicating the name, platform, toolkit and compute. +pub fn device_info() -> (String, String, String, String) { + let mut name = [0 as c_char; 64]; + let mut platform = [0 as c_char; 10]; + let mut toolkit = [0 as c_char; 64]; + let mut compute = [0 as c_char; 10]; + unsafe { + let err_val = af_device_info(&mut name[0], + &mut platform[0], + &mut toolkit[0], + &mut compute[0]); + HANDLE_ERROR(AfError::from(err_val)); + (CStr::from_ptr(name.as_mut_ptr()).to_string_lossy().into_owned(), + CStr::from_ptr(platform.as_mut_ptr()).to_string_lossy().into_owned(), + CStr::from_ptr(toolkit.as_mut_ptr()).to_string_lossy().into_owned(), + CStr::from_ptr(compute.as_mut_ptr()).to_string_lossy().into_owned()) + } +} + /// Initialize ArrayFire library /// /// 0th device will be the default device unless init call diff --git a/src/error.rs b/src/error.rs index 0c1b371b3..ddb765605 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,33 +4,27 @@ use std::error::Error; use std::marker::{Send, Sync}; use std::sync::RwLock; - pub type ErrorCallback = Fn(AfError); - /// Wrap ErrorCallback function pointer inside a structure /// to enable implementing Send, Sync traits on it. pub struct Callback<'cblifetime> { pub cb: &'cblifetime ErrorCallback, } - // Implement Send, Sync traits for Callback structure to // enable the user of Callback function pointer in conjunction // with threads using a mutex. unsafe impl<'cblifetime> Send for Callback<'cblifetime> {} unsafe impl<'cblifetime> Sync for Callback<'cblifetime> {} - pub const DEFAULT_HANDLE_ERROR: Callback<'static> = Callback{cb: &handle_error_general}; - lazy_static! { static ref ERROR_HANDLER_LOCK: RwLock< Callback<'static> > = RwLock::new(DEFAULT_HANDLE_ERROR); } - /// Register user provided error handler /// /// # Examples diff --git a/src/graphics.rs b/src/graphics.rs index 4cc6e657b..7e25f78ff 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -7,11 +7,7 @@ use error::HANDLE_ERROR; use self::libc::{c_int, c_uint, c_float, c_double, c_char}; use std::ffi::CString; use std::ptr; - -type MutWndHandle = *mut self::libc::c_ulonglong; -type WndHandle = self::libc::c_ulonglong; -type AfArray = self::libc::c_longlong; -type CellPtr = *const self::libc::c_void; +use util::{AfArray, CellPtr, MutWndHandle, WndHandle}; #[allow(dead_code)] extern { diff --git a/src/image/mod.rs b/src/image/mod.rs index 88258d541..b44729c16 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -3,13 +3,9 @@ extern crate libc; use array::Array; use defines::{AfError, BorderType, ColorSpace, Connectivity, InterpType, YCCStd, MomentType}; use error::HANDLE_ERROR; -use util::HasAfEnum; +use util::{AfArray, DimT, HasAfEnum, MutAfArray}; use self::libc::{uint8_t, c_uint, c_int, c_float, c_double}; -type MutAfArray = *mut self::libc::c_longlong; -type AfArray = self::libc::c_longlong; -type DimT = self::libc::c_longlong; - // unused functions from image.h header // af_load_image_memory // af_save_image_memory diff --git a/src/index.rs b/src/index.rs index 273963bab..e478b1b9d 100644 --- a/src/index.rs +++ b/src/index.rs @@ -5,12 +5,7 @@ use defines::AfError; use error::HANDLE_ERROR; use seq::Seq; use self::libc::{c_double, c_int, c_uint}; - -type MutAfIndex = *mut self::libc::c_longlong; -type MutAfArray = *mut self::libc::c_longlong; -type AfArray = self::libc::c_longlong; -type DimT = self::libc::c_longlong; -type IndexT = self::libc::c_longlong; +use util::{AfArray, DimT, IndexT, MutAfArray, MutAfIndex}; #[allow(dead_code)] extern { diff --git a/src/lapack/mod.rs b/src/lapack/mod.rs index 3afec476e..7193f2816 100644 --- a/src/lapack/mod.rs +++ b/src/lapack/mod.rs @@ -3,13 +3,9 @@ extern crate libc; use array::Array; use defines::{AfError, MatProp, NormType}; use error::HANDLE_ERROR; -use util::to_u32; +use util::{AfArray, MutAfArray, MutDouble, to_u32}; use self::libc::{uint8_t, c_int, c_uint, c_double}; -type MutAfArray = *mut self::libc::c_longlong; -type MutDouble = *mut self::libc::c_double; -type AfArray = self::libc::c_longlong; - #[allow(dead_code)] extern { fn af_svd(u: MutAfArray, s: MutAfArray, vt: MutAfArray, input: AfArray) -> c_int; @@ -403,4 +399,4 @@ pub fn is_lapack_available() -> bool { af_is_lapack_available(&mut temp as *mut c_int); temp > 0 // Return boolean fla } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 23b2a78dc..2ead5233d 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,7 @@ pub use data::{select, selectl, selectr, replace, replace_scalar}; pub use data::{range_t, iota_t, identity_t, constant_t}; mod data; -pub use device::{get_version, info, init, device_count, is_double_available, set_device, get_device}; +pub use device::{get_version, get_revision, info, info_string, device_info, init, device_count, is_double_available, set_device, get_device}; pub use device::{device_mem_info, print_mem_info, set_mem_step_size, get_mem_step_size, device_gc, sync}; mod device; diff --git a/src/random/mod.rs b/src/random/mod.rs index 9a095ad2d..f382e31cc 100644 --- a/src/random/mod.rs +++ b/src/random/mod.rs @@ -5,15 +5,7 @@ use dim4::Dim4; use defines::{AfError, RandomEngineType}; use error::HANDLE_ERROR; use self::libc::{uint8_t, c_int, c_uint}; -use util::HasAfEnum; - -type MutAfArray = *mut self::libc::c_longlong; -type AfArray = self::libc::c_longlong; -type MutRandEngine = *mut self::libc::c_longlong; -type RandEngine = self::libc::c_longlong; -type DimT = self::libc::c_longlong; -type Intl = self::libc::c_longlong; -type Uintl = self::libc::c_ulonglong; +use util::{DimT, HasAfEnum, MutAfArray, MutRandEngine, RandEngine, Uintl}; #[allow(dead_code)] extern { diff --git a/src/seq.rs b/src/seq.rs index a56410362..cd625dd19 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -2,7 +2,6 @@ extern crate libc; use std::fmt; use std::default::Default; - use num::{One, Zero}; /// Sequences are used for indexing Arrays diff --git a/src/signal/mod.rs b/src/signal/mod.rs index cf404cbf3..8c33e060e 100644 --- a/src/signal/mod.rs +++ b/src/signal/mod.rs @@ -4,9 +4,7 @@ use array::Array; use defines::{AfError, ConvDomain, ConvMode, InterpType}; use error::HANDLE_ERROR; use self::libc::{uint8_t, c_int, c_float, c_double, c_longlong, size_t}; - -type MutAfArray = *mut self::libc::c_longlong; -type AfArray = self::libc::c_longlong; +use util::{AfArray, MutAfArray}; #[allow(dead_code)] extern { diff --git a/src/sparse/mod.rs b/src/sparse/mod.rs index 1950edcb8..e5ee79a59 100644 --- a/src/sparse/mod.rs +++ b/src/sparse/mod.rs @@ -4,12 +4,7 @@ use array::Array; use defines::{AfError, SparseFormat}; use error::HANDLE_ERROR; use self::libc::{uint8_t, c_void, c_int}; -use util::HasAfEnum; - -type MutAfArray = *mut self::libc::c_longlong; -type AfArray = self::libc::c_longlong; -type DimT = self::libc::c_longlong; -type MutDimT = *mut self::libc::c_longlong; +use util::{AfArray, DimT, HasAfEnum, MutAfArray, MutDimT}; #[allow(dead_code)] extern { diff --git a/src/statistics/mod.rs b/src/statistics/mod.rs index cb1269a5c..742fed476 100644 --- a/src/statistics/mod.rs +++ b/src/statistics/mod.rs @@ -4,11 +4,7 @@ use array::Array; use defines::AfError; use error::HANDLE_ERROR; use self::libc::{c_int}; - -type MutAfArray = *mut self::libc::c_longlong; -type MutDouble = *mut self::libc::c_double; -type AfArray = self::libc::c_longlong; -type DimT = self::libc::c_longlong; +use util::{AfArray, DimT, MutAfArray, MutDouble}; #[allow(dead_code)] extern { diff --git a/src/util.rs b/src/util.rs index db8740bb2..648b05bbe 100644 --- a/src/util.rs +++ b/src/util.rs @@ -6,11 +6,35 @@ use defines::{SparseFormat, BinaryOp, RandomEngineType}; use error::HANDLE_ERROR; use std::mem; use self::num::Complex; -use self::libc::{uint8_t, c_int, size_t}; +use self::libc::{uint8_t, c_int, size_t, c_void}; + +pub type AfArray = self::libc::c_longlong; +pub type CellPtr = *const self::libc::c_void; +pub type Complex32 = Complex; +pub type Complex64 = Complex; +pub type DimT = self::libc::c_longlong; +pub type Feat = *const self::libc::c_void; +pub type IndexT = self::libc::c_longlong; +pub type Intl = self::libc::c_longlong; +pub type MutAfArray = *mut self::libc::c_longlong; +pub type MutAfIndex = *mut self::libc::c_longlong; +pub type MutDimT = *mut self::libc::c_longlong; +pub type MutDouble = *mut self::libc::c_double; +pub type MutFeat = *mut *mut self::libc::c_void; +pub type MutRandEngine = *mut self::libc::c_longlong; +pub type MutUint = *mut self::libc::c_uint; +pub type MutVoidPtr = *mut self::libc::c_ulonglong; +pub type MutWndHandle = *mut self::libc::c_ulonglong; +pub type RandEngine = self::libc::c_longlong; +pub type Uintl = self::libc::c_ulonglong; +pub type WndHandle = self::libc::c_ulonglong; #[allow(dead_code)] extern { fn af_get_size_of(size: *mut size_t, aftype: uint8_t) -> c_int; + + fn af_alloc_host(ptr: *mut *const c_void, bytes: DimT) -> c_int; + fn af_free_host(ptr: *mut c_void) -> c_int; } /// Get size, in bytes, of the arrayfire native type @@ -23,6 +47,26 @@ pub fn get_size(value: DType) -> usize { } } +/// Allocates space using Arrayfire allocator in host memory +#[allow(dead_code)] +pub fn alloc_host(elements: usize, _type: DType) -> *const T { + let ptr: *const T = ::std::ptr::null(); + let bytes = (elements * get_size(_type)) as DimT; + unsafe { + let err_val = af_alloc_host(&mut (ptr as *const c_void), bytes); + HANDLE_ERROR(AfError::from(err_val)); + } + ptr +} + +/// Frees memory allocated by Arrayfire allocator in host memory +pub fn free_host(ptr: *mut T) { + unsafe { + let err_val = af_free_host(ptr as *mut c_void); + HANDLE_ERROR(AfError::from(err_val)); + } +} + impl From for AfError { fn from(t: i32) -> AfError { assert!(AfError::SUCCESS as i32 <= t && t <= AfError::ERR_UNKNOWN as i32); diff --git a/src/vision/mod.rs b/src/vision/mod.rs index ab88a6004..eb2a9daab 100644 --- a/src/vision/mod.rs +++ b/src/vision/mod.rs @@ -4,15 +4,9 @@ use std::mem; use array::Array; use defines::{AfError, HomographyType, MatchType}; use error::HANDLE_ERROR; -use util::HasAfEnum; +use util::{AfArray, DimT, Feat, HasAfEnum, MutAfArray, MutFeat}; use self::libc::{c_void, uint8_t, c_uint, c_int, c_float, c_double, c_longlong}; -type MutAfArray = *mut self::libc::c_longlong; -type AfArray = self::libc::c_longlong; -type DimT = self::libc::c_longlong; -type MutFeat = *mut *mut self::libc::c_void; -type Feat = *const self::libc::c_void; - // af_sift and af_gloh uses patented algorithms, so didn't add them // they are built using installer builds