Skip to content

API Catchup to 3.3.0 version #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 12, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.2.0"
version = "3.3.0"
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 arrayfire
Submodule arrayfire updated 459 files
12 changes: 6 additions & 6 deletions examples/unified.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,29 @@ fn main() {
println!("There are {:?} available backends", get_backend_count().unwrap());
let available = get_available_backends().unwrap();

if available.contains(&Backend::AF_BACKEND_CPU){
if available.contains(&Backend::CPU){
println!("Evaluating CPU Backend...");
let err = set_backend(Backend::AF_BACKEND_CPU);
let err = set_backend(Backend::CPU);
println!("There are {} CPU compute devices", device_count().unwrap());
match err {
Ok(_) => test_backend(),
Err(e) => println!("CPU backend error: {}", e),
};
}

if available.contains(&Backend::AF_BACKEND_CUDA){
if available.contains(&Backend::CUDA){
println!("Evaluating CUDA Backend...");
let err = set_backend(Backend::AF_BACKEND_CUDA);
let err = set_backend(Backend::CUDA);
println!("There are {} CUDA compute devices", device_count().unwrap());
match err {
Ok(_) => test_backend(),
Err(e) => println!("CUDA backend error: {}", e),
};
}

if available.contains(&Backend::AF_BACKEND_OPENCL){
if available.contains(&Backend::OPENCL){
println!("Evaluating OpenCL Backend...");
let err = set_backend(Backend::AF_BACKEND_OPENCL);
let err = set_backend(Backend::OPENCL);
println!("There are {} OpenCL compute devices", device_count().unwrap());
match err {
Ok(_) => test_backend(),
Expand Down
111 changes: 102 additions & 9 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ extern {
fn af_cast(out: MutAfArray, arr: AfArray, aftype: uint8_t) -> c_int;

fn af_get_backend_id(backend: *mut c_int, input: AfArray) -> c_int;

fn af_get_device_id(device: *mut c_int, input: AfArray) -> c_int;

fn af_create_strided_array(arr: MutAfArray, data: *const c_void, offset: DimT,
ndims: c_uint, dims: *const DimT, strides: *const DimT,
aftype: uint8_t) -> c_int;

fn af_get_strides(s0: *mut DimT, s1: *mut DimT, s2: *mut DimT, s3: *mut DimT,
arr: AfArray) -> c_int;

fn af_get_offset(offset: *mut DimT, arr: AfArray) -> c_int;

fn af_is_linear(result: *mut c_int, arr: AfArray) -> c_int;

fn af_is_owner(result: *mut c_int, arr: AfArray) -> c_int;
}

/// A multidimensional data container
Expand Down Expand Up @@ -122,21 +137,68 @@ impl Array {
}
}

/// Constructs a new Array object from strided data
///
/// This data can possiblly offseted using an additiona `offset` parameter.
///
/// # Examples
///
/// ```
/// let values: &[f32] = &[1.0, 2.0, 3.0];
/// let indices = Array::new(Dim4::new(&[3, 1, 1, 1]), values, Aftype::F32).unwrap();
/// ```
#[allow(unused_mut)]
pub fn new_strided<T>(slice: &[T], offset: i64,
dims: Dim4, strides: Dim4,
aftype: Aftype) -> Result<Array, AfError> {
unsafe {
let mut temp: i64 = 0;
let err_val = af_create_strided_array(&mut temp as MutAfArray,
slice.as_ptr() as *const c_void,
offset as DimT,
dims.ndims() as c_uint,
dims.get().as_ptr() as * const c_longlong,
strides.get().as_ptr() as * const c_longlong,
aftype as uint8_t);
match err_val {
0 => Ok(Array {handle: temp}),
_ => Err(AfError::from(err_val)),
}
}
}

/// Returns the backend of the Array
///
/// # Return Values
///
/// Returns an value of type `Backend` which indicates which backend
/// was active when Array was created.
pub fn get_backend(&self) -> Backend {
pub fn get_backend(&self) -> Result<Backend, AfError> {
unsafe {
let mut ret_val: i32 = 0;
af_get_backend_id(&mut ret_val as *mut c_int, self.handle as AfArray);
match ret_val {
1 => Backend::AF_BACKEND_CPU,
2 => Backend::AF_BACKEND_CUDA,
3 => Backend::AF_BACKEND_OPENCL,
_ => Backend::AF_BACKEND_DEFAULT,
let err_val = af_get_backend_id(&mut ret_val as *mut c_int, self.handle as AfArray);
match (err_val, ret_val) {
(0, 1) => Ok(Backend::CPU),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good way to squash the error check in. 👍

(0, 2) => Ok(Backend::CUDA),
(0, 3) => Ok(Backend::OPENCL),
_ => Err(AfError::from(err_val)),
}
}
}

/// Returns the device identifier(integer) on which the Array was created
///
/// # Return Values
///
/// Return the device id on which Array was created.
pub fn get_device_id(&self) -> Result<i32, AfError> {
unsafe {
let mut ret_val: i32 = 0;
let err_val = af_get_device_id(&mut ret_val as *mut c_int, self.handle as AfArray);
match err_val {
0 => Ok(ret_val),
_ => Err(AfError::from(err_val)),

}
}
}
Expand Down Expand Up @@ -172,8 +234,8 @@ impl Array {
let mut ret1: i64 = 0;
let mut ret2: i64 = 0;
let mut ret3: i64 = 0;
let err_val = af_get_dims(&mut ret0 as *mut c_longlong, &mut ret1 as *mut c_longlong,
&mut ret2 as *mut c_longlong, &mut ret3 as *mut c_longlong,
let err_val = af_get_dims(&mut ret0 as *mut DimT, &mut ret1 as *mut DimT,
&mut ret2 as *mut DimT, &mut ret3 as *mut DimT,
self.handle as AfArray);
match err_val {
0 => Ok(Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64])),
Expand All @@ -182,6 +244,23 @@ impl Array {
}
}

/// Returns the strides of the Array
pub fn strides(&self) -> Result<Dim4, AfError> {
unsafe {
let mut ret0: i64 = 0;
let mut ret1: i64 = 0;
let mut ret2: i64 = 0;
let mut ret3: i64 = 0;
let err_val = af_get_strides(&mut ret0 as *mut DimT, &mut ret1 as *mut DimT,
&mut ret2 as *mut DimT, &mut ret3 as *mut DimT,
self.handle as AfArray);
match err_val {
0 => Ok(Dim4::new(&[ret0 as u64, ret1 as u64, ret2 as u64, ret3 as u64])),
_ => Err(AfError::from(err_val)),
}
}
}

/// Returns the number of dimensions of the Array
pub fn numdims(&self) -> Result<u32, AfError> {
unsafe {
Expand All @@ -194,6 +273,18 @@ impl Array {
}
}

/// Returns the offset to the pointer from where data begins
pub fn offset(&self) -> Result<i64, AfError> {
unsafe {
let mut ret_val: i64 = 0;
let err_val = af_get_offset(&mut ret_val as *mut DimT, self.handle as AfArray);
match err_val {
0 => Ok(ret_val),
_ => Err(AfError::from(err_val)),
}
}
}

/// Returns the native FFI handle for Rust object `Array`
pub fn get(&self) -> i64 {
self.handle
Expand Down Expand Up @@ -247,6 +338,8 @@ impl Array {
is_func!(is_floating, af_is_floating);
is_func!(is_integer, af_is_integer);
is_func!(is_bool, af_is_bool);
is_func!(is_linear, af_is_linear);
is_func!(is_owner, af_is_owner);

/// Cast the Array data type to `target_type`
pub fn cast(&self, target_type: Aftype) -> Result<Array, AfError> {
Expand Down
23 changes: 20 additions & 3 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern {
fn af_set_backend(bknd: uint8_t) -> c_int;
fn af_get_backend_count(num_backends: *mut c_uint) -> c_int;
fn af_get_available_backends(backends: *mut c_int) -> c_int;
fn af_get_active_backend(backend: *mut c_int) -> c_int;
}

/// Toggle backends between cuda, opencl or cpu
Expand Down Expand Up @@ -47,12 +48,28 @@ pub fn get_available_backends() -> Result<Vec<Backend>, AfError> {
match err_val {
0 => {
let mut b = Vec::new();
if temp & 0b0100 == 0b0100 { b.push(Backend::AF_BACKEND_OPENCL); }
if temp & 0b0010 == 0b0010 { b.push(Backend::AF_BACKEND_CUDA); }
if temp & 0b0001 == 0b0001 { b.push(Backend::AF_BACKEND_CPU); }
if temp & 0b0100 == 0b0100 { b.push(Backend::OPENCL); }
if temp & 0b0010 == 0b0010 { b.push(Backend::CUDA); }
if temp & 0b0001 == 0b0001 { b.push(Backend::CPU); }
Ok(b)
},
_ => Err(AfError::from(err_val)),
}
}
}

/// Get current active backend
#[allow(unused_mut)]
pub fn get_active_backend() -> Result<Backend, AfError> {
unsafe {
let mut temp: i32 = 0;
let err_val = af_get_active_backend(&mut temp as *mut c_int);
match (err_val, temp) {
(0, 0) => Ok(Backend::DEFAULT),
(0, 1) => Ok(Backend::CPU),
(0, 2) => Ok(Backend::CUDA),
(0, 4) => Ok(Backend::OPENCL),
_ => Err(AfError::from(err_val)),
}
}
}
33 changes: 25 additions & 8 deletions src/defines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub enum AfError {
ERR_DIFF_TYPE = 205,
/// Function does not support GFOR / batch mode
ERR_BATCH = 207,
/// Input does not belong to the current device
ERR_DEVICE = 208,
// 300-399 Errors for missing software features
/// The option is not supported
ERR_NOT_SUPPORTED = 301,
Expand All @@ -51,22 +53,22 @@ pub enum AfError {
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Backend {
/// Default backend order: OpenCL -> CUDA -> CPU
AF_BACKEND_DEFAULT = 0,
DEFAULT = 0,
/// CPU a.k.a sequential algorithms
AF_BACKEND_CPU = 1,
CPU = 1,
/// CUDA Compute Backend
AF_BACKEND_CUDA = 2,
CUDA = 2,
/// OpenCL Compute Backend
AF_BACKEND_OPENCL = 4
OPENCL = 4
}

impl Display for Backend {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
let text = match *self {
Backend::AF_BACKEND_OPENCL => "OpenCL",
Backend::AF_BACKEND_CUDA => "Cuda",
Backend::AF_BACKEND_CPU => "CPU",
Backend::AF_BACKEND_DEFAULT => "Default",
Backend::OPENCL => "OpenCL",
Backend::CUDA => "Cuda",
Backend::CPU => "CPU",
Backend::DEFAULT => "Default",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner. Good call

};
write!(f, "{}", text)
}
Expand All @@ -91,6 +93,7 @@ impl Error for AfError {
AfError::ERR_TYPE => "The type is not supported by this function",
AfError::ERR_DIFF_TYPE => "The type of input arrays are not compatible",
AfError::ERR_BATCH => "Function does not support GFOR / batch mode",
AfError::ERR_DEVICE => "Array does not belong to device",
AfError::ERR_NOT_SUPPORTED => "The option is not supported",
AfError::ERR_NOT_CONFIGURED => "This build of ArrayFire does not support this feature",
AfError::ERR_NO_DBL => "This device does not support double",
Expand Down Expand Up @@ -305,3 +308,17 @@ pub enum HomographyType {
/// Least Median of Squares
LMEDS = 1,
}

/// Plotting markers
#[repr(C)]
#[derive(Copy, Clone)]
pub enum MarkerType {
NONE = 0,
POINT = 1,
CIRCLE = 2,
SQUARE = 3,
TRIANGLE = 4,
CROSS = 5,
PLUS = 6,
STAR = 7
}
Loading