Skip to content

Commit 2609c90

Browse files
authored
Merge pull request #127 from arrayfire/devel
v3.4.3 devel to master
2 parents e1ce525 + 4ca32a9 commit 2609c90

File tree

8 files changed

+120
-32
lines changed

8 files changed

+120
-32
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "arrayfire"
33
description = "ArrayFire is a high performance software library for parallel computing with an easy-to-use API. Its array based function set makes parallel programming simple. ArrayFire's multiple backends (CUDA, OpenCL and native CPU) make it platform independent and highly portable. A few lines of code in ArrayFire can replace dozens of lines of parallel computing code, saving you valuable time and lowering development costs. This crate provides Rust bindings for ArrayFire library."
4-
version = "3.4.2"
4+
version = "3.4.3"
55
documentation = "http://arrayfire.github.io/arrayfire-rust/arrayfire/index.html"
66
homepage = "https://github.com/arrayfire/arrayfire"
77
repository = "https://github.com/arrayfire/arrayfire-rust"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ first.
3737
3. Make sure you add the path to library files to your path environment variables.
3838
- On Linux & OSX: do `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AF_PATH/lib`
3939
- On Windows: Add `%AF_PATH%\lib` to your PATH environment variable.
40-
4. Add `arrayfire = "3.4.2"` to the dependencies section of your project's Cargo.toml file - 3.4.2
40+
4. Add `arrayfire = "3.4.3"` to the dependencies section of your project's Cargo.toml file - 3.4.3
4141
is the lastest version of crate.
4242

4343
Once step (4) is over, you should be able to use ArrayFire in your Rust project. If you find any bugs, please report them [here](https://github.com/arrayfire/arrayfire-rust/issues).

build.rs

+38-10
Original file line numberDiff line numberDiff line change
@@ -357,19 +357,49 @@ fn blob_backends(conf: &Config, build_dir: &std::path::PathBuf) -> (Vec<String>,
357357
if conf.use_lib {
358358
let afpath = match env::var("AF_PATH") {
359359
Ok(af_path) => PathBuf::from(&af_path),
360-
Err(_) => panic!("Error use_lib is defined, but AF_PATH is not defined"),
360+
Err(_) => {
361+
println!("WARNING! USE_LIB IS DEFINED, BUT AF_PATH IS NOT FOUND,");
362+
println!(" TRYING TO FIND LIBRARIES FROM KNOWN DEFAULT LOCATIONS");
363+
364+
if cfg!(target_os = "windows") {
365+
PathBuf::from("C:/Program Files/ArrayFire/v3/")
366+
} else {
367+
PathBuf::from("/usr/local/")
368+
}
369+
},
361370
};
371+
362372
let libpath = afpath.join("lib");
363373
backend_dirs.push(libpath.to_str().to_owned().unwrap().to_string());
374+
375+
if !cfg!(target_os = "windows") {
376+
backend_dirs.push(String::from("/opt/arrayfire-3/lib"));
377+
backend_dirs.push(String::from("/usr/lib"));
378+
}
364379
} else {
365380
backend_dirs.push(build_dir.join("package/lib").to_str().to_owned().unwrap().to_string());
366381
}
367382

368-
let lib_dir = PathBuf::from(backend_dirs.last().unwrap());
383+
let mut uni_lib_exists = false;
384+
let mut cud_lib_exists = false;
385+
let mut ocl_lib_exists = false;
386+
387+
for backend_dir in backend_dirs.iter() {
388+
let lib_dir = PathBuf::from(backend_dir);
389+
390+
let cud_lib_file_to_check = if cfg!(windows) {WIN_CUDA_LIB_NAME} else {UNIX_CUDA_LIB_NAME};
391+
cud_lib_exists = cud_lib_exists || backend_exists(&lib_dir.join(cud_lib_file_to_check).to_string_lossy());
392+
393+
let ocl_lib_file_to_check = if cfg!(windows) {WIN_OCL_LIB_NAME} else {UNIX_OCL_LIB_NAME};
394+
ocl_lib_exists = ocl_lib_exists || backend_exists(&lib_dir.join(ocl_lib_file_to_check).to_string_lossy());
395+
396+
let uni_lib_file_to_check = if cfg!(windows) {WIN_UNI_LIB_NAME} else {UNIX_UNI_LIB_NAME};
397+
uni_lib_exists = uni_lib_exists || backend_exists(&lib_dir.join(uni_lib_file_to_check).to_string_lossy());
398+
}
399+
369400
if ! conf.use_lib {
370401
// blob in cuda deps
371-
let mut lib_file_to_check = if cfg!(windows) {WIN_CUDA_LIB_NAME} else {UNIX_CUDA_LIB_NAME};
372-
if backend_exists(&lib_dir.join(lib_file_to_check).to_string_lossy()) {
402+
if cud_lib_exists {
373403
if cfg!(windows) {
374404
backend_dirs.push(format!("{}\\lib\\x64", conf.cuda_sdk));
375405
backend_dirs.push(format!("{}\\nvvm\\lib\\x64", conf.cuda_sdk));
@@ -389,8 +419,8 @@ fn blob_backends(conf: &Config, build_dir: &std::path::PathBuf) -> (Vec<String>,
389419
}
390420

391421
//blob in opencl deps
392-
lib_file_to_check = if cfg!(windows) {WIN_OCL_LIB_NAME} else {UNIX_OCL_LIB_NAME};
393-
if backend_exists(&lib_dir.join(lib_file_to_check).to_string_lossy()) {
422+
423+
if ocl_lib_exists {
394424
if ! cfg!(target_os = "macos"){
395425
backends.push("OpenCL".to_string());
396426
}
@@ -413,14 +443,12 @@ fn blob_backends(conf: &Config, build_dir: &std::path::PathBuf) -> (Vec<String>,
413443

414444
if conf.build_graphics=="ON" {
415445
if !conf.use_lib {
416-
backend_dirs.push(build_dir.join("third_party/forge/lib")
417-
.to_str().to_owned().unwrap().to_string());
446+
backend_dirs.push(build_dir.join("third_party/forge/lib").to_str().to_owned().unwrap().to_string());
418447
}
419448
}
420449
}
421450

422-
let lib_file_to_check = if cfg!(windows) {WIN_UNI_LIB_NAME} else {UNIX_UNI_LIB_NAME};
423-
if backend_exists(&lib_dir.join(lib_file_to_check).to_string_lossy()) {
451+
if uni_lib_exists {
424452
backends.push("af".to_string());
425453
if !conf.use_lib && conf.build_graphics=="ON" {
426454
backends.push("forge".to_string());

src/array.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ extern {
104104
/// A multidimensional data container
105105
///
106106
/// Currently, Array objects can store only data until four dimensions
107+
///
108+
/// ### NOTE
109+
///
110+
/// All operators(traits) from std::ops module implemented for Array object
111+
/// carry out element wise operations. For example, `*` does multiplication of
112+
/// elements at corresponding locations in two different Arrays.
107113
pub struct Array {
108114
handle: i64,
109115
}
@@ -296,7 +302,7 @@ impl Array {
296302

297303
/// Makes an copy of the Array
298304
///
299-
/// Internally, this is handled by reference counting
305+
/// This does a deep copy of the data into a new Array
300306
pub fn copy(&self) -> Array {
301307
unsafe {
302308
let mut temp: i64 = 0;
@@ -383,7 +389,14 @@ impl From<i64> for Array {
383389
}
384390
}
385391

386-
/// Used for incrementing the reference count of Array's native resource
392+
/// Returns a new Array object after incrementing the reference count of native resource
393+
///
394+
/// Cloning an Array does not do a deep copy of the underlying array data. It increments the
395+
/// reference count of native resource and returns you the new reference in the form a new Array
396+
/// object.
397+
///
398+
/// To create a deep copy use
399+
/// [copy()](http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.copy)
387400
impl Clone for Array {
388401
fn clone(&self) -> Array {
389402
unsafe {

src/blas/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub fn matmul(lhs: &Array, rhs: &Array,
4646

4747
/// Calculate the dot product of vectors.
4848
///
49-
/// Scalar dot product between two vectors. Also referred to as the inner product. This function returns the scalar product of two equal sized vectors or between a matrix and a vector. The second operand needs to be a vector in either case.
49+
/// Scalar dot product between two vectors. Also referred to as the inner product. This function returns the scalar product of two equal sized vectors.
5050
///
5151
/// # Parameters
5252
///

src/data/mod.rs

+37-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ extern {
3838

3939
fn af_tile(out: MutAfArray, arr: AfArray, x: c_uint, y: c_uint, z: c_uint, w: c_uint) -> c_int;
4040
fn af_reorder(o: MutAfArray, a: AfArray, x: c_uint, y: c_uint, z: c_uint, w: c_uint) -> c_int;
41-
fn af_shift(o: MutAfArray, a: AfArray, x: c_uint, y: c_uint, z: c_uint, w: c_uint) -> c_int;
41+
fn af_shift(o: MutAfArray, a: AfArray, x: c_int, y: c_int, z: c_int, w: c_int) -> c_int;
4242
fn af_moddims(out: MutAfArray, arr: AfArray, ndims: c_uint, dims: *const DimT) -> c_int;
4343

4444
fn af_flat(out: MutAfArray, arr: AfArray) -> c_int;
@@ -375,7 +375,42 @@ macro_rules! data_func_def {
375375

376376
data_func_def!("Tile the input array along specified dimension", tile, af_tile);
377377
data_func_def!("Reorder the array in specified order", reorder, af_reorder);
378-
data_func_def!("Circular shift of values along specified dimension", shift, af_shift);
378+
379+
380+
///"Circular shift of values along specified dimension
381+
///
382+
///# Parameters
383+
///
384+
/// - `input` is the input Array
385+
/// - `offsets` is 4-value tuple that specifies the shift along respective dimension
386+
///
387+
///# Return Values
388+
///
389+
/// An Array with shifted data.
390+
///
391+
///# Examples
392+
///
393+
/// ```rust
394+
/// use arrayfire::{Array, Dim4, print, randu, shift};
395+
/// let a = randu::<f32>(Dim4::new(&[5, 1, 1, 1]));
396+
/// let _a = shift(&a, &[-1i32, 1 , 1, 1]); //shift data one step backward
397+
/// let a_ = shift(&a, &[ 1i32, 1 , 1, 1]); //shift data one step forward
398+
/// print(& a);
399+
/// print(&_a);
400+
/// print(&a_);
401+
/// ```
402+
#[allow(unused_mut)]
403+
pub fn shift(input: &Array, offsets: &[i32; 4]) -> Array {
404+
unsafe {
405+
let mut temp: i64 = 0;
406+
let err_val = af_shift(&mut temp as MutAfArray, input.get() as AfArray,
407+
offsets[0] as c_int, offsets[1] as c_int,
408+
offsets[2] as c_int, offsets[3] as c_int);
409+
HANDLE_ERROR(AfError::from(err_val));
410+
Array::from(temp)
411+
}
412+
}
413+
379414

380415
/// Change the shape of the Array
381416
///

src/defines.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ impl Error for AfError {
102102
AfError::ERR_NOT_CONFIGURED => "This build of ArrayFire does not support this feature",
103103
AfError::ERR_NO_DBL => "This device does not support double",
104104
AfError::ERR_NO_GFX => "This build of ArrayFire has no graphics support",
105-
AfError::ERR_INTERNAL => "Eror either in ArrayFire or in a project upstream",
105+
AfError::ERR_INTERNAL => "Error either in ArrayFire or in a project upstream",
106106
AfError::ERR_UNKNOWN => "Unknown Error",
107107
}
108108
}

src/image/mod.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use array::Array;
44
use defines::{AfError, BorderType, ColorSpace, Connectivity, InterpType, YCCStd, MomentType};
55
use error::HANDLE_ERROR;
66
use util::{AfArray, DimT, HasAfEnum, MutAfArray};
7-
use self::libc::{uint8_t, c_uint, c_int, c_float, c_double};
7+
use self::libc::{uint8_t, c_uint, c_int, c_float, c_double, c_char};
8+
use std::ffi::CString;
89

910
// unused functions from image.h header
1011
// af_load_image_memory
@@ -14,10 +15,10 @@ use self::libc::{uint8_t, c_uint, c_int, c_float, c_double};
1415
#[allow(dead_code)]
1516
extern {
1617
fn af_gradient(dx: MutAfArray, dy: MutAfArray, arr: AfArray) -> c_int;
17-
fn af_load_image(out: MutAfArray, filename: *const u8, iscolor: c_int) -> c_int;
18-
fn af_save_image(filename: *const u8, input: AfArray) -> c_int;
19-
fn af_load_image_native(out: MutAfArray, filename: *const u8) -> c_int;
20-
fn af_save_image_native(filename: *const u8, input: AfArray) -> c_int;
18+
fn af_load_image(out: MutAfArray, filename: *const c_char, iscolor: c_int) -> c_int;
19+
fn af_save_image(filename: *const c_char, input: AfArray) -> c_int;
20+
fn af_load_image_native(out: MutAfArray, filename: *const c_char) -> c_int;
21+
fn af_save_image_native(filename: *const c_char, input: AfArray) -> c_int;
2122

2223
fn af_resize(out: MutAfArray, input: AfArray,
2324
odim0: DimT, odim1: DimT, method: uint8_t) -> c_int;
@@ -135,11 +136,13 @@ pub fn gradient(input: &Array) -> (Array, Array) {
135136
/// An Array with pixel values loaded from the image
136137
#[allow(unused_mut)]
137138
pub fn load_image(filename: String, is_color: bool) -> Array {
139+
let cstr_param = match CString::new(filename) {
140+
Ok(cstr) => cstr,
141+
Err(_) => panic!("CString creation from input filename failed"),
142+
};
138143
unsafe {
139144
let mut temp: i64 = 0;
140-
let err_val = af_load_image(&mut temp as MutAfArray,
141-
filename.clone().as_bytes().as_ptr() as *const u8,
142-
is_color as c_int);
145+
let err_val = af_load_image(&mut temp as MutAfArray, cstr_param.as_ptr(), is_color as c_int);
143146
HANDLE_ERROR(AfError::from(err_val));
144147
Array::from(temp)
145148
}
@@ -165,10 +168,13 @@ pub fn load_image(filename: String, is_color: bool) -> Array {
165168
/// An Array with pixel values loaded from the image
166169
#[allow(unused_mut)]
167170
pub fn load_image_native(filename: String) -> Array {
171+
let cstr_param = match CString::new(filename) {
172+
Ok(cstr) => cstr,
173+
Err(_) => panic!("CString creation from input filename failed"),
174+
};
168175
unsafe {
169176
let mut temp: i64 = 0;
170-
let err_val = af_load_image_native(&mut temp as MutAfArray,
171-
filename.clone().as_bytes().as_ptr() as *const u8);
177+
let err_val = af_load_image_native(&mut temp as MutAfArray, cstr_param.as_ptr());
172178
HANDLE_ERROR(AfError::from(err_val));
173179
Array::from(temp)
174180
}
@@ -182,9 +188,12 @@ pub fn load_image_native(filename: String) -> Array {
182188
/// - `input` is the Array to be stored into the image file
183189
#[allow(unused_mut)]
184190
pub fn save_image(filename: String, input: &Array) {
191+
let cstr_param = match CString::new(filename) {
192+
Ok(cstr) => cstr,
193+
Err(_) => panic!("CString creation from input filename failed"),
194+
};
185195
unsafe {
186-
let err_val = af_save_image(filename.clone().as_bytes().as_ptr() as *const u8,
187-
input.get() as AfArray);
196+
let err_val = af_save_image(cstr_param.as_ptr(), input.get() as AfArray);
188197
HANDLE_ERROR(AfError::from(err_val));
189198
}
190199
}
@@ -207,9 +216,12 @@ pub fn save_image(filename: String, input: &Array) {
207216
/// - `input` is the Array to be saved. Should be U8 for saving 8-bit image, U16 for 16-bit image, and F32 for 32-bit image.
208217
#[allow(unused_mut)]
209218
pub fn save_image_native(filename: String, input: &Array) {
219+
let cstr_param = match CString::new(filename) {
220+
Ok(cstr) => cstr,
221+
Err(_) => panic!("CString creation from input filename failed"),
222+
};
210223
unsafe {
211-
let err_val = af_save_image_native(filename.clone().as_bytes().as_ptr() as *const u8,
212-
input.get() as AfArray);
224+
let err_val = af_save_image_native(cstr_param.as_ptr(), input.get() as AfArray);
213225
HANDLE_ERROR(AfError::from(err_val));
214226
}
215227
}

0 commit comments

Comments
 (0)