From 2545bdfeb87cae53430934ba9770ee1fd54d0b91 Mon Sep 17 00:00:00 2001 From: pradeep Date: Wed, 8 Jul 2015 19:29:40 -0400 Subject: [PATCH 1/6] Changed code organization heirarchy * Each header in arrayfire has it's own module which reexported later for public exposed API * structs `Array`, `Dim4` has their own source files * `util` module has helper functions needed internally * Modified `constant` to be generic function --- Cargo.lock | 18 +++ Cargo.toml | 1 + src/algorithm/mod.rs | 36 ++++- src/arith/mod.rs | 42 +++++ src/array.rs | 125 +++++++++++++++ src/data/mod.rs | 189 ++++++++++++++++++++++ src/device/mod.rs | 17 ++ src/dim4.rs | 51 ++++++ src/lib.rs | 364 +++---------------------------------------- src/signal/mod.rs | 49 ++++++ src/util.rs | 32 ++++ tests/hello_world.rs | 4 + 12 files changed, 578 insertions(+), 350 deletions(-) create mode 100644 src/arith/mod.rs create mode 100644 src/array.rs create mode 100644 src/data/mod.rs create mode 100644 src/device/mod.rs create mode 100644 src/dim4.rs create mode 100644 src/signal/mod.rs create mode 100644 src/util.rs diff --git a/Cargo.lock b/Cargo.lock index 3b81b6769..ecda39e8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,6 +3,7 @@ name = "arrayfire" version = "3.0.0" dependencies = [ "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -11,6 +12,23 @@ name = "libc" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc-serialize" version = "0.3.15" diff --git a/Cargo.toml b/Cargo.toml index 3d6653afc..9232625ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ build = "build.rs" [dependencies] libc = "*" +num = "*" [build-dependencies.rustc-serialize] rustc-serialize = "*" diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs index 84793b0f5..587c1c4e3 100644 --- a/src/algorithm/mod.rs +++ b/src/algorithm/mod.rs @@ -1,12 +1,12 @@ extern crate libc; use super::Array as Array; -use libc::{c_int, c_uint, c_double}; +use self::libc::{c_int, c_uint}; -type MutAfArray = *mut ::libc::c_longlong; -type MutDouble = *mut ::libc::c_double; -type MutUint = *mut ::libc::c_uint; -type AfArray = ::libc::c_longlong; +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; #[allow(dead_code)] extern { @@ -94,6 +94,7 @@ pub fn sum(input: &Array, dim: i32) -> Array { // } //} +#[allow(unused_mut)] pub fn product(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -111,6 +112,7 @@ pub fn product(input: &Array, dim: i32) -> Array { // } //} +#[allow(unused_mut)] pub fn min(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -119,6 +121,7 @@ pub fn min(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn max(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -127,6 +130,7 @@ pub fn max(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn all_true(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -135,6 +139,7 @@ pub fn all_true(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn any_true(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -143,6 +148,7 @@ pub fn any_true(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn count(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -151,6 +157,7 @@ pub fn count(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn sum_all(input: &Array) -> (f64, f64) { unsafe { let mut real: f64 = 0.0; @@ -191,6 +198,7 @@ pub fn product_all(input: &Array) -> (f64, f64) { // } //} +#[allow(unused_mut)] pub fn min_all(input: &Array) -> (f64, f64) { unsafe { let mut real: f64 = 0.0; @@ -201,6 +209,7 @@ pub fn min_all(input: &Array) -> (f64, f64) { } } +#[allow(unused_mut)] pub fn max_all(input: &Array) -> (f64, f64) { unsafe { let mut real: f64 = 0.0; @@ -211,6 +220,7 @@ pub fn max_all(input: &Array) -> (f64, f64) { } } +#[allow(unused_mut)] pub fn all_true_all(input: &Array) -> (f64, f64) { unsafe { let mut real: f64 = 0.0; @@ -221,6 +231,7 @@ pub fn all_true_all(input: &Array) -> (f64, f64) { } } +#[allow(unused_mut)] pub fn any_true_all(input: &Array) -> (f64, f64) { unsafe { let mut real: f64 = 0.0; @@ -231,6 +242,7 @@ pub fn any_true_all(input: &Array) -> (f64, f64) { } } +#[allow(unused_mut)] pub fn count_all(input: &Array) -> (f64, f64) { unsafe { let mut real: f64 = 0.0; @@ -241,6 +253,7 @@ pub fn count_all(input: &Array) -> (f64, f64) { } } +#[allow(unused_mut)] pub fn imin(input: &Array, dim: i32) -> (Array, Array) { unsafe { let mut temp: i64 = 0; @@ -251,6 +264,7 @@ pub fn imin(input: &Array, dim: i32) -> (Array, Array) { } } +#[allow(unused_mut)] pub fn imax(input: &Array, dim: i32) -> (Array, Array) { unsafe { let mut temp: i64 = 0; @@ -261,6 +275,7 @@ pub fn imax(input: &Array, dim: i32) -> (Array, Array) { } } +#[allow(unused_mut)] pub fn imin_all(input: &Array) -> (f64, f64, u32) { unsafe { let mut real: f64 = 0.0; @@ -272,6 +287,7 @@ pub fn imin_all(input: &Array) -> (f64, f64, u32) { } } +#[allow(unused_mut)] pub fn imax_all(input: &Array) -> (f64, f64, u32) { unsafe { let mut real: f64 = 0.0; @@ -283,6 +299,7 @@ pub fn imax_all(input: &Array) -> (f64, f64, u32) { } } +#[allow(unused_mut)] pub fn accum(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -291,6 +308,7 @@ pub fn accum(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn locate(input: &Array) -> Array { unsafe { let mut temp: i64 = 0; @@ -299,6 +317,7 @@ pub fn locate(input: &Array) -> Array { } } +#[allow(unused_mut)] pub fn diff1(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -307,6 +326,7 @@ pub fn diff1(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn diff2(input: &Array, dim: i32) -> Array { unsafe { let mut temp: i64 = 0; @@ -315,6 +335,7 @@ pub fn diff2(input: &Array, dim: i32) -> Array { } } +#[allow(unused_mut)] pub fn sort(input: &Array, dim: u32, ascending: bool) -> Array { unsafe { let mut temp: i64 = 0; @@ -324,6 +345,7 @@ pub fn sort(input: &Array, dim: u32, ascending: bool) -> Array { } } +#[allow(unused_mut)] pub fn sort_index(input: &Array, dim: u32, ascending: bool) -> (Array, Array) { unsafe { let mut temp: i64 = 0; @@ -335,6 +357,7 @@ pub fn sort_index(input: &Array, dim: u32, ascending: bool) -> (Array, Array) { } } +#[allow(unused_mut)] pub fn sort_by_key(keys: &Array, vals: &Array, dim: u32, ascending: bool) -> (Array, Array) { unsafe { let mut temp: i64 = 0; @@ -346,6 +369,7 @@ pub fn sort_by_key(keys: &Array, vals: &Array, dim: u32, ascending: bool) -> (Ar } } +#[allow(unused_mut)] pub fn set_unique(input: &Array, is_sorted: bool) -> Array { unsafe { let mut temp: i64 = 0; @@ -354,6 +378,7 @@ pub fn set_unique(input: &Array, is_sorted: bool) -> Array { } } +#[allow(unused_mut)] pub fn set_union(first: &Array, second: &Array, is_unique: bool) -> Array { unsafe { let mut temp: i64 = 0; @@ -363,6 +388,7 @@ pub fn set_union(first: &Array, second: &Array, is_unique: bool) -> Array { } } +#[allow(unused_mut)] pub fn set_intersect(first: &Array, second: &Array, is_unique: bool) -> Array { unsafe { let mut temp: i64 = 0; diff --git a/src/arith/mod.rs b/src/arith/mod.rs new file mode 100644 index 000000000..9e7864e29 --- /dev/null +++ b/src/arith/mod.rs @@ -0,0 +1,42 @@ +extern crate libc; + +use super::Array as Array; +use self::libc::{c_int}; +use data::constant; + +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; + +#[allow(dead_code)] +extern { + fn af_add(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + + fn af_sin(out: MutAfArray, arr: AfArray) -> c_int; + +} + +impl Add for Array { + type Output = Array; + + fn add(self, rhs: f64) -> Array { + let cnst_arr = constant(rhs, self.dims()); + unsafe { + let mut temp: i64 = 0; + af_add(&mut temp as MutAfArray, self.get() as AfArray, cnst_arr.get() as AfArray, 0); + Array {handle: temp} + } + } +} + +#[allow(unused_mut)] +pub fn sin(input: &Array) -> Array { + unsafe { + let mut temp: i64 = 0; + af_sin(&mut temp as MutAfArray, input.get() as AfArray); + Array {handle: temp} + } +} diff --git a/src/array.rs b/src/array.rs new file mode 100644 index 000000000..4707022d5 --- /dev/null +++ b/src/array.rs @@ -0,0 +1,125 @@ +extern crate libc; + +use super::Array as Array; +use super::Dim4 as Dim4; +use super::Aftype as Aftype; +use util::get_ffi_type; +use util::get_af_type; +use self::libc::{c_void, c_int, c_uint, c_longlong}; + +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; + +#[allow(dead_code)] +extern { + fn af_create_array(out: MutAfArray, data: *const c_void, + ndims: c_uint, dims: *const DimT, aftype: c_int) -> c_int; + + fn af_get_elements(out: MutAfArray, arr: AfArray) -> c_int; + + fn af_get_type(out: *mut c_int, arr: AfArray) -> c_int; + + fn af_get_dims(dim0: *mut c_longlong, dim1: *mut c_longlong, dim2: *mut c_longlong, + dim3: *mut c_longlong, arr: AfArray) -> c_int; + + fn af_get_numdims(result: *mut c_uint, arr: AfArray) -> c_int; + + fn af_get_data_ptr(data: *mut c_void, arr: AfArray) -> c_int; + + fn af_eval(arr: AfArray) -> c_int; + + fn af_release_array(arr: AfArray) -> c_int; + + fn af_print_array(arr: AfArray) -> c_int; +} + +impl Array { + #[allow(unused_mut)] + pub fn new(dims: Dim4, slice: &[T], aftype: Aftype) -> Array { + unsafe { + let mut temp: i64 = 0; + af_create_array(&mut temp as *mut c_longlong, + slice.as_ptr() as *const c_void, + dims.ndims() as c_uint, + dims.get().as_ptr() as * const c_longlong, + get_ffi_type(aftype.clone()) as c_int); + Array { handle: temp } + } + } + + pub fn elements(&self) -> i64 { + unsafe { + let mut ret_val: i64 = 0; + af_get_elements(&mut ret_val as *mut c_longlong, + self.handle as c_longlong); + ret_val + } + } + + pub fn get_type(&self) -> Aftype { + unsafe { + let mut ret_val: i32 = 0; + af_get_type(&mut ret_val as *mut c_int, + self.handle as c_longlong); + get_af_type(ret_val) + } + } + + pub fn dims(&self) -> Dim4 { + unsafe { + let mut ret0: i64 = 0; + let mut ret1: i64 = 0; + let mut ret2: i64 = 0; + let mut ret3: i64 = 0; + af_get_dims(&mut ret0 as *mut c_longlong, + &mut ret1 as *mut c_longlong, + &mut ret2 as *mut c_longlong, + &mut ret3 as *mut c_longlong, + self.handle as c_longlong); + Dim4 { dims: [ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64] } + } + } + + pub fn numdims(&self) -> u32 { + unsafe { + let mut ret_val: u32 = 0; + af_get_numdims(&mut ret_val as *mut c_uint, + self.handle as c_longlong); + ret_val + } + } + + pub fn get(&self) -> i64 { + self.handle + } + + pub fn host(&self, data:&mut [f64]) { + unsafe { + af_get_data_ptr(data.as_mut_ptr() as *mut c_void, + self.handle as c_longlong); + } + } + + pub fn eval(&self) { + unsafe { + af_eval(self.handle as c_longlong); + } + } +} + +impl Drop for Array { + fn drop(&mut self) { + unsafe { + af_release_array(self.handle); + } + } +} + +pub fn print(input: &Array) { + unsafe { + af_print_array(input.get() as c_longlong); + } +} diff --git a/src/data/mod.rs b/src/data/mod.rs new file mode 100644 index 000000000..c572c2098 --- /dev/null +++ b/src/data/mod.rs @@ -0,0 +1,189 @@ +extern crate libc; +extern crate num; + +use super::Array as Array; +use super::Dim4 as Dim4; +use super::Aftype as Aftype; +use util::get_ffi_type; +use self::libc::{c_int, c_uint, c_double}; +use self::num::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; +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, + ndims: c_uint, dims: *const DimT, afdtype: c_int) -> c_int; + + fn af_constant_complex(out: MutAfArray, real: c_double, imag: c_double, + ndims: c_uint, dims: *const DimT, afdtype: c_int) -> c_int; + + fn af_constant_long(out: MutAfArray, val: Intl, + ndims: c_uint, dims: *const DimT) -> c_int; + + fn af_constant_ulong(out: MutAfArray, val: Uintl, + ndims: c_uint, dims: *const DimT) -> c_int; + + fn af_range(out: MutAfArray, ndims: c_uint, dims: *const DimT, + seq_dims: c_int, afdtype: c_int) -> c_int; + + fn af_iota(out: MutAfArray, ndims: c_uint, dims: *const DimT, + t_ndims: c_uint, tdims: *const DimT, afdtype: c_int) -> c_int; + + fn af_randu(out: MutAfArray, ndims: c_uint, dims: *const DimT, afdtype: c_int) -> c_int; + + fn af_randn(out: MutAfArray, ndims: c_uint, dims: *const DimT, afdtype: c_int) -> c_int; + + fn af_set_seed(seed: Uintl); + + fn af_get_seed(seed: *mut Uintl); + +} + +pub trait ConstGenerator { + fn generate(&self, dims: Dim4) -> Array; +} + +#[allow(unused_mut)] +impl ConstGenerator for i64 { + fn generate(&self, dims: Dim4) -> Array { + unsafe { + let mut temp: i64 = 0; + af_constant_long(&mut temp as MutAfArray, *self as Intl, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT); + Array {handle: temp} + } + } +} + +#[allow(unused_mut)] +impl ConstGenerator for u64 { + fn generate(&self, dims: Dim4) -> Array { + unsafe { + let mut temp: i64 = 0; + af_constant_ulong(&mut temp as MutAfArray, *self as Uintl, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT); + Array {handle: temp} + } + } +} + +#[allow(unused_mut)] +impl ConstGenerator for Complex { + fn generate(&self, dims: Dim4) -> Array { + unsafe { + let mut temp: i64 = 0; + af_constant_complex(&mut temp as MutAfArray, + (*self).re as c_double, (*self).im as c_double, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, 1); + Array {handle: temp} + } + } +} + +#[allow(unused_mut)] +impl ConstGenerator for Complex { + fn generate(&self, dims: Dim4) -> Array { + unsafe { + let mut temp: i64 = 0; + af_constant_complex(&mut temp as MutAfArray, + (*self).re as c_double, (*self).im as c_double, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, 3); + Array {handle: temp} + } + } +} + +macro_rules! cnst { + ($rust_type:ty, $ffi_type:expr) => ( + #[allow(unused_mut)] + impl ConstGenerator for $rust_type { + fn generate(&self, dims: Dim4) -> Array { + unsafe { + let mut temp: i64 = 0; + af_constant(&mut temp as MutAfArray, *self as c_double, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, + $ffi_type); + Array {handle: temp} + } + } + } + ) +} + +cnst!(f32 , 0); +cnst!(f64 , 2); +cnst!(bool, 4); +cnst!(i32 , 5); +cnst!(u32 , 6); +cnst!(u8 , 7); + + +pub fn constant(cnst: T, dims: Dim4) -> Array { + cnst.generate(dims) +} + +#[allow(unused_mut)] +pub fn range(dims: Dim4, seq_dim: i32, aftype: Aftype) -> Array { + unsafe { + let mut temp: i64 = 0; + af_range(&mut temp as MutAfArray, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, + seq_dim as c_int, + get_ffi_type(aftype.clone()) as c_int); + Array {handle: temp} + } +} + +#[allow(unused_mut)] +pub fn iota(dims: Dim4, tdims: Dim4, aftype: Aftype) -> Array { + unsafe { + let mut temp: i64 = 0; + af_iota(&mut temp as MutAfArray, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, + tdims.ndims() as c_uint, tdims.get().as_ptr() as *const DimT, + get_ffi_type(aftype.clone()) as c_int); + Array {handle: temp} + } +} + +pub fn set_seed(seed: u64) { + unsafe { af_set_seed(seed as Uintl); } +} + +#[allow(unused_mut)] +pub fn get_seed() -> u64 { + unsafe { + let mut temp: u64 = 0; + af_get_seed(&mut temp as *mut Uintl); + temp + } +} + +#[allow(unused_mut)] +pub fn randu(dims: Dim4, aftype: Aftype) -> Array { + unsafe { + let mut temp: i64 = 0; + af_randu(&mut temp as MutAfArray, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, + get_ffi_type(aftype.clone()) as c_int); + Array {handle: temp} + } +} + +#[allow(unused_mut)] +pub fn randn(dims: Dim4, aftype: Aftype) -> Array { + unsafe { + let mut temp: i64 = 0; + af_randn(&mut temp as MutAfArray, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, + get_ffi_type(aftype.clone()) as c_int); + Array {handle: temp} + } +} diff --git a/src/device/mod.rs b/src/device/mod.rs new file mode 100644 index 000000000..880c1f4f0 --- /dev/null +++ b/src/device/mod.rs @@ -0,0 +1,17 @@ +extern crate libc; + +use self::libc::c_int; + +extern { + fn af_info() -> c_int; + + fn af_set_device(device: c_int) -> c_int; +} + +pub fn info() { + unsafe { af_info(); } +} + +pub fn set_device(device: i32) { + unsafe { af_set_device(device as c_int); } +} diff --git a/src/dim4.rs b/src/dim4.rs new file mode 100644 index 000000000..4ad54ef6a --- /dev/null +++ b/src/dim4.rs @@ -0,0 +1,51 @@ +use super::Dim4 as Dim4; +use std::fmt; +use std::ops::Index; + +impl Default for Dim4 { + fn default() -> Dim4 { + Dim4 { dims:[1, 1, 1, 1] } + } +} + +impl Index for Dim4 { + type Output = u64; + + fn index<'a>(&'a self, _index: usize) ->&'a u64 { + &self.dims[_index] + } +} + +impl fmt::Display for Dim4 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "[{} {} {} {}]", self.dims[0], self.dims[1], self.dims[2], self.dims[3]) + } +} + +impl Dim4 { + pub fn new(dims: &[u64; 4]) -> Dim4 { + Dim4 { dims: dims.clone(), } + } + + pub fn elements(&self) -> u64 { + self.dims[0]*self.dims[1]*self.dims[2]*self.dims[3] + } + + pub fn ndims(&self) -> usize { + let nelems = self.elements(); + match nelems { + 0 => 0, + 1 => 0, + _ => { + if self.dims[3] != 1 { 4 } + else if self.dims[2] != 1 { 3 } + else if self.dims[1] != 1 { 2 } + else { 1 } + }, + } + } + + pub fn get(&self) -> &[u64; 4] { + &self.dims + } +} diff --git a/src/lib.rs b/src/lib.rs index 54f322d83..72db09020 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,84 +1,3 @@ -extern crate libc; - -use libc::{c_void, c_int, c_uint, c_double, c_longlong}; - -use std::fmt; -use std::ops::Index; -use std::ops::Add; - -extern { - fn af_set_device(device: c_int) -> c_int; - - fn af_info() -> c_int; - - fn af_create_array(out: *mut c_longlong, - data: *const c_void, - ndims: c_uint, - dims: *const c_longlong, - af_type: c_int) -> c_int; - - fn af_get_elements(out: *mut c_longlong, - arr: c_longlong) -> c_int; - - fn af_get_type(out: *mut c_int, - arr: c_longlong) -> c_int; - - fn af_get_dims(dim0: *mut c_longlong, - dim1: *mut c_longlong, - dim2: *mut c_longlong, - dim3: *mut c_longlong, - arr: c_longlong) -> c_int; - - fn af_get_numdims(result: *mut c_uint, - arr: c_longlong) -> c_int; - - fn af_get_data_ptr(data: *mut c_void, - arr: c_longlong) -> c_int; - - fn af_eval(arr: c_longlong) -> c_int; - - fn af_release_array(arr: c_longlong) -> c_int; - - fn af_print_array(arr: c_longlong) -> c_int; - - fn af_constant(out: *mut c_longlong, - cnst: c_double, - ndims: c_uint, - dims: *const c_longlong, - af_type: c_int) -> c_int; - - fn af_randu(out: *mut c_longlong, - ndims: c_uint, - dims: *const c_longlong, - af_type: c_int) -> c_int; - - fn af_add(out: *mut c_longlong, - lhs: c_longlong, - rhs: c_longlong, - batch: c_int) -> c_int; - - fn af_sin(out: *mut c_longlong, - arr: c_longlong) -> c_int; - - fn af_fft(out: *mut c_longlong, - arr: c_longlong, - nfac: c_double, - odim0: c_longlong) -> c_int; - - fn af_fft2(out: *mut c_longlong, - arr: c_longlong, - nfac: c_double, - odim0: c_longlong, - odim1: c_longlong) -> c_int; - - fn af_fft3(out: *mut c_longlong, - arr: c_longlong, - nfac: c_double, - odim0: c_longlong, - odim1: c_longlong, - odim2: c_longlong) -> c_int; -} - #[derive(Clone)] pub enum Aftype { F32, @@ -93,282 +12,24 @@ pub enum Aftype { U64, } -fn get_ffi_type(t: Aftype) -> i32 { - match t { - Aftype::F32 => 0, - Aftype::C32 => 1, - Aftype::F64 => 2, - Aftype::C64 => 3, - Aftype::B8 => 4, - Aftype::S32 => 5, - Aftype::U32 => 6, - Aftype::U8 => 7, - Aftype::S64 => 8, - Aftype::U64 => 9, - } -} - -fn get_af_type(t: i32) -> Aftype { - match t { - 0 => Aftype::F32, - 1 => Aftype::C32, - 2 => Aftype::F64, - 3 => Aftype::C64, - 4 => Aftype::B8 , - 5 => Aftype::S32, - 6 => Aftype::U32, - 7 => Aftype::U8 , - 8 => Aftype::S64, - 9 => Aftype::U64, - _ => Aftype::F32, - } -} - #[derive(Clone)] pub struct Dim4 { dims: [u64; 4], } -impl Default for Dim4 { - fn default() -> Dim4 { - Dim4 { dims:[1, 1, 1, 1] } - } -} - -impl Index for Dim4 { - type Output = u64; - - fn index<'a>(&'a self, _index: usize) ->&'a u64 { - &self.dims[_index] - } -} - -impl fmt::Display for Dim4 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "[{} {} {} {}]", self.dims[0], self.dims[1], self.dims[2], self.dims[3]) - } -} - -impl Dim4 { - pub fn new(dims: &[u64; 4]) -> Dim4 { - Dim4 { dims: dims.clone(), } - } - - pub fn elements(&self) -> u64 { - self.dims[0]*self.dims[1]*self.dims[2]*self.dims[3] - } - - pub fn ndims(&self) -> usize { - let nelems = self.elements(); - match nelems { - 0 => 0, - 1 => 0, - _ => { - if self.dims[3] != 1 { 4 } - else if self.dims[2] != 1 { 3 } - else if self.dims[1] != 1 { 2 } - else { 1 } - }, - } - } - - pub fn get(&self) -> &[u64; 4] { - &self.dims - } -} - pub struct Array { handle: i64, } -impl Array { - #[allow(unused_mut)] - pub fn new(dims: Dim4, slice: &[T], aftype: Aftype) -> Array { - unsafe { - let mut temp: i64 = 0; - af_create_array(&mut temp as *mut c_longlong, - slice.as_ptr() as *const c_void, - dims.ndims() as c_uint, - dims.get().as_ptr() as * const c_longlong, - get_ffi_type(aftype.clone()) as c_int); - Array { handle: temp } - } - } - - pub fn elements(&self) -> i64 { - unsafe { - let mut ret_val: i64 = 0; - af_get_elements(&mut ret_val as *mut c_longlong, - self.handle as c_longlong); - ret_val - } - } - - pub fn get_type(&self) -> Aftype { - unsafe { - let mut ret_val: i32 = 0; - af_get_type(&mut ret_val as *mut c_int, - self.handle as c_longlong); - get_af_type(ret_val) - } - } - - pub fn dims(&self) -> Dim4 { - unsafe { - let mut ret0: i64 = 0; - let mut ret1: i64 = 0; - let mut ret2: i64 = 0; - let mut ret3: i64 = 0; - af_get_dims(&mut ret0 as *mut c_longlong, - &mut ret1 as *mut c_longlong, - &mut ret2 as *mut c_longlong, - &mut ret3 as *mut c_longlong, - self.handle as c_longlong); - Dim4 { dims: [ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64] } - } - } - - pub fn numdims(&self) -> u32 { - unsafe { - let mut ret_val: u32 = 0; - af_get_numdims(&mut ret_val as *mut c_uint, - self.handle as c_longlong); - ret_val - } - } - - pub fn get(&self) -> i64 { - self.handle - } - - pub fn host(&self, data:&mut [f64]) { - unsafe { - af_get_data_ptr(data.as_mut_ptr() as *mut c_void, - self.handle as c_longlong); - } - } - - pub fn eval(&self) { - unsafe { - af_eval(self.handle as c_longlong); - } - } -} - -impl Drop for Array { - fn drop(&mut self) { - unsafe { - af_release_array(self.handle); - } - } -} - -impl Add for Array { - type Output = Array; - - fn add(self, rhs: f64) -> Array { - let cnst_arr = constant(rhs, self.dims(), self.get_type().clone()); - unsafe { - let mut temp: i64 = 0; - af_add(&mut temp as *mut c_longlong, - self.get() as c_longlong, - cnst_arr.get() as c_longlong, - 0); - Array { handle: temp } - } - } -} - -pub fn set_device(device: i32) { - unsafe { - af_set_device(device as c_int); - } -} +pub use array::{print}; +mod array; -pub fn info() { - unsafe { - af_info(); - } -} +mod dim4; -pub fn print(input: &Array) { - unsafe { - af_print_array(input.get() as c_longlong); - } -} +mod util; -#[allow(unused_mut)] -pub fn randu(dims: Dim4, aftype: Aftype) -> Array { - unsafe { - let mut temp: i64 = 0; - af_randu(&mut temp as *mut c_longlong, - dims.ndims() as c_uint, - dims.get().as_ptr() as * const c_longlong, - get_ffi_type(aftype.clone()) as c_int); - Array { handle: temp } - } -} - -#[allow(unused_mut)] -pub fn constant(cnst: f64, dims: Dim4, aftype: Aftype) -> Array { - unsafe { - let mut temp: i64 = 0; - af_constant(&mut temp as *mut c_longlong, - cnst as c_double, - dims.ndims() as c_uint, - dims.get().as_ptr() as * const c_longlong, - get_ffi_type(aftype.clone()) as c_int); - Array { handle: temp } - } -} - -#[allow(unused_mut)] -pub fn sin(input: &Array) -> Array { - unsafe { - let mut temp: i64 = 0; - af_sin(&mut temp as *mut c_longlong, input.get() as c_longlong); - Array { handle: temp } - } -} - -#[allow(unused_mut)] -pub fn fft(input: &Array, norm_factor: f64, odim0: i64) -> Array { - unsafe { - let mut temp: i64 = 0; - af_fft(&mut temp as *mut c_longlong, - input.get() as c_longlong, - norm_factor as c_double, - odim0 as c_longlong); - Array { handle: temp } - } -} - -#[allow(unused_mut)] -pub fn fft2(input: &Array, norm_factor: f64, odim0: i64, odim1: i64) -> Array { - unsafe { - let mut temp: i64 = 0; - af_fft2(&mut temp as *mut c_longlong, - input.get() as c_longlong, - norm_factor as c_double, - odim0 as c_longlong, - odim1 as c_longlong); - Array { handle: temp } - } -} - -#[allow(unused_mut)] -pub fn fft3(input: &Array, norm_factor: f64, odim0: i64, odim1: i64, odim2: i64) -> Array { - unsafe { - let mut temp: i64 = 0; - af_fft3(&mut temp as *mut c_longlong, - input.get() as c_longlong, - norm_factor as c_double, - odim0 as c_longlong, - odim1 as c_longlong, - odim2 as c_longlong); - Array { handle: temp } - } -} +pub use device::{info, set_device}; +mod device; //pub use algorithm::{sum_nan, product_nan, sum_nan_all, product_nan_all}; pub use algorithm::{sum, product, min, max, all_true, any_true, count}; @@ -377,3 +38,16 @@ pub use algorithm::{all_true_all, any_true_all, count_all, imin, imax, imin_all, pub use algorithm::{accum, locate, diff1, diff2, sort, sort_index, sort_by_key}; pub use algorithm::{set_unique, set_union, set_intersect}; mod algorithm; + +pub use arith::{sin}; +mod arith; + +pub use data::{constant, range, iota}; +pub use data::{set_seed, get_seed, randu, randn}; +//pub use data::{identity, diag_create, diag_extract, lower, upper}; +//pub use data::{join, join_many, tile}; +//pub use data::{reorder, shift, moddims, flat, flip}; +mod data; + +pub use signal::{fft, fft2, fft3}; +mod signal; diff --git a/src/signal/mod.rs b/src/signal/mod.rs new file mode 100644 index 000000000..e2ed13d0d --- /dev/null +++ b/src/signal/mod.rs @@ -0,0 +1,49 @@ +extern crate libc; + +use super::Array as Array; +use self::libc::{c_int, c_double, c_longlong}; + +type MutAfArray = *mut self::libc::c_longlong; +type AfArray = self::libc::c_longlong; + +#[allow(dead_code)] +extern { + fn af_fft(out: MutAfArray, arr: AfArray, + nfac: c_double, odim0: c_longlong) -> c_int; + + fn af_fft2(out: MutAfArray, arr: AfArray, nfac: c_double, + odim0: c_longlong, odim1: c_longlong) -> c_int; + + fn af_fft3(out: MutAfArray, arr: AfArray, nfac: c_double, + odim0: c_longlong, odim1: c_longlong, odim2: c_longlong) -> c_int; +} + +#[allow(unused_mut)] +pub fn fft(input: &Array, norm_factor: f64, odim0: i64) -> Array { + unsafe { + let mut temp: i64 = 0; + af_fft(&mut temp as MutAfArray, input.get() as AfArray, + norm_factor as c_double, odim0 as c_longlong); + Array {handle: temp} + } +} + +#[allow(unused_mut)] +pub fn fft2(input: &Array, norm_factor: f64, odim0: i64, odim1: i64) -> Array { + unsafe { + let mut temp: i64 = 0; + af_fft2(&mut temp as MutAfArray, input.get() as AfArray, + norm_factor as c_double, odim0 as c_longlong, odim1 as c_longlong); + Array {handle: temp} + } +} + +#[allow(unused_mut)] +pub fn fft3(input: &Array, norm_factor: f64, odim0: i64, odim1: i64, odim2: i64) -> Array { + unsafe { + let mut temp: i64 = 0; + af_fft3(&mut temp as MutAfArray, input.get() as AfArray, norm_factor as c_double, + odim0 as c_longlong, odim1 as c_longlong, odim2 as c_longlong); + Array {handle: temp} + } +} diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 000000000..4d64501bc --- /dev/null +++ b/src/util.rs @@ -0,0 +1,32 @@ +use super::Aftype as Aftype; + +pub fn get_ffi_type(t: Aftype) -> i32 { + match t { + Aftype::F32 => 0, + Aftype::C32 => 1, + Aftype::F64 => 2, + Aftype::C64 => 3, + Aftype::B8 => 4, + Aftype::S32 => 5, + Aftype::U32 => 6, + Aftype::U8 => 7, + Aftype::S64 => 8, + Aftype::U64 => 9, + } +} + +pub fn get_af_type(t: i32) -> Aftype { + match t { + 0 => Aftype::F32, + 1 => Aftype::C32, + 2 => Aftype::F64, + 3 => Aftype::C64, + 4 => Aftype::B8 , + 5 => Aftype::S32, + 6 => Aftype::U32, + 7 => Aftype::U8 , + 8 => Aftype::S64, + 9 => Aftype::U64, + _ => Aftype::F32, + } +} diff --git a/tests/hello_world.rs b/tests/hello_world.rs index 7c71be940..120df48f4 100644 --- a/tests/hello_world.rs +++ b/tests/hello_world.rs @@ -46,4 +46,8 @@ fn main() { let (vals, inds) = af::sort_index(&a, 0, true); af::print(&vals); af::print(&inds); + + println!("u8 constant array"); + let u8_cnst = af::constant(1 as u8, Dim4::new(&[4,4,1,1])); + af::print(&u8_cnst); } From 0fc739b563f9213a5115457e45340d8ae5559997 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 9 Jul 2015 01:35:01 -0400 Subject: [PATCH 2/6] API for util header from arrayfire Also, implemented `Copy` trait for `Aftype` and `Dim4` structs. --- src/array.rs | 85 +++++++++++++++++++++++++++++++++----------- src/data/mod.rs | 8 ++--- src/device/mod.rs | 12 +++++++ src/lib.rs | 6 ++-- tests/hello_world.rs | 3 +- 5 files changed, 85 insertions(+), 29 deletions(-) diff --git a/src/array.rs b/src/array.rs index 4707022d5..29e43211c 100644 --- a/src/array.rs +++ b/src/array.rs @@ -27,6 +27,32 @@ extern { fn af_get_numdims(result: *mut c_uint, arr: AfArray) -> c_int; + fn af_is_empty(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_scalar(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_row(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_column(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_vector(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_complex(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_real(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_double(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_single(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_realfloating(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_floating(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_integer(result: *mut c_int, arr: AfArray) -> c_int; + + fn af_is_bool(result: *mut c_int, arr: AfArray) -> c_int; + fn af_get_data_ptr(data: *mut c_void, arr: AfArray) -> c_int; fn af_eval(arr: AfArray) -> c_int; @@ -36,25 +62,34 @@ extern { fn af_print_array(arr: AfArray) -> c_int; } +macro_rules! is_func { + ($fn_name: ident, $ffi_fn: ident) => ( + pub fn $fn_name(&self) -> bool { + unsafe { + let mut ret_val: i32 = 0; + $ffi_fn(&mut ret_val as *mut c_int, self.handle as AfArray); + ret_val > 0 + } + } + ) +} + impl Array { #[allow(unused_mut)] pub fn new(dims: Dim4, slice: &[T], aftype: Aftype) -> Array { unsafe { let mut temp: i64 = 0; - af_create_array(&mut temp as *mut c_longlong, - slice.as_ptr() as *const c_void, - dims.ndims() as c_uint, - dims.get().as_ptr() as * const c_longlong, - get_ffi_type(aftype.clone()) as c_int); - Array { handle: temp } + af_create_array(&mut temp as MutAfArray, slice.as_ptr() as *const c_void, + dims.ndims() as c_uint, dims.get().as_ptr() as * const c_longlong, + get_ffi_type(aftype) as c_int); + Array {handle: temp} } } pub fn elements(&self) -> i64 { unsafe { let mut ret_val: i64 = 0; - af_get_elements(&mut ret_val as *mut c_longlong, - self.handle as c_longlong); + af_get_elements(&mut ret_val as MutAfArray, self.handle as AfArray); ret_val } } @@ -62,8 +97,7 @@ impl Array { pub fn get_type(&self) -> Aftype { unsafe { let mut ret_val: i32 = 0; - af_get_type(&mut ret_val as *mut c_int, - self.handle as c_longlong); + af_get_type(&mut ret_val as *mut c_int, self.handle as AfArray); get_af_type(ret_val) } } @@ -74,20 +108,17 @@ impl Array { let mut ret1: i64 = 0; let mut ret2: i64 = 0; let mut ret3: i64 = 0; - af_get_dims(&mut ret0 as *mut c_longlong, - &mut ret1 as *mut c_longlong, - &mut ret2 as *mut c_longlong, - &mut ret3 as *mut c_longlong, - self.handle as c_longlong); - Dim4 { dims: [ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64] } + af_get_dims(&mut ret0 as *mut c_longlong, &mut ret1 as *mut c_longlong, + &mut ret2 as *mut c_longlong, &mut ret3 as *mut c_longlong, + self.handle as AfArray); + Dim4 {dims: [ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64]} } } pub fn numdims(&self) -> u32 { unsafe { let mut ret_val: u32 = 0; - af_get_numdims(&mut ret_val as *mut c_uint, - self.handle as c_longlong); + af_get_numdims(&mut ret_val as *mut c_uint, self.handle as AfArray); ret_val } } @@ -98,16 +129,28 @@ impl Array { pub fn host(&self, data:&mut [f64]) { unsafe { - af_get_data_ptr(data.as_mut_ptr() as *mut c_void, - self.handle as c_longlong); + af_get_data_ptr(data.as_mut_ptr() as *mut c_void, self.handle as AfArray); } } pub fn eval(&self) { unsafe { - af_eval(self.handle as c_longlong); + af_eval(self.handle as AfArray); } } + + is_func!(is_empty, af_is_empty); + is_func!(is_scalar, af_is_scalar); + is_func!(is_row, af_is_row); + is_func!(is_column, af_is_column); + is_func!(is_vector, af_is_vector); + is_func!(is_complex, af_is_complex); + is_func!(is_double, af_is_double); + is_func!(is_single, af_is_single); + is_func!(is_real, af_is_real); + is_func!(is_floating, af_is_floating); + is_func!(is_integer, af_is_integer); + is_func!(is_bool, af_is_bool); } impl Drop for Array { diff --git a/src/data/mod.rs b/src/data/mod.rs index c572c2098..7a72c63b2 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -136,7 +136,7 @@ pub fn range(dims: Dim4, seq_dim: i32, aftype: Aftype) -> Array { af_range(&mut temp as MutAfArray, dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, seq_dim as c_int, - get_ffi_type(aftype.clone()) as c_int); + get_ffi_type(aftype) as c_int); Array {handle: temp} } } @@ -148,7 +148,7 @@ pub fn iota(dims: Dim4, tdims: Dim4, aftype: Aftype) -> Array { af_iota(&mut temp as MutAfArray, dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, tdims.ndims() as c_uint, tdims.get().as_ptr() as *const DimT, - get_ffi_type(aftype.clone()) as c_int); + get_ffi_type(aftype) as c_int); Array {handle: temp} } } @@ -172,7 +172,7 @@ pub fn randu(dims: Dim4, aftype: Aftype) -> Array { let mut temp: i64 = 0; af_randu(&mut temp as MutAfArray, dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, - get_ffi_type(aftype.clone()) as c_int); + get_ffi_type(aftype) as c_int); Array {handle: temp} } } @@ -183,7 +183,7 @@ pub fn randn(dims: Dim4, aftype: Aftype) -> Array { let mut temp: i64 = 0; af_randn(&mut temp as MutAfArray, dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, - get_ffi_type(aftype.clone()) as c_int); + get_ffi_type(aftype) as c_int); Array {handle: temp} } } diff --git a/src/device/mod.rs b/src/device/mod.rs index 880c1f4f0..ad75a35c6 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -3,11 +3,23 @@ extern crate libc; use self::libc::c_int; extern { + fn af_get_version(major: *mut c_int, minor: *mut c_int, patch: *mut c_int) -> c_int; + fn af_info() -> c_int; fn af_set_device(device: c_int) -> c_int; } +pub fn get_version() -> (i32, i32, i32) { + unsafe { + let mut maj: i32 = 0; + let mut min: i32 = 0; + let mut pat: i32 = 0; + af_get_version(&mut maj as *mut c_int, &mut min as *mut c_int, &mut pat as *mut c_int); + (maj, min, pat) + } +} + pub fn info() { unsafe { af_info(); } } diff --git a/src/lib.rs b/src/lib.rs index 72db09020..916eb81ef 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#[derive(Clone)] +#[derive(Copy, Clone)] pub enum Aftype { F32, C32, @@ -12,7 +12,7 @@ pub enum Aftype { U64, } -#[derive(Clone)] +#[derive(Copy, Clone)] pub struct Dim4 { dims: [u64; 4], } @@ -28,7 +28,7 @@ mod dim4; mod util; -pub use device::{info, set_device}; +pub use device::{get_version, info, set_device}; mod device; //pub use algorithm::{sum_nan, product_nan, sum_nan_all, product_nan_all}; diff --git a/tests/hello_world.rs b/tests/hello_world.rs index 120df48f4..152443d1d 100644 --- a/tests/hello_world.rs +++ b/tests/hello_world.rs @@ -48,6 +48,7 @@ fn main() { af::print(&inds); println!("u8 constant array"); - let u8_cnst = af::constant(1 as u8, Dim4::new(&[4,4,1,1])); + let u8_cnst = af::constant(1 as u8, dims); af::print(&u8_cnst); + println!("Is u8_cnst array float precision type ? {}", u8_cnst.is_single()); } From b8b8f0b891ff8b1ff4e016912e41683e7a7354dc Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 9 Jul 2015 04:12:20 -0400 Subject: [PATCH 3/6] API for arith header from ArrayFire --- src/algorithm/mod.rs | 36 +------ src/arith/mod.rs | 238 ++++++++++++++++++++++++++++++++++++++++--- src/data/mod.rs | 2 - src/lib.rs | 7 +- 4 files changed, 235 insertions(+), 48 deletions(-) diff --git a/src/algorithm/mod.rs b/src/algorithm/mod.rs index 587c1c4e3..5a8291969 100644 --- a/src/algorithm/mod.rs +++ b/src/algorithm/mod.rs @@ -11,69 +11,39 @@ type AfArray = self::libc::c_longlong; #[allow(dead_code)] extern { fn af_sum(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - //fn af_sum_nan(out: MutAfArray, input: AfArray, dim: c_int, nanval: c_double) -> c_int; - fn af_product(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - //fn af_product_nan(out: MutAfArray, input: AfArray, dim: c_int, val: c_double) -> c_int; - fn af_min(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_max(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_all_true(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_any_true(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_count(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_sum_all(r: MutDouble, i: MutDouble, input: AfArray) -> c_int; - //fn af_sum_nan_all(r: MutDouble, i: MutDouble, input: AfArray, val: c_double) -> c_int; - fn af_product_all(r: MutDouble, i: MutDouble, input: AfArray) -> c_int; - //fn af_product_nan_all(r: MutDouble, i: MutDouble, input: AfArray, val: c_double) -> c_int; - fn af_min_all(r: MutDouble, i: MutDouble, input: AfArray) -> c_int; - fn af_max_all(r: MutDouble, i: MutDouble, input: AfArray) -> c_int; - fn af_all_true_all(r: MutDouble, i: MutDouble, input: AfArray) -> c_int; - fn af_any_true_all(r: MutDouble, i: MutDouble, input: AfArray) -> c_int; - fn af_count_all(r: MutDouble, i: MutDouble, input: AfArray) -> c_int; - fn af_imin(out: MutAfArray, idx: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_imax(out: MutAfArray, idx: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_imin_all(r: MutDouble, i: MutDouble, idx: MutUint, input: AfArray) -> c_int; - fn af_imax_all(r: MutDouble, i: MutDouble, idx: MutUint, input: AfArray) -> c_int; - fn af_accum(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_where(out: MutAfArray, input: AfArray) -> c_int; - fn af_diff1(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_diff2(out: MutAfArray, input: AfArray, dim: c_int) -> c_int; - fn af_sort(out: MutAfArray, input: AfArray, dim: c_uint, ascend: c_int) -> c_int; - fn af_sort_index(o: MutAfArray, i: MutAfArray, inp: AfArray, d: c_uint, a: c_int) -> c_int; - - fn af_sort_by_key(out_keys: MutAfArray, out_vals: MutAfArray, - in_keys: AfArray, in_vals: AfArray, dim: c_uint, ascend: c_int) -> c_int; - fn af_set_unique(out: MutAfArray, input: AfArray, is_sorted: c_int) -> c_int; - fn af_set_union(out: MutAfArray, first: AfArray, second: AfArray, is_unq: c_int) -> c_int; - fn af_set_intersect(out: MutAfArray, one: AfArray, two: AfArray, is_unq: c_int) -> c_int; + + fn af_sort_by_key(out_keys: MutAfArray, out_vals: MutAfArray, + in_keys: AfArray, in_vals: AfArray, dim: c_uint, ascend: c_int) -> c_int; } #[allow(unused_mut)] diff --git a/src/arith/mod.rs b/src/arith/mod.rs index 9e7864e29..0fd696702 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -1,42 +1,256 @@ extern crate libc; +extern crate num; use super::Array as Array; use self::libc::{c_int}; use data::constant; +use self::num::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; +use std::ops::{Add, Sub, Div, Mul, BitAnd, BitOr, BitXor, Not, Rem, Shl, Shr}; #[allow(dead_code)] extern { fn af_add(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_sub(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_mul(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_div(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + + fn af_lt(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_gt(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_le(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_ge(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_eq(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_or(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + + fn af_neq(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_and(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_rem(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_mod(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + + fn af_bitand(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_bitor(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_bitxor(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_bitshiftl(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_bitshiftr(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_minof(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_maxof(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + + fn af_not(out: MutAfArray, arr: AfArray) -> c_int; + fn af_abs(out: MutAfArray, arr: AfArray) -> c_int; + fn af_arg(out: MutAfArray, arr: AfArray) -> c_int; + fn af_sign(out: MutAfArray, arr: AfArray) -> c_int; + fn af_ceil(out: MutAfArray, arr: AfArray) -> c_int; + fn af_round(out: MutAfArray, arr: AfArray) -> c_int; + fn af_trunc(out: MutAfArray, arr: AfArray) -> c_int; + fn af_floor(out: MutAfArray, arr: AfArray) -> c_int; + + fn af_hypot(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; fn af_sin(out: MutAfArray, arr: AfArray) -> c_int; + fn af_cos(out: MutAfArray, arr: AfArray) -> c_int; + fn af_tan(out: MutAfArray, arr: AfArray) -> c_int; + fn af_asin(out: MutAfArray, arr: AfArray) -> c_int; + fn af_acos(out: MutAfArray, arr: AfArray) -> c_int; + fn af_atan(out: MutAfArray, arr: AfArray) -> c_int; + + fn af_atan2(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_cplx2(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_root(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_pow(out: MutAfArray, lhs: AfArray, rhs: AfArray, batch: c_int) -> c_int; + fn af_cplx(out: MutAfArray, arr: AfArray) -> c_int; + fn af_real(out: MutAfArray, arr: AfArray) -> c_int; + fn af_imag(out: MutAfArray, arr: AfArray) -> c_int; + fn af_conjg(out: MutAfArray, arr: AfArray) -> c_int; + fn af_sinh(out: MutAfArray, arr: AfArray) -> c_int; + fn af_cosh(out: MutAfArray, arr: AfArray) -> c_int; + fn af_tanh(out: MutAfArray, arr: AfArray) -> c_int; + fn af_asinh(out: MutAfArray, arr: AfArray) -> c_int; + fn af_acosh(out: MutAfArray, arr: AfArray) -> c_int; + fn af_atanh(out: MutAfArray, arr: AfArray) -> c_int; + fn af_pow2(out: MutAfArray, arr: AfArray) -> c_int; + fn af_exp(out: MutAfArray, arr: AfArray) -> c_int; + fn af_expm1(out: MutAfArray, arr: AfArray) -> c_int; + fn af_erf(out: MutAfArray, arr: AfArray) -> c_int; + fn af_erfc(out: MutAfArray, arr: AfArray) -> c_int; + fn af_log(out: MutAfArray, arr: AfArray) -> c_int; + fn af_log1p(out: MutAfArray, arr: AfArray) -> c_int; + fn af_log10(out: MutAfArray, arr: AfArray) -> c_int; + fn af_log2(out: MutAfArray, arr: AfArray) -> c_int; + fn af_sqrt(out: MutAfArray, arr: AfArray) -> c_int; + fn af_cbrt(out: MutAfArray, arr: AfArray) -> c_int; + fn af_factorial(out: MutAfArray, arr: AfArray) -> c_int; + fn af_tgamma(out: MutAfArray, arr: AfArray) -> c_int; + fn af_lgamma(out: MutAfArray, arr: AfArray) -> c_int; + fn af_iszero(out: MutAfArray, arr: AfArray) -> c_int; + fn af_isinf(out: MutAfArray, arr: AfArray) -> c_int; + fn af_isnan(out: MutAfArray, arr: AfArray) -> c_int; } -impl Add for Array { +impl Not for Array { type Output = Array; - fn add(self, rhs: f64) -> Array { - let cnst_arr = constant(rhs, self.dims()); + fn not(self) -> Array { unsafe { let mut temp: i64 = 0; - af_add(&mut temp as MutAfArray, self.get() as AfArray, cnst_arr.get() as AfArray, 0); + af_not(&mut temp as MutAfArray, self.get() as AfArray); Array {handle: temp} } } } -#[allow(unused_mut)] -pub fn sin(input: &Array) -> Array { - unsafe { - let mut temp: i64 = 0; - af_sin(&mut temp as MutAfArray, input.get() as AfArray); - Array {handle: temp} - } +macro_rules! unary_func { + ($fn_name: ident, $ffi_fn: ident) => ( + #[allow(unused_mut)] + pub fn $fn_name(input: &Array) -> Array { + unsafe { + let mut temp: i64 = 0; + $ffi_fn(&mut temp as MutAfArray, input.get() as AfArray); + Array {handle: temp} + } + } + ) +} + +unary_func!(abs, af_abs); +unary_func!(arg, af_arg); +unary_func!(sign, af_sign); +unary_func!(round, af_round); +unary_func!(trunc, af_trunc); +unary_func!(floor, af_floor); +unary_func!(ceil, af_ceil); +unary_func!(sin, af_sin); +unary_func!(cos, af_cos); +unary_func!(tan, af_tan); +unary_func!(asin, af_asin); +unary_func!(acos, af_acos); +unary_func!(atan, af_atan); +unary_func!(cplx, af_cplx); +unary_func!(real, af_real); +unary_func!(imag, af_imag); +unary_func!(conjg, af_conjg); +unary_func!(sinh, af_sinh); +unary_func!(cosh, af_cosh); +unary_func!(tanh, af_tanh); +unary_func!(asinh, af_asinh); +unary_func!(acosh, af_acosh); +unary_func!(atanh, af_atanh); +unary_func!(pow2, af_pow2); +unary_func!(exp, af_exp); +unary_func!(expm1, af_expm1); +unary_func!(erf, af_erf); +unary_func!(erfc, af_erfc); +unary_func!(log, af_log); +unary_func!(log1p, af_log1p); +unary_func!(log10, af_log10); +unary_func!(log2, af_log2); +unary_func!(sqrt, af_sqrt); +unary_func!(cbrt, af_cbrt); +unary_func!(factorial, af_factorial); +unary_func!(tgamma, af_tgamma); +unary_func!(lgamma, af_lgamma); +unary_func!(iszero, af_iszero); +unary_func!(isinf, af_isinf); +unary_func!(isnan, af_isnan); + +macro_rules! binary_func { + ($fn_name: ident, $ffi_fn: ident) => ( + #[allow(unused_mut)] + pub fn $fn_name(lhs: &Array, rhs: &Array) -> Array { + unsafe { + let mut temp: i64 = 0; + $ffi_fn(&mut temp as MutAfArray, lhs.get() as AfArray, rhs.get() as AfArray, 0); + Array {handle: temp} + } + } + ) } + +binary_func!(lt, af_lt); +binary_func!(gt, af_gt); +binary_func!(le, af_le); +binary_func!(ge, af_ge); +binary_func!(eq, af_eq); +binary_func!(neq, af_neq); +binary_func!(and, af_and); +binary_func!(or, af_or); +binary_func!(minof, af_minof); +binary_func!(maxof, af_maxof); +binary_func!(modulo, af_mod); +binary_func!(hypot, af_hypot); +binary_func!(atan2, af_atan2); +binary_func!(cplx2, af_cplx2); +binary_func!(root, af_root); +binary_func!(pow, af_pow); + +macro_rules! arith_scalar_func { + ($rust_type: ty, $op_name:ident, $fn_name: ident, $ffi_fn: ident) => ( + impl $op_name<$rust_type> for 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; + $ffi_fn(&mut temp as MutAfArray, + self.get() as AfArray, cnst_arr.get() as AfArray, + 0); + Array {handle: temp} + } + } + } + ) +} + +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_spec!(Complex); +arith_scalar_spec!(Complex); +arith_scalar_spec!(f64); +arith_scalar_spec!(f32); +arith_scalar_spec!(u64); +arith_scalar_spec!(i64); +arith_scalar_spec!(u32); +arith_scalar_spec!(i32); +arith_scalar_spec!(u8); + +macro_rules! arith_func { + ($op_name:ident, $fn_name:ident, $ffi_fn: ident) => ( + impl $op_name for Array { + type Output = Array; + + fn $fn_name(self, rhs: Array) -> Array { + unsafe { + let mut temp: i64 = 0; + $ffi_fn(&mut temp as MutAfArray, + self.get() as AfArray, rhs.get() as AfArray, + 0); + Array {handle: temp} + } + } + } + ) +} + +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); diff --git a/src/data/mod.rs b/src/data/mod.rs index 7a72c63b2..d02b6bab9 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -37,11 +37,9 @@ extern { t_ndims: c_uint, tdims: *const DimT, afdtype: c_int) -> c_int; fn af_randu(out: MutAfArray, ndims: c_uint, dims: *const DimT, afdtype: c_int) -> c_int; - fn af_randn(out: MutAfArray, ndims: c_uint, dims: *const DimT, afdtype: c_int) -> c_int; fn af_set_seed(seed: Uintl); - fn af_get_seed(seed: *mut Uintl); } diff --git a/src/lib.rs b/src/lib.rs index 916eb81ef..a9e4dbf9e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,12 @@ pub use algorithm::{accum, locate, diff1, diff2, sort, sort_index, sort_by_key}; pub use algorithm::{set_unique, set_union, set_intersect}; mod algorithm; -pub use arith::{sin}; +pub use arith::{lt, gt, le, ge, eq, neq, and, or, minof, maxof}; +pub use arith::{abs, sign, round, trunc, floor, ceil, modulo}; +pub use arith::{sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, asinh, acosh, atanh}; +pub use arith::{atan2, cplx2, arg, cplx, real, imag, conjg, hypot}; +pub use arith::{sqrt, log, log1p, log10, log2, pow2, exp, expm1, erf, erfc, root, pow}; +pub use arith::{cbrt, factorial, tgamma, lgamma, iszero, isinf, isnan}; mod arith; pub use data::{constant, range, iota}; From d8684b75691fe9d6764e88735b306ede1a0b7bd2 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 9 Jul 2015 14:36:59 -0400 Subject: [PATCH 4/6] Modified arith operator semantics --- src/array.rs | 12 ++++++++++++ tests/hello_world.rs | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/array.rs b/src/array.rs index 29e43211c..3502139f1 100644 --- a/src/array.rs +++ b/src/array.rs @@ -57,6 +57,8 @@ extern { fn af_eval(arr: AfArray) -> c_int; + fn af_retain_array(out: MutAfArray, arr: AfArray) -> c_int; + fn af_release_array(arr: AfArray) -> c_int; fn af_print_array(arr: AfArray) -> c_int; @@ -153,6 +155,16 @@ impl Array { is_func!(is_bool, af_is_bool); } +impl Clone for Array { + fn clone(&self) -> Array { + unsafe { + let mut temp: i64 = 0; + af_retain_array(&mut temp as MutAfArray, self.handle as AfArray); + Array {handle: temp} + } + } +} + impl Drop for Array { fn drop(&mut self) { unsafe { diff --git a/tests/hello_world.rs b/tests/hello_world.rs index 152443d1d..bc6f35f0c 100644 --- a/tests/hello_world.rs +++ b/tests/hello_world.rs @@ -19,6 +19,9 @@ fn main() { let b: Array = af::sin(&a) + 1.5; af::print(&b); + let test = a.clone() + b.clone(); + af::print(&test); + // printf("Negate the first three elements of second column\n"); // B(seq(0, 2), 1) = B(seq(0, 2), 1) * -1; // af_print(B); From 7d07769032f12cf90b65e43d7d23c906fbdb2939 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 9 Jul 2015 17:52:26 -0400 Subject: [PATCH 5/6] Changed arith operator overloads From now on, do the arith operations, users have to do the following ``` let a = randu(Dim4::new(&[4,4,1,1])); let b = &a + 3.5; let c = &a - &b; ``` We can't do just `a+b` because of move semantics limitation. This may be improved later when `Copy` trait can be implemented on Objects with `Drop` trait implemented. --- src/arith/mod.rs | 8 ++++---- tests/hello_world.rs | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/arith/mod.rs b/src/arith/mod.rs index 0fd696702..43df8b110 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -92,7 +92,7 @@ extern { fn af_isnan(out: MutAfArray, arr: AfArray) -> c_int; } -impl Not for Array { +impl<'f> Not for &'f Array { type Output = Array; fn not(self) -> Array { @@ -190,7 +190,7 @@ binary_func!(pow, af_pow); macro_rules! arith_scalar_func { ($rust_type: ty, $op_name:ident, $fn_name: ident, $ffi_fn: ident) => ( - impl $op_name<$rust_type> for Array { + impl<'f> $op_name<$rust_type> for &'f Array { type Output = Array; fn $fn_name(self, rhs: $rust_type) -> Array { @@ -228,10 +228,10 @@ arith_scalar_spec!(u8); macro_rules! arith_func { ($op_name:ident, $fn_name:ident, $ffi_fn: ident) => ( - impl $op_name for Array { + impl<'f> $op_name<&'f Array> for &'f Array { type Output = Array; - fn $fn_name(self, rhs: Array) -> Array { + fn $fn_name(self, rhs:&'f Array) -> Array { unsafe { let mut temp: i64 = 0; $ffi_fn(&mut temp as MutAfArray, diff --git a/tests/hello_world.rs b/tests/hello_world.rs index bc6f35f0c..60b13efcb 100644 --- a/tests/hello_world.rs +++ b/tests/hello_world.rs @@ -16,10 +16,14 @@ fn main() { af::print(&a); println!("Element-wise arithmetic"); - let b: Array = af::sin(&a) + 1.5; - af::print(&b); - - let test = a.clone() + b.clone(); + let b: Array = &af::sin(&a) + 1.5; + let b2: Array = &af::sin(&a) + &af::cos(&a); + let b3: Array = ! &a; + println!("sin(a) + 1.5 => "); af::print(&b); + println!("sin(a) + cos(a) => "); af::print(&b2); + println!("!a => "); af::print(&b3); + + let test = &a + &b; af::print(&test); // printf("Negate the first three elements of second column\n"); From 6c53edf7dee0d22db1236a1d5fb93ad0567c10ff Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 9 Jul 2015 18:15:47 -0400 Subject: [PATCH 6/6] Moved examples to examples folder and modified README to reflect it --- Cargo.toml | 4 +- README.md | 79 +++++++++++++++++-- .../hello_world.rs => examples/helloworld.rs | 3 +- 3 files changed, 74 insertions(+), 12 deletions(-) rename tests/hello_world.rs => examples/helloworld.rs (97%) diff --git a/Cargo.toml b/Cargo.toml index 9232625ee..e244addf3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,6 @@ rustc-serialize = "*" name = "arrayfire" path = "src/lib.rs" -[[test]] +[[example]] name = "helloworld" -path = "tests/hello_world.rs" +path = "examples/helloworld.rs" diff --git a/README.md b/README.md index 986be35a3..3f76c373e 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,17 @@ Edit [build.conf](build.conf) to modify the build flags. The structure is a simp Currently Rust does not allow key:value pairs to be passed from the CLI. To use an existing arrayfire installation modify the first three JSON values. -To build: +To build arrayfire: ```bash git submodule update --init --recursive cargo build ``` -To test: +To run hello world example: ```bash -~/p/arrayfire_rust> cargo test +~/p/arrayfire_rust> cargo run --example helloworld ... running 1 test ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38) @@ -35,12 +35,75 @@ Create a 5-by-3 matrix of random floats on the GPU 0.9251 0.5132 0.6814 Element-wise arithmetic +sin(a) + 1.5 => [5 3 1 1] - 0.6744 0.4317 0.7006 - 0.7962 0.6189 0.2905 - 0.0390 0.1097 0.6549 - 0.8243 0.4531 0.3509 - 0.7987 0.4910 0.6299 + 2.1744 1.9317 2.2006 + 2.2962 2.1189 1.7905 + 1.5390 1.6097 2.1549 + 2.3243 1.9531 1.8509 + 2.2987 1.9910 2.1299 + +sin(a) + cos(a) => +[5 3 1 1] + 1.4128 1.3337 1.4142 + 1.4012 1.4044 1.2474 + 1.0382 1.1037 1.4106 + 1.3905 1.3446 1.2873 + 1.4004 1.3621 1.4066 + +!a => +[5 3 1 1] + 1 1 1 + 1 1 1 + 1 1 1 + 1 1 1 + 1 1 1 + +a + b +[5 3 1 1] + 2.9147 2.3780 2.9767 + 3.2172 2.7862 2.0853 + 1.5780 1.7196 2.8689 + 3.2933 2.4233 2.2094 + 3.2238 2.5042 2.8113 + +Fourier transform the result +[5 3 1 1] + (10.6327,0.0000) (9.6043,0.0000) (10.1267,0.0000) + (0.4689,0.4640) (0.3193,0.0802) (0.1713,0.1441) + (-0.3491,-0.7454) (-0.2923,-0.4018) (0.2667,0.4886) + (-0.3491,0.7454) (-0.2923,0.4018) (0.2667,-0.4886) + (0.4689,-0.4640) (0.3193,-0.0802) (0.1713,-0.1441) + +Create 2-by-3 matrix from host data +[2 3 1 1] + 1 3 5 + 2 4 6 + +Sort A and print sorted array and corresponding indices +[5 3 1 1] + 0.0390 0.1099 0.2948 + 0.7402 0.4464 0.3585 + 0.9210 0.4702 0.6814 + 0.9251 0.5132 0.7140 + 0.9690 0.6673 0.7762 + +[5 3 1 1] + 2 2 1 + 0 0 3 + 1 3 4 + 4 4 2 + 3 1 0 + +u8 constant array +[5 3 1 1] + 1 1 1 + 1 1 1 + 1 1 1 + 1 1 1 + 1 1 1 + +Is u8_cnst array float precision type ? false ``` ## Issues diff --git a/tests/hello_world.rs b/examples/helloworld.rs similarity index 97% rename from tests/hello_world.rs rename to examples/helloworld.rs index 60b13efcb..486853870 100644 --- a/tests/hello_world.rs +++ b/examples/helloworld.rs @@ -4,7 +4,6 @@ extern crate arrayfire as af; use af::Dim4; use af::Array; -#[test] fn main() { af::set_device(0); af::info(); @@ -24,7 +23,7 @@ fn main() { println!("!a => "); af::print(&b3); let test = &a + &b; - af::print(&test); + println!("a + b"); af::print(&test); // printf("Negate the first three elements of second column\n"); // B(seq(0, 2), 1) = B(seq(0, 2), 1) * -1;