Skip to content

Commit

Permalink
Merge pull request #127 from arrayfire/devel
Browse files Browse the repository at this point in the history
v3.4.3 devel to master
  • Loading branch information
9prady9 authored Apr 10, 2017
2 parents e1ce525 + 4ca32a9 commit 2609c90
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "arrayfire"
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."
version = "3.4.2"
version = "3.4.3"
documentation = "http://arrayfire.github.io/arrayfire-rust/arrayfire/index.html"
homepage = "https://github.com/arrayfire/arrayfire"
repository = "https://github.com/arrayfire/arrayfire-rust"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ first.
3. Make sure you add the path to library files to your path environment variables.
- On Linux & OSX: do `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$AF_PATH/lib`
- On Windows: Add `%AF_PATH%\lib` to your PATH environment variable.
4. Add `arrayfire = "3.4.2"` to the dependencies section of your project's Cargo.toml file - 3.4.2
4. Add `arrayfire = "3.4.3"` to the dependencies section of your project's Cargo.toml file - 3.4.3
is the lastest version of crate.

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).
Expand Down
48 changes: 38 additions & 10 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,19 +357,49 @@ fn blob_backends(conf: &Config, build_dir: &std::path::PathBuf) -> (Vec<String>,
if conf.use_lib {
let afpath = match env::var("AF_PATH") {
Ok(af_path) => PathBuf::from(&af_path),
Err(_) => panic!("Error use_lib is defined, but AF_PATH is not defined"),
Err(_) => {
println!("WARNING! USE_LIB IS DEFINED, BUT AF_PATH IS NOT FOUND,");
println!(" TRYING TO FIND LIBRARIES FROM KNOWN DEFAULT LOCATIONS");

if cfg!(target_os = "windows") {
PathBuf::from("C:/Program Files/ArrayFire/v3/")
} else {
PathBuf::from("/usr/local/")
}
},
};

let libpath = afpath.join("lib");
backend_dirs.push(libpath.to_str().to_owned().unwrap().to_string());

if !cfg!(target_os = "windows") {
backend_dirs.push(String::from("/opt/arrayfire-3/lib"));
backend_dirs.push(String::from("/usr/lib"));
}
} else {
backend_dirs.push(build_dir.join("package/lib").to_str().to_owned().unwrap().to_string());
}

let lib_dir = PathBuf::from(backend_dirs.last().unwrap());
let mut uni_lib_exists = false;
let mut cud_lib_exists = false;
let mut ocl_lib_exists = false;

for backend_dir in backend_dirs.iter() {
let lib_dir = PathBuf::from(backend_dir);

let cud_lib_file_to_check = if cfg!(windows) {WIN_CUDA_LIB_NAME} else {UNIX_CUDA_LIB_NAME};
cud_lib_exists = cud_lib_exists || backend_exists(&lib_dir.join(cud_lib_file_to_check).to_string_lossy());

let ocl_lib_file_to_check = if cfg!(windows) {WIN_OCL_LIB_NAME} else {UNIX_OCL_LIB_NAME};
ocl_lib_exists = ocl_lib_exists || backend_exists(&lib_dir.join(ocl_lib_file_to_check).to_string_lossy());

let uni_lib_file_to_check = if cfg!(windows) {WIN_UNI_LIB_NAME} else {UNIX_UNI_LIB_NAME};
uni_lib_exists = uni_lib_exists || backend_exists(&lib_dir.join(uni_lib_file_to_check).to_string_lossy());
}

if ! conf.use_lib {
// blob in cuda deps
let mut lib_file_to_check = if cfg!(windows) {WIN_CUDA_LIB_NAME} else {UNIX_CUDA_LIB_NAME};
if backend_exists(&lib_dir.join(lib_file_to_check).to_string_lossy()) {
if cud_lib_exists {
if cfg!(windows) {
backend_dirs.push(format!("{}\\lib\\x64", conf.cuda_sdk));
backend_dirs.push(format!("{}\\nvvm\\lib\\x64", conf.cuda_sdk));
Expand All @@ -389,8 +419,8 @@ fn blob_backends(conf: &Config, build_dir: &std::path::PathBuf) -> (Vec<String>,
}

//blob in opencl deps
lib_file_to_check = if cfg!(windows) {WIN_OCL_LIB_NAME} else {UNIX_OCL_LIB_NAME};
if backend_exists(&lib_dir.join(lib_file_to_check).to_string_lossy()) {

if ocl_lib_exists {
if ! cfg!(target_os = "macos"){
backends.push("OpenCL".to_string());
}
Expand All @@ -413,14 +443,12 @@ fn blob_backends(conf: &Config, build_dir: &std::path::PathBuf) -> (Vec<String>,

if conf.build_graphics=="ON" {
if !conf.use_lib {
backend_dirs.push(build_dir.join("third_party/forge/lib")
.to_str().to_owned().unwrap().to_string());
backend_dirs.push(build_dir.join("third_party/forge/lib").to_str().to_owned().unwrap().to_string());
}
}
}

let lib_file_to_check = if cfg!(windows) {WIN_UNI_LIB_NAME} else {UNIX_UNI_LIB_NAME};
if backend_exists(&lib_dir.join(lib_file_to_check).to_string_lossy()) {
if uni_lib_exists {
backends.push("af".to_string());
if !conf.use_lib && conf.build_graphics=="ON" {
backends.push("forge".to_string());
Expand Down
17 changes: 15 additions & 2 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ extern {
/// A multidimensional data container
///
/// Currently, Array objects can store only data until four dimensions
///
/// ### NOTE
///
/// All operators(traits) from std::ops module implemented for Array object
/// carry out element wise operations. For example, `*` does multiplication of
/// elements at corresponding locations in two different Arrays.
pub struct Array {
handle: i64,
}
Expand Down Expand Up @@ -296,7 +302,7 @@ impl Array {

/// Makes an copy of the Array
///
/// Internally, this is handled by reference counting
/// This does a deep copy of the data into a new Array
pub fn copy(&self) -> Array {
unsafe {
let mut temp: i64 = 0;
Expand Down Expand Up @@ -383,7 +389,14 @@ impl From<i64> for Array {
}
}

/// Used for incrementing the reference count of Array's native resource
/// Returns a new Array object after incrementing the reference count of native resource
///
/// Cloning an Array does not do a deep copy of the underlying array data. It increments the
/// reference count of native resource and returns you the new reference in the form a new Array
/// object.
///
/// To create a deep copy use
/// [copy()](http://arrayfire.org/arrayfire-rust/arrayfire/struct.Array.html#method.copy)
impl Clone for Array {
fn clone(&self) -> Array {
unsafe {
Expand Down
2 changes: 1 addition & 1 deletion src/blas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn matmul(lhs: &Array, rhs: &Array,

/// Calculate the dot product of vectors.
///
/// 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.
/// Scalar dot product between two vectors. Also referred to as the inner product. This function returns the scalar product of two equal sized vectors.
///
/// # Parameters
///
Expand Down
39 changes: 37 additions & 2 deletions src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extern {

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

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

data_func_def!("Tile the input array along specified dimension", tile, af_tile);
data_func_def!("Reorder the array in specified order", reorder, af_reorder);
data_func_def!("Circular shift of values along specified dimension", shift, af_shift);


///"Circular shift of values along specified dimension
///
///# Parameters
///
/// - `input` is the input Array
/// - `offsets` is 4-value tuple that specifies the shift along respective dimension
///
///# Return Values
///
/// An Array with shifted data.
///
///# Examples
///
/// ```rust
/// use arrayfire::{Array, Dim4, print, randu, shift};
/// let a = randu::<f32>(Dim4::new(&[5, 1, 1, 1]));
/// let _a = shift(&a, &[-1i32, 1 , 1, 1]); //shift data one step backward
/// let a_ = shift(&a, &[ 1i32, 1 , 1, 1]); //shift data one step forward
/// print(& a);
/// print(&_a);
/// print(&a_);
/// ```
#[allow(unused_mut)]
pub fn shift(input: &Array, offsets: &[i32; 4]) -> Array {
unsafe {
let mut temp: i64 = 0;
let err_val = af_shift(&mut temp as MutAfArray, input.get() as AfArray,
offsets[0] as c_int, offsets[1] as c_int,
offsets[2] as c_int, offsets[3] as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
}


/// Change the shape of the Array
///
Expand Down
2 changes: 1 addition & 1 deletion src/defines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl Error for AfError {
AfError::ERR_NOT_CONFIGURED => "This build of ArrayFire does not support this feature",
AfError::ERR_NO_DBL => "This device does not support double",
AfError::ERR_NO_GFX => "This build of ArrayFire has no graphics support",
AfError::ERR_INTERNAL => "Eror either in ArrayFire or in a project upstream",
AfError::ERR_INTERNAL => "Error either in ArrayFire or in a project upstream",
AfError::ERR_UNKNOWN => "Unknown Error",
}
}
Expand Down
40 changes: 26 additions & 14 deletions src/image/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use array::Array;
use defines::{AfError, BorderType, ColorSpace, Connectivity, InterpType, YCCStd, MomentType};
use error::HANDLE_ERROR;
use util::{AfArray, DimT, HasAfEnum, MutAfArray};
use self::libc::{uint8_t, c_uint, c_int, c_float, c_double};
use self::libc::{uint8_t, c_uint, c_int, c_float, c_double, c_char};
use std::ffi::CString;

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

fn af_resize(out: MutAfArray, input: AfArray,
odim0: DimT, odim1: DimT, method: uint8_t) -> c_int;
Expand Down Expand Up @@ -135,11 +136,13 @@ pub fn gradient(input: &Array) -> (Array, Array) {
/// An Array with pixel values loaded from the image
#[allow(unused_mut)]
pub fn load_image(filename: String, is_color: bool) -> Array {
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let mut temp: i64 = 0;
let err_val = af_load_image(&mut temp as MutAfArray,
filename.clone().as_bytes().as_ptr() as *const u8,
is_color as c_int);
let err_val = af_load_image(&mut temp as MutAfArray, cstr_param.as_ptr(), is_color as c_int);
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
Expand All @@ -165,10 +168,13 @@ pub fn load_image(filename: String, is_color: bool) -> Array {
/// An Array with pixel values loaded from the image
#[allow(unused_mut)]
pub fn load_image_native(filename: String) -> Array {
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let mut temp: i64 = 0;
let err_val = af_load_image_native(&mut temp as MutAfArray,
filename.clone().as_bytes().as_ptr() as *const u8);
let err_val = af_load_image_native(&mut temp as MutAfArray, cstr_param.as_ptr());
HANDLE_ERROR(AfError::from(err_val));
Array::from(temp)
}
Expand All @@ -182,9 +188,12 @@ pub fn load_image_native(filename: String) -> Array {
/// - `input` is the Array to be stored into the image file
#[allow(unused_mut)]
pub fn save_image(filename: String, input: &Array) {
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let err_val = af_save_image(filename.clone().as_bytes().as_ptr() as *const u8,
input.get() as AfArray);
let err_val = af_save_image(cstr_param.as_ptr(), input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
}
Expand All @@ -207,9 +216,12 @@ pub fn save_image(filename: String, input: &Array) {
/// - `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.
#[allow(unused_mut)]
pub fn save_image_native(filename: String, input: &Array) {
let cstr_param = match CString::new(filename) {
Ok(cstr) => cstr,
Err(_) => panic!("CString creation from input filename failed"),
};
unsafe {
let err_val = af_save_image_native(filename.clone().as_bytes().as_ptr() as *const u8,
input.get() as AfArray);
let err_val = af_save_image_native(cstr_param.as_ptr(), input.get() as AfArray);
HANDLE_ERROR(AfError::from(err_val));
}
}
Expand Down

0 comments on commit 2609c90

Please sign in to comment.