arrayfire 3.5.0

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.
Documentation
extern crate libc;

use defines::{AfError, Backend};
use error::HANDLE_ERROR;
use self::libc::{c_int, c_uint, uint8_t};

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
///
/// # Parameters
///
/// - `backend` to which to switch to
pub fn set_backend(backend: Backend) {
    unsafe {
        let err_val = af_set_backend(backend as uint8_t);
        HANDLE_ERROR(AfError::from(err_val));
    }
}

/// Get the available backend count
#[allow(unused_mut)]
pub fn get_backend_count() -> u32 {
    unsafe {
        let mut temp: u32 = 0;
        let err_val = af_get_backend_count(&mut temp as *mut c_uint);
        HANDLE_ERROR(AfError::from(err_val));
        temp
    }
}


/// Get the available backends
#[allow(unused_mut)]
pub fn get_available_backends() -> Vec<Backend> {
    unsafe {
        let mut temp: i32 = 0;
        let err_val = af_get_available_backends(&mut temp as *mut c_int);
        HANDLE_ERROR(AfError::from(err_val));

        let mut b = Vec::new();
        if temp & 0b0100 == 0b0100 { b.push(Backend::OPENCL); }
        if temp & 0b0010 == 0b0010 { b.push(Backend::CUDA); }
        if temp & 0b0001 == 0b0001 { b.push(Backend::CPU); }

        b
    }
}

/// Get current active backend
#[allow(unused_mut)]
pub fn get_active_backend() -> Backend {
    unsafe {
        let mut temp: i32 = 0;
        let err_val = af_get_active_backend(&mut temp as *mut c_int);
        HANDLE_ERROR(AfError::from(err_val));
        match (err_val, temp) {
            (0, 0) => Backend::DEFAULT,
            (0, 1) => Backend::CPU,
            (0, 2) => Backend::CUDA,
            (0, 4) => Backend::OPENCL,
            _ => panic!("Invalid backend retrieved, undefined behavior."),
        }
    }
}