@@ -2,6 +2,7 @@ extern crate libc;
2
2
3
3
use dim4:: Dim4 ;
4
4
use defines:: { AfError , Aftype , Backend } ;
5
+ use util:: HasAfEnum ;
5
6
use self :: libc:: { uint8_t, c_void, c_int, c_uint, c_longlong} ;
6
7
7
8
type MutAfArray = * mut self :: libc:: c_longlong ;
@@ -72,6 +73,21 @@ extern {
72
73
fn af_cast ( out : MutAfArray , arr : AfArray , aftype : uint8_t ) -> c_int ;
73
74
74
75
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 ;
75
91
}
76
92
77
93
/// A multidimensional data container
@@ -104,11 +120,12 @@ impl Array {
104
120
///
105
121
/// ```
106
122
/// 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();
108
124
/// ```
109
125
#[ 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 > {
111
127
unsafe {
128
+ let aftype = T :: get_af_dtype ( ) ;
112
129
let mut temp: i64 = 0 ;
113
130
let err_val = af_create_array ( & mut temp as MutAfArray ,
114
131
slice. as_ptr ( ) as * const c_void ,
@@ -122,21 +139,61 @@ impl Array {
122
139
}
123
140
}
124
141
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
+
125
165
/// Returns the backend of the Array
126
166
///
127
167
/// # Return Values
128
168
///
129
169
/// Returns an value of type `Backend` which indicates which backend
130
170
/// was active when Array was created.
131
- pub fn get_backend ( & self ) -> Backend {
171
+ pub fn get_backend ( & self ) -> Result < Backend , AfError > {
132
172
unsafe {
133
173
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
+
140
197
}
141
198
}
142
199
}
@@ -172,8 +229,8 @@ impl Array {
172
229
let mut ret1: i64 = 0 ;
173
230
let mut ret2: i64 = 0 ;
174
231
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 ,
177
234
self . handle as AfArray ) ;
178
235
match err_val {
179
236
0 => Ok ( Dim4 :: new ( & [ ret0 as u64 , ret1 as u64 , ret2 as u64 , ret3 as u64 ] ) ) ,
@@ -182,6 +239,23 @@ impl Array {
182
239
}
183
240
}
184
241
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
+
185
259
/// Returns the number of dimensions of the Array
186
260
pub fn numdims ( & self ) -> Result < u32 , AfError > {
187
261
unsafe {
@@ -194,6 +268,18 @@ impl Array {
194
268
}
195
269
}
196
270
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
+
197
283
/// Returns the native FFI handle for Rust object `Array`
198
284
pub fn get ( & self ) -> i64 {
199
285
self . handle
@@ -247,12 +333,15 @@ impl Array {
247
333
is_func ! ( is_floating, af_is_floating) ;
248
334
is_func ! ( is_integer, af_is_integer) ;
249
335
is_func ! ( is_bool, af_is_bool) ;
336
+ is_func ! ( is_linear, af_is_linear) ;
337
+ is_func ! ( is_owner, af_is_owner) ;
250
338
251
339
/// 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 > {
253
341
unsafe {
342
+ let trgt_type = T :: get_af_dtype ( ) ;
254
343
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 ) ;
256
345
match err_val {
257
346
0 => Ok ( Array :: from ( temp) ) ,
258
347
_ => Err ( AfError :: from ( err_val) ) ,
@@ -301,7 +390,7 @@ impl Drop for Array {
301
390
///
302
391
/// ```
303
392
/// 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 ) {
305
394
/// Ok(value) => value,
306
395
/// Err(error) => panic!("{}", error),
307
396
/// };
0 commit comments