@@ -2,6 +2,7 @@ extern crate libc;
22
33use dim4:: Dim4 ;
44use defines:: { AfError , Aftype , Backend } ;
5+ use util:: HasAfEnum ;
56use self :: libc:: { uint8_t, c_void, c_int, c_uint, c_longlong} ;
67
78type MutAfArray = * mut self :: libc:: c_longlong ;
@@ -72,6 +73,21 @@ extern {
7273 fn af_cast ( out : MutAfArray , arr : AfArray , aftype : uint8_t ) -> c_int ;
7374
7475 fn af_get_backend_id ( backend : * mut c_int , input : AfArray ) -> c_int ;
76+
77+ fn af_get_device_id ( device : * mut c_int , input : AfArray ) -> c_int ;
78+
79+ fn af_create_strided_array ( arr : MutAfArray , data : * const c_void , offset : DimT ,
80+ ndims : c_uint , dims : * const DimT , strides : * const DimT ,
81+ aftype : uint8_t ) -> c_int ;
82+
83+ fn af_get_strides ( s0 : * mut DimT , s1 : * mut DimT , s2 : * mut DimT , s3 : * mut DimT ,
84+ arr : AfArray ) -> c_int ;
85+
86+ fn af_get_offset ( offset : * mut DimT , arr : AfArray ) -> c_int ;
87+
88+ fn af_is_linear ( result : * mut c_int , arr : AfArray ) -> c_int ;
89+
90+ fn af_is_owner ( result : * mut c_int , arr : AfArray ) -> c_int ;
7591}
7692
7793/// A multidimensional data container
@@ -104,11 +120,12 @@ impl Array {
104120 ///
105121 /// ```
106122 /// let values: &[f32] = &[1.0, 2.0, 3.0];
107- /// let indices = Array::new(Dim4::new(&[3, 1, 1, 1]), values, Aftype::F32 ).unwrap();
123+ /// let indices = Array::new(values, Dim4::new(&[3, 1, 1, 1])).unwrap();
108124 /// ```
109125 #[ allow( unused_mut) ]
110- pub fn new < T > ( dims : Dim4 , slice : & [ T ] , aftype : Aftype ) -> Result < Array , AfError > {
126+ pub fn new < T : HasAfEnum > ( slice : & [ T ] , dims : Dim4 ) -> Result < Array , AfError > {
111127 unsafe {
128+ let aftype = T :: get_af_dtype ( ) ;
112129 let mut temp: i64 = 0 ;
113130 let err_val = af_create_array ( & mut temp as MutAfArray ,
114131 slice. as_ptr ( ) as * const c_void ,
@@ -122,21 +139,61 @@ impl Array {
122139 }
123140 }
124141
142+ /// Constructs a new Array object from strided data
143+ ///
144+ /// The data pointed by the slice passed to this function can possibily be offseted using an additional `offset` parameter.
145+ #[ allow( unused_mut) ]
146+ pub fn new_strided < T : HasAfEnum > ( slice : & [ T ] , offset : i64 ,
147+ dims : Dim4 , strides : Dim4 ) -> Result < Array , AfError > {
148+ unsafe {
149+ let aftype = T :: get_af_dtype ( ) ;
150+ let mut temp: i64 = 0 ;
151+ let err_val = af_create_strided_array ( & mut temp as MutAfArray ,
152+ slice. as_ptr ( ) as * const c_void ,
153+ offset as DimT ,
154+ dims. ndims ( ) as c_uint ,
155+ dims. get ( ) . as_ptr ( ) as * const c_longlong ,
156+ strides. get ( ) . as_ptr ( ) as * const c_longlong ,
157+ aftype as uint8_t ) ;
158+ match err_val {
159+ 0 => Ok ( Array { handle : temp} ) ,
160+ _ => Err ( AfError :: from ( err_val) ) ,
161+ }
162+ }
163+ }
164+
125165 /// Returns the backend of the Array
126166 ///
127167 /// # Return Values
128168 ///
129169 /// Returns an value of type `Backend` which indicates which backend
130170 /// was active when Array was created.
131- pub fn get_backend ( & self ) -> Backend {
171+ pub fn get_backend ( & self ) -> Result < Backend , AfError > {
132172 unsafe {
133173 let mut ret_val: i32 = 0 ;
134- af_get_backend_id ( & mut ret_val as * mut c_int , self . handle as AfArray ) ;
135- match ret_val {
136- 1 => Backend :: AF_BACKEND_CPU ,
137- 2 => Backend :: AF_BACKEND_CUDA ,
138- 3 => Backend :: AF_BACKEND_OPENCL ,
139- _ => Backend :: AF_BACKEND_DEFAULT ,
174+ let err_val = af_get_backend_id ( & mut ret_val as * mut c_int , self . handle as AfArray ) ;
175+ match ( err_val, ret_val) {
176+ ( 0 , 1 ) => Ok ( Backend :: CPU ) ,
177+ ( 0 , 2 ) => Ok ( Backend :: CUDA ) ,
178+ ( 0 , 3 ) => Ok ( Backend :: OPENCL ) ,
179+ _ => Err ( AfError :: from ( err_val) ) ,
180+ }
181+ }
182+ }
183+
184+ /// Returns the device identifier(integer) on which the Array was created
185+ ///
186+ /// # Return Values
187+ ///
188+ /// Return the device id on which Array was created.
189+ pub fn get_device_id ( & self ) -> Result < i32 , AfError > {
190+ unsafe {
191+ let mut ret_val: i32 = 0 ;
192+ let err_val = af_get_device_id ( & mut ret_val as * mut c_int , self . handle as AfArray ) ;
193+ match err_val {
194+ 0 => Ok ( ret_val) ,
195+ _ => Err ( AfError :: from ( err_val) ) ,
196+
140197 }
141198 }
142199 }
@@ -172,8 +229,8 @@ impl Array {
172229 let mut ret1: i64 = 0 ;
173230 let mut ret2: i64 = 0 ;
174231 let mut ret3: i64 = 0 ;
175- let err_val = af_get_dims ( & mut ret0 as * mut c_longlong , & mut ret1 as * mut c_longlong ,
176- & mut ret2 as * mut c_longlong , & mut ret3 as * mut c_longlong ,
232+ let err_val = af_get_dims ( & mut ret0 as * mut DimT , & mut ret1 as * mut DimT ,
233+ & mut ret2 as * mut DimT , & mut ret3 as * mut DimT ,
177234 self . handle as AfArray ) ;
178235 match err_val {
179236 0 => Ok ( Dim4 :: new ( & [ ret0 as u64 , ret1 as u64 , ret2 as u64 , ret3 as u64 ] ) ) ,
@@ -182,6 +239,23 @@ impl Array {
182239 }
183240 }
184241
242+ /// Returns the strides of the Array
243+ pub fn strides ( & self ) -> Result < Dim4 , AfError > {
244+ unsafe {
245+ let mut ret0: i64 = 0 ;
246+ let mut ret1: i64 = 0 ;
247+ let mut ret2: i64 = 0 ;
248+ let mut ret3: i64 = 0 ;
249+ let err_val = af_get_strides ( & mut ret0 as * mut DimT , & mut ret1 as * mut DimT ,
250+ & mut ret2 as * mut DimT , & mut ret3 as * mut DimT ,
251+ self . handle as AfArray ) ;
252+ match err_val {
253+ 0 => Ok ( Dim4 :: new ( & [ ret0 as u64 , ret1 as u64 , ret2 as u64 , ret3 as u64 ] ) ) ,
254+ _ => Err ( AfError :: from ( err_val) ) ,
255+ }
256+ }
257+ }
258+
185259 /// Returns the number of dimensions of the Array
186260 pub fn numdims ( & self ) -> Result < u32 , AfError > {
187261 unsafe {
@@ -194,6 +268,18 @@ impl Array {
194268 }
195269 }
196270
271+ /// Returns the offset to the pointer from where data begins
272+ pub fn offset ( & self ) -> Result < i64 , AfError > {
273+ unsafe {
274+ let mut ret_val: i64 = 0 ;
275+ let err_val = af_get_offset ( & mut ret_val as * mut DimT , self . handle as AfArray ) ;
276+ match err_val {
277+ 0 => Ok ( ret_val) ,
278+ _ => Err ( AfError :: from ( err_val) ) ,
279+ }
280+ }
281+ }
282+
197283 /// Returns the native FFI handle for Rust object `Array`
198284 pub fn get ( & self ) -> i64 {
199285 self . handle
@@ -247,12 +333,15 @@ impl Array {
247333 is_func ! ( is_floating, af_is_floating) ;
248334 is_func ! ( is_integer, af_is_integer) ;
249335 is_func ! ( is_bool, af_is_bool) ;
336+ is_func ! ( is_linear, af_is_linear) ;
337+ is_func ! ( is_owner, af_is_owner) ;
250338
251339 /// Cast the Array data type to `target_type`
252- pub fn cast ( & self , target_type : Aftype ) -> Result < Array , AfError > {
340+ pub fn cast < T : HasAfEnum > ( & self ) -> Result < Array , AfError > {
253341 unsafe {
342+ let trgt_type = T :: get_af_dtype ( ) ;
254343 let mut temp: i64 = 0 ;
255- let err_val = af_cast ( & mut temp as MutAfArray , self . handle as AfArray , target_type as uint8_t ) ;
344+ let err_val = af_cast ( & mut temp as MutAfArray , self . handle as AfArray , trgt_type as uint8_t ) ;
256345 match err_val {
257346 0 => Ok ( Array :: from ( temp) ) ,
258347 _ => Err ( AfError :: from ( err_val) ) ,
@@ -301,7 +390,7 @@ impl Drop for Array {
301390///
302391/// ```
303392/// println!("Create a 5-by-3 matrix of random floats on the GPU");
304- /// let a = match randu(dims, Aftype::F32 ) {
393+ /// let a = match randu::<f32>(dims ) {
305394/// Ok(value) => value,
306395/// Err(error) => panic!("{}", error),
307396/// };
0 commit comments