From bcd99097df075bf10e6ed615b9da391369fd2dc7 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 15 Dec 2016 12:30:42 +0530 Subject: [PATCH 1/3] new data generation function: constant_like function to create an array with same shape and type as input array filled with a constant --- src/data/mod.rs | 23 +++++++++++++++++++++++ src/lib.rs | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/data/mod.rs b/src/data/mod.rs index 23fbfbf24..ed6abd552 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -622,3 +622,26 @@ pub fn replace_scalar(a: &mut Array, cond: &Array, b: f64) { HANDLE_ERROR(AfError::from(err_val)); } } + +/// Create an array filled with given constant retaining type/shape of another Array. +/// +/// # Parameters +/// +/// - `value` is the constant with which output Array is to be filled +/// - `input` is the Array whose shape the output Array has to maintain +/// +/// # Return Values +/// +/// Array with given constant value and input Array's shape and similar internal data type. +pub fn constant_like(value: f64, input: &Array) -> Array { + let dims = input.dims(); + unsafe { + let mut temp: i64 = 0; + let err_val = af_constant(&mut temp as MutAfArray, value as c_double, + dims.ndims() as c_uint, + dims.get().as_ptr() as *const DimT, + input.get_type() as c_int); + HANDLE_ERROR(AfError::from(err_val)); + Array::from(temp) + } +} diff --git a/src/lib.rs b/src/lib.rs index 00a4426ef..ae44f4ab6 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ mod backend; pub use blas::{matmul, dot, transpose, transpose_inplace}; mod blas; -pub use data::{constant, range, iota}; +pub use data::{constant, constant_like, range, iota}; 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}; From 63293afa34d33114f1675c5b0106f386d70d3c35 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 15 Dec 2016 12:37:55 +0530 Subject: [PATCH 2/3] Implement negation trait for Array --- src/arith/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/arith/mod.rs b/src/arith/mod.rs index 6a49a68ad..4e50aa40a 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -6,9 +6,11 @@ use array::Array; use defines::AfError; use error::HANDLE_ERROR; use self::libc::{c_int}; -use data::{constant, tile}; +use data::{constant, constant_like, tile}; use self::num::Complex; +use std::ops::Neg; + type MutAfArray = *mut self::libc::c_longlong; type MutDouble = *mut self::libc::c_double; type MutUint = *mut self::libc::c_uint; @@ -485,3 +487,12 @@ bit_assign_func!(BitOrAssign, bitor_assign, bitor); bit_assign_func!(BitXorAssign, bitxor_assign, bitxor); } + +///Implement negation trait for Array +impl Neg for Array { + type Output = Array; + + fn neg(self) -> Self::Output { + constant_like(0.0, &self) - self + } +} From 10a20d1b9326c6551aa6e1265c2adf1f2b552bda Mon Sep 17 00:00:00 2001 From: pradeep Date: Sat, 17 Dec 2016 21:45:28 +0530 Subject: [PATCH 3/3] New fns to create arrays using Dim4 and DType params * constant_t * range_t * range_t * iota_t --- src/arith/mod.rs | 21 ++++++-- src/data/mod.rs | 135 +++++++++++++++++++++++++++++++++++++++++++---- src/defines.rs | 32 +++++++++++ src/lib.rs | 7 +-- 4 files changed, 178 insertions(+), 17 deletions(-) diff --git a/src/arith/mod.rs b/src/arith/mod.rs index 4e50aa40a..32e291dd9 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -3,14 +3,16 @@ extern crate num; use dim4::Dim4; use array::Array; -use defines::AfError; +use defines::{AfError, DType, Scalar}; use error::HANDLE_ERROR; use self::libc::{c_int}; -use data::{constant, constant_like, tile}; +use data::{constant, constant_t, tile}; use self::num::Complex; 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; @@ -493,6 +495,19 @@ impl Neg for Array { type Output = Array; fn neg(self) -> Self::Output { - constant_like(0.0, &self) - self + match self.get_type() { + DType::S64 => (constant_t(Scalar::S64(0 as i64), self.dims(), DType::S64) - self), + DType::U64 => (constant_t(Scalar::U64(0 as u64), self.dims(), DType::U64) - self), + DType::C32 => (constant_t(Scalar::C32(Complex32::new(0.0, 0.0)), self.dims(), DType::C32) - self), + DType::C64 => (constant_t(Scalar::C64(Complex64::new(0.0, 0.0)), self.dims(), DType::C64) - self), + DType::F32 => (constant_t(Scalar::F32(0 as f32), self.dims(), DType::F32) - self), + DType::F64 => (constant_t(Scalar::F64(0 as f64), self.dims(), DType::F64) - self), + DType::B8 => (constant_t(Scalar::B8 (false ), self.dims(), DType::B8 ) - self), + DType::S32 => (constant_t(Scalar::S32(0 as i32), self.dims(), DType::S32) - self), + DType::U32 => (constant_t(Scalar::U32(0 as u32), self.dims(), DType::U32) - self), + DType::U8 => (constant_t(Scalar::U8 (0 as u8 ), self.dims(), DType::U8 ) - self), + DType::S16 => (constant_t(Scalar::S16(0 as i16), self.dims(), DType::S16) - self), + DType::U16 => (constant_t(Scalar::U16(0 as u16), self.dims(), DType::U16) - self), + } } } diff --git a/src/data/mod.rs b/src/data/mod.rs index ed6abd552..a85f0382a 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -3,7 +3,7 @@ extern crate num; use array::Array; use dim4::Dim4; -use defines::AfError; +use defines::{AfError, DType, Scalar}; use error::HANDLE_ERROR; use self::libc::{uint8_t, c_int, c_uint, c_double}; use self::num::Complex; @@ -623,24 +623,137 @@ pub fn replace_scalar(a: &mut Array, cond: &Array, b: f64) { } } -/// Create an array filled with given constant retaining type/shape of another Array. +/// Create a range of values of given type([DType](./enum.DType.html)) +/// +/// Creates an array with [0, n] values along the `seq_dim` which is tiled across other dimensions. +/// +/// # Parameters +/// +/// - `dims` is the size of Array +/// - `seq_dim` is the dimension along which range values are populated, all values along other +/// dimensions are just repeated +/// - `dtype` indicates whats the type of the Array to be created +/// +/// # Return Values +/// Array +#[allow(unused_mut)] +pub fn range_t(dims: Dim4, seq_dim: i32, dtype: DType) -> Array { + unsafe { + let mut temp: i64 = 0; + let err_val = af_range(&mut temp as MutAfArray, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, + seq_dim as c_int, dtype as uint8_t); + HANDLE_ERROR(AfError::from(err_val)); + Array::from(temp) + } +} + +/// Create a range of values of given type([DType](./enum.DType.html)) +/// +/// Create an sequence [0, dims.elements() - 1] and modify to specified dimensions dims and then tile it according to tile_dims. +/// +/// # Parameters +/// +/// - `dims` is the dimensions of the sequence to be generated +/// - `tdims` is the number of repitions of the unit dimensions +/// - `dtype` indicates whats the type of the Array to be created +/// +/// # Return Values +/// +/// Array +#[allow(unused_mut)] +pub fn iota_t(dims: Dim4, tdims: Dim4, dtype: DType) -> Array { + unsafe { + let mut temp: i64 = 0; + let err_val =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, + dtype as uint8_t); + HANDLE_ERROR(AfError::from(err_val)); + Array::from(temp) + } +} + +/// Create an identity array with 1's in diagonal of given type([DType](./enum.DType.html)) /// /// # Parameters /// -/// - `value` is the constant with which output Array is to be filled -/// - `input` is the Array whose shape the output Array has to maintain +/// - `dims` is the output Array dimensions +/// - `dtype` indicates whats the type of the Array to be created /// /// # Return Values /// -/// Array with given constant value and input Array's shape and similar internal data type. -pub fn constant_like(value: f64, input: &Array) -> Array { - let dims = input.dims(); +/// Identity matrix +#[allow(unused_mut)] +pub fn identity_t(dims: Dim4, dtype: DType) -> Array { + unsafe { + let mut temp: i64 = 0; + let err_val = af_identity(&mut temp as MutAfArray, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, + dtype as uint8_t); + HANDLE_ERROR(AfError::from(err_val)); + Array::from(temp) + } +} + +/// Create a constant array of given type([DType](./enum.DType.html)) +/// +/// You can use this function to create arrays of type dictated by the enum +/// [DType](./enum.DType.html) using the scalar `value` that has the shape similar +/// to `dims`. +/// +/// # Parameters +/// +/// - `value` is the [Scalar](./enum.Scalar.html) to be filled into the array +/// - `dims` is the output Array dimensions +/// - `dtype` indicates the type of Array to be created and is the type of the scalar to be passed +/// via the paramter `value`. +/// +/// # Return Values +/// +/// Array of `dims` shape and filed with given constant `value`. +#[allow(unused_mut)] +pub fn constant_t(value: Scalar, dims: Dim4, dtype: DType) -> Array { + use Scalar::*; + + // Below macro is only visible to this function + // and it is used to abbreviate the repetitive const calls + macro_rules! expand_const_call { + ($ffi_name: ident, $temp: expr, $v: expr, $dims: expr, $dt: expr) => ({ + $ffi_name(&mut $temp as MutAfArray, $v as c_double, + $dims.ndims() as c_uint, $dims.get().as_ptr() as *const DimT, $dt) + }) + } + unsafe { + let dt = dtype as c_int; let mut temp: i64 = 0; - let err_val = af_constant(&mut temp as MutAfArray, value as c_double, - dims.ndims() as c_uint, - dims.get().as_ptr() as *const DimT, - input.get_type() as c_int); + let err_val = match value { + C32(v) => { + af_constant_complex(&mut temp as MutAfArray, v.re as c_double, v.im as c_double, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, dt) + }, + C64(v) => { + af_constant_complex(&mut temp as MutAfArray, v.re as c_double, v.im as c_double, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT, dt) + }, + S64(v) => { + af_constant_long(&mut temp as MutAfArray, v as Intl, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT) + }, + U64(v) => { + af_constant_ulong(&mut temp as MutAfArray, v as Uintl, + dims.ndims() as c_uint, dims.get().as_ptr() as *const DimT) + }, + F32(v) => expand_const_call!(af_constant, temp, v, dims, dt), + F64(v) => expand_const_call!(af_constant, temp, v, dims, dt), + B8(v) => expand_const_call!(af_constant, temp, v as i32, dims, dt), + S32(v) => expand_const_call!(af_constant, temp, v, dims, dt), + U32(v) => expand_const_call!(af_constant, temp, v, dims, dt), + U8(v) => expand_const_call!(af_constant, temp, v, dims, dt), + S16(v) => expand_const_call!(af_constant, temp, v, dims, dt), + U16(v) => expand_const_call!(af_constant, temp, v, dims, dt), + }; HANDLE_ERROR(AfError::from(err_val)); Array::from(temp) } diff --git a/src/defines.rs b/src/defines.rs index e74337d3b..ab42c3be7 100644 --- a/src/defines.rs +++ b/src/defines.rs @@ -1,6 +1,9 @@ +extern crate num; + use std::error::Error; use std::fmt::{Display, Formatter}; use std::fmt::Error as FmtError; +use self::num::Complex; /// Error codes #[repr(C)] @@ -397,3 +400,32 @@ pub const PHILOX : RandomEngineType = RandomEngineType::PHILOX_4X32_10; pub const THREEFRY : RandomEngineType = RandomEngineType::THREEFRY_2X32_16; pub const MERSENNE : RandomEngineType = RandomEngineType::MERSENNE_GP11213; pub const DEFAULT_RANDOM_ENGINE : RandomEngineType = PHILOX; + +/// Scalar value types +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum Scalar { + /// 32 bit float + F32(f32), + /// 32 bit complex float + C32(Complex), + /// 64 bit float + F64(f64), + /// 64 bit complex float + C64(Complex), + /// 8 bit boolean + B8(bool), + /// 32 bit signed integer + S32(i32), + /// 32 bit unsigned integer + U32(u32), + /// 8 bit unsigned integer + U8(u8), + /// 64 bit signed integer + S64(i64), + /// 64 bit unsigned integer + U64(u64), + /// 16 bit signed integer + S16(i16), + /// 16 bit unsigned integer + U16(u16), +} diff --git a/src/lib.rs b/src/lib.rs index ae44f4ab6..23b2a78dc 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,11 +32,12 @@ mod backend; pub use blas::{matmul, dot, transpose, transpose_inplace}; mod blas; -pub use data::{constant, constant_like, range, iota}; -pub use data::{identity, diag_create, diag_extract, lower, upper}; +pub use data::{constant, range, iota, identity}; +pub use data::{diag_create, diag_extract, lower, upper}; pub use data::{join, join_many, tile}; pub use data::{reorder, shift, moddims, flat, flip}; 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}; @@ -47,7 +48,7 @@ pub use defines::{DType, AfError, Backend, ColorMap, YCCStd, HomographyType}; pub use defines::{InterpType, BorderType, MatchType, NormType}; pub use defines::{Connectivity, ConvMode, ConvDomain, ColorSpace, MatProp}; pub use defines::{MarkerType, MomentType, SparseFormat, BinaryOp, RandomEngineType}; -pub use defines::{PHILOX, THREEFRY, MERSENNE, DEFAULT_RANDOM_ENGINE}; +pub use defines::{PHILOX, THREEFRY, MERSENNE, DEFAULT_RANDOM_ENGINE, Scalar}; mod defines; pub use dim4::Dim4;