From aa68391ece5db8e5ed1d3c17c286b4a0528ca00b Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 8 Jun 2017 13:50:05 +0530 Subject: [PATCH 1/7] add lint to allow non camel case naming for enums --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index c59d22869..678f28432 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://arrayfire.com/docs/rust")] #![warn(missing_docs)] +#![allow(non_camel_case_types)] #[macro_use] extern crate lazy_static; From 8481527b28653bd7ba30faa7835e70f8951bb5c5 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 8 Jun 2017 13:55:20 +0530 Subject: [PATCH 2/7] change Array::elements return type to usize --- src/array.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/array.rs b/src/array.rs index 60770a1c3..ba6b711dc 100644 --- a/src/array.rs +++ b/src/array.rs @@ -233,12 +233,12 @@ impl Array { } /// Returns the number of elements in the Array - pub fn elements(&self) -> i64 { + pub fn elements(&self) -> usize { unsafe { let mut ret_val: i64 = 0; let err_val = af_get_elements(&mut ret_val as MutAfArray, self.handle as AfArray); HANDLE_ERROR(AfError::from(err_val)); - ret_val + ret_val as usize } } From de0278ad6ee71dda08839ec477d6f96d09a02dae Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 8 Jun 2017 13:55:46 +0530 Subject: [PATCH 3/7] add HasAfEnum trait bound and size check to Array::host method --- src/array.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/array.rs b/src/array.rs index ba6b711dc..1b44b4937 100644 --- a/src/array.rs +++ b/src/array.rs @@ -308,7 +308,10 @@ impl Array { } /// Copies the data from the Array to the mutable slice `data` - pub fn host(&self, data: &mut [T]) { + pub fn host(&self, data: &mut [T]) { + if data.len() != self.elements() { + HANDLE_ERROR(AfError::ERR_SIZE); + } unsafe { let err_val = af_get_data_ptr(data.as_mut_ptr() as *mut c_void, self.handle as AfArray); HANDLE_ERROR(AfError::from(err_val)); From b646fbbb14155c87c244d7ecef2e3318d533d880 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 8 Jun 2017 16:27:51 +0530 Subject: [PATCH 4/7] fix ref count for arrays used in indexing The Array objects used by Indexer objects were not properly incrementing the reference count. This led to memory corruption and undefined behaviour which is fixed now. --- src/index.rs | 42 ++++++++++++++++-------------------------- src/util.rs | 2 +- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/index.rs b/src/index.rs index 67d2b3857..ae85344b2 100644 --- a/src/index.rs +++ b/src/index.rs @@ -5,26 +5,25 @@ use defines::AfError; use error::HANDLE_ERROR; use seq::Seq; use self::libc::{c_double, c_int, c_uint}; -use util::{AfArray, DimT, IndexT, MutAfArray, MutAfIndex}; +use util::{AfArray, AfIndex, DimT, MutAfArray, MutAfIndex}; #[allow(dead_code)] extern { fn af_create_indexers(indexers: MutAfIndex) -> c_int; - fn af_set_array_indexer(indexer: MutAfIndex, idx: AfArray, dim: DimT) -> c_int; - fn af_set_seq_indexer(indexer: MutAfIndex, idx: *const SeqInternal, dim: DimT, is_batch: c_int) -> c_int; - fn af_release_indexers(indexers: MutAfIndex) -> c_int; + fn af_set_array_indexer(indexer: AfIndex, idx: AfArray, dim: DimT) -> c_int; + fn af_set_seq_indexer(indexer: AfIndex, idx: *const SeqInternal, dim: DimT, is_batch: c_int) -> c_int; + fn af_release_indexers(indexers: AfIndex) -> c_int; fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const SeqInternal) -> c_int; fn af_lookup(out: MutAfArray, arr: AfArray, indices: AfArray, dim: c_uint) -> c_int; fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const SeqInternal, rhs: AfArray) -> c_int; - fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: *const IndexT) -> c_int; - fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: *const IndexT, rhs: AfArray) -> c_int; + fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: AfIndex) -> c_int; + fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: AfIndex, rhs: AfArray) -> c_int; } /// Struct to manage an array of resources of type `af_indexer_t`(ArrayFire C struct) pub struct Indexer { handle: i64, - count: u32, } // Trait that indicates that object can be used for indexing @@ -32,7 +31,7 @@ pub struct Indexer { // Any object to be able to be passed on to [./struct.Indexer.html#method.set_index] method // should implement this trait with appropriate implementation pub trait Indexable { - fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option); + fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option); } /// Enables [Array](./struct.Array.html) to be used to index another Array @@ -41,11 +40,10 @@ pub trait Indexable { /// [assign_gen](./fn.assign_gen.html) impl Indexable for Array { #[allow(unused_variables)] - fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option) { + fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option) { unsafe { - let err_val = af_set_array_indexer(idxr.clone().get() as MutAfIndex, - self.get() as AfArray, - dim as DimT); + let err_val = af_set_array_indexer(idxr.get() as AfIndex, self.clone().get() as AfArray, + dim as DimT); HANDLE_ERROR(AfError::from(err_val)); } } @@ -56,9 +54,9 @@ impl Indexable for Array { /// This is used in functions [index_gen](./fn.index_gen.html) and /// [assign_gen](./fn.assign_gen.html) impl Indexable for Seq where c_double: From { - fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option) { + fn set(&self, idxr: &mut Indexer, dim: u32, is_batch: Option) { unsafe { - let err_val = af_set_seq_indexer(idxr.clone().get() as MutAfIndex, + let err_val = af_set_seq_indexer(idxr.get() as AfIndex, &SeqInternal::from_seq(self) as *const SeqInternal, dim as DimT, is_batch.unwrap() as c_int); HANDLE_ERROR(AfError::from(err_val)); @@ -74,13 +72,12 @@ impl Indexer { let mut temp: i64 = 0; let err_val = af_create_indexers(&mut temp as MutAfIndex); HANDLE_ERROR(AfError::from(err_val)); - Indexer{handle: temp, count: 0} + Indexer{handle: temp} } } /// Set either [Array](./struct.Array.html) or [Seq](./struct.Seq.html) to index an Array along `idx` dimension pub fn set_index(&mut self, idx: &T, dim: u32, is_batch: Option) { - self.count = self.count + 1; idx.set(self, dim, is_batch) } @@ -88,19 +85,12 @@ impl Indexer { pub fn get(&self) -> i64 { self.handle } - - /// Get number of indexers - /// - /// This can be a maximum of four since currently ArrayFire supports maximum of four dimensions - pub fn len(&self) -> u32 { - self.count - } } impl Drop for Indexer { fn drop(&mut self) { unsafe { - let ret_val = af_release_indexers(self.handle as MutAfIndex); + let ret_val = af_release_indexers(self.handle as AfIndex); match ret_val { 0 => (), _ => panic!("Failed to release indexers resource: {}", ret_val), @@ -338,7 +328,7 @@ pub fn index_gen(input: &Array, indices: Indexer) -> Array { unsafe{ let mut temp: i64 = 0; let err_val = af_index_gen(&mut temp as MutAfArray, input.get() as AfArray, - indices.len() as DimT, indices.get() as *const IndexT); + 4, indices.get() as AfIndex); HANDLE_ERROR(AfError::from(err_val)); Array::from(temp) } @@ -380,7 +370,7 @@ pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Array { unsafe{ let mut temp: i64 = 0; let err_val = af_assign_gen(&mut temp as MutAfArray, lhs.get() as AfArray, - indices.len() as DimT, indices.get() as *const IndexT, + 4, indices.get() as AfIndex, rhs.get() as AfArray); HANDLE_ERROR(AfError::from(err_val)); Array::from(temp) diff --git a/src/util.rs b/src/util.rs index 181f735ba..36dbc8335 100644 --- a/src/util.rs +++ b/src/util.rs @@ -9,12 +9,12 @@ use self::num::Complex; use self::libc::{uint8_t, c_int, size_t, c_void}; pub type AfArray = self::libc::c_longlong; +pub type AfIndex = 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; From c53c7f225da01fcfd53262c9be8ffbb4f853980d Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 8 Jun 2017 16:59:15 +0530 Subject: [PATCH 5/7] Update docs about type of Array returned by comparison ops --- src/arith/mod.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/arith/mod.rs b/src/arith/mod.rs index 7e77df60d..623a69e3c 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -255,6 +255,17 @@ macro_rules! overloaded_binary_func { /// /// An Array with results of the binary operation. /// + /// In the case of comparison operations such as the following, the type of output + /// Array is [DType::B8](./enum.DType.html). To retrieve the results of such boolean output + /// to host, an array of 8-bit wide types(eg. u8, i8) should be used since ArrayFire's internal + /// implementation uses char for boolean. + /// + /// * [gt](./fn.gt.html) + /// * [lt](./fn.lt.html) + /// * [ge](./fn.ge.html) + /// * [le](./fn.le.html) + /// * [eq](./fn.eq.html) + /// ///# Note /// /// The trait `Convertable` essentially translates to a scalar native type on rust or Array. From ff4e1be866bacc4f3358d7da8950cffaa7b21b9f Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 8 Jun 2017 17:44:58 +0530 Subject: [PATCH 6/7] Update load_image docs --- src/image/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/image/mod.rs b/src/image/mod.rs index fec01bca5..0579f3c22 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -126,6 +126,8 @@ pub fn gradient(input: &Array) -> (Array, Array) { /// Load Image into Array /// +/// Only, Images with 8/16/32 bits per channel can be loaded using this function. +/// /// # Parameters /// /// - `filename` is aboslute path of the image to be loaded. From 33f9175fb7c7509df9bed63d608603ae804e9301 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 8 Jun 2017 23:25:33 +0530 Subject: [PATCH 7/7] Update README with 1.15.1 as minimum Rust version required starting commit d55874800fdcc10065bbe00e293cffff6d69c532 rustc-serialize has been replaced in favor of serde. Serde requires rust 1.15.1. Thus, README has been updated reflecting the same. --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index 573442f83..dd55af841 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,7 @@ You can find the most recent updated documentation [here](http://arrayfire.githu ## Supported platforms -- Linux and OSX: The bindings have been tested with Rust 1.x. -- Windows: Rust 1.5 (MSVC ABI) is the first version that works with our bindings and ArrayFire library(built using MSVC compiler). - -We recommend using Rust 1.5 and higher. - -Rust 1.8 stabilized the traits for compound assignment operations. These are automatically enabled -based on the rust version you are using. +Linux, Windows and OSX. We recommend using Rust 1.15.1 or higher. ## Use from Crates.io [![](http://meritbadge.herokuapp.com/arrayfire)](https://crates.io/crates/arrayfire)