diff --git a/examples/helloworld.rs b/examples/helloworld.rs index be21558cd..cae62575b 100644 --- a/examples/helloworld.rs +++ b/examples/helloworld.rs @@ -7,6 +7,7 @@ use af::*; fn main() { set_device(0); info(); + print!("Info String:\n{}", info_string(true)); let num_rows: u64 = 5; let num_cols: u64 = 3; diff --git a/src/device/mod.rs b/src/device/mod.rs index d8a8a0081..ff0e8ac65 100644 --- a/src/device/mod.rs +++ b/src/device/mod.rs @@ -1,13 +1,15 @@ extern crate libc; -use defines::AfError; +use defines::{AfError, DType}; use error::HANDLE_ERROR; -use self::libc::{c_int, size_t, c_char}; -use std::ffi::CString; +use self::libc::{c_int, size_t, c_char, c_void}; +use std::ffi::{CStr, CString}; +use util::free_host; extern { fn af_get_version(major: *mut c_int, minor: *mut c_int, patch: *mut c_int) -> c_int; fn af_info() -> c_int; + fn af_info_string(str: *mut *mut c_char, verbose: bool) -> c_int; fn af_init() -> c_int; fn af_get_device_count(nDevices: *mut c_int) -> c_int; fn af_get_dbl_support(available: *mut c_int, device: c_int) -> c_int; @@ -56,6 +58,29 @@ pub fn info() { } } +/// Return library meta-info as `String` +/// +/// # Examples +/// +/// An example output of `af::info_string` call looks like below +/// +/// ```text +/// ArrayFire v3.0.0 (CUDA, 64-bit Mac OSX, build d8d4b38) +/// Platform: CUDA Toolkit 7, Driver: CUDA Driver Version: 7000 +/// [0] GeForce GT 750M, 2048 MB, CUDA Compute 3.0 +/// ``` +pub fn info_string(verbose: bool) -> String { + let result: String; + unsafe { + let mut tmp: *mut c_char = ::std::ptr::null_mut(); + let err_val = af_info_string(&mut tmp, verbose); + HANDLE_ERROR(AfError::from(err_val)); + result = CStr::from_ptr(tmp).to_string_lossy().into_owned(); + free_host(tmp); + } + result +} + /// Initialize ArrayFire library /// /// 0th device will be the default device unless init call diff --git a/src/lib.rs b/src/lib.rs index 23b2a78dc..a1c5b6fe3 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,7 +40,7 @@ pub use data::{select, selectl, selectr, replace, replace_scalar}; pub use data::{range_t, iota_t, identity_t, constant_t}; mod data; -pub use device::{get_version, info, init, device_count, is_double_available, set_device, get_device}; +pub use device::{get_version, info, info_string, init, device_count, is_double_available, set_device, get_device}; pub use device::{device_mem_info, print_mem_info, set_mem_step_size, get_mem_step_size, device_gc, sync}; mod device; diff --git a/src/util.rs b/src/util.rs index db8740bb2..01f5261ea 100644 --- a/src/util.rs +++ b/src/util.rs @@ -6,11 +6,18 @@ use defines::{SparseFormat, BinaryOp, RandomEngineType}; use error::HANDLE_ERROR; use std::mem; use self::num::Complex; -use self::libc::{uint8_t, c_int, size_t}; +use self::libc::{uint8_t, c_int, size_t, c_void}; + +// This is private in array +// use array::DimT; +type DimT = self::libc::c_longlong; #[allow(dead_code)] extern { fn af_get_size_of(size: *mut size_t, aftype: uint8_t) -> c_int; + + fn af_alloc_host(ptr: *mut *const c_void, bytes: DimT) -> c_int; + fn af_free_host(ptr: *mut c_void) -> c_int; } /// Get size, in bytes, of the arrayfire native type @@ -23,6 +30,25 @@ pub fn get_size(value: DType) -> usize { } } +/// Allocates space using Arrayfire allocator in host memory +pub fn alloc_host(elements: usize, _type: DType) -> *const T { + let ptr: *const T = ::std::ptr::null(); + let bytes = (elements * get_size(_type)) as DimT; + unsafe { + let err_val = af_alloc_host(&mut (ptr as *const c_void), bytes); + HANDLE_ERROR(AfError::from(err_val)); + } + ptr +} + +/// Frees memory allocated by Arrayfire allocator in host memory +pub fn free_host(ptr: *mut T) { + unsafe { + let err_val = af_free_host(ptr as *mut c_void); + HANDLE_ERROR(AfError::from(err_val)); + } +} + impl From for AfError { fn from(t: i32) -> AfError { assert!(AfError::SUCCESS as i32 <= t && t <= AfError::ERR_UNKNOWN as i32);