From a11744fc0d7396d8e2a73b80121f9d238690e162 Mon Sep 17 00:00:00 2001 From: pradeep Date: Thu, 23 Jul 2015 13:11:49 -0400 Subject: [PATCH 1/3] graphics module * wrapper for graphics API from arrayfire * Fix in image::{medfilt, minfilt, maxfilt} API * Modified ColorMap enum to use C representation * Corrections to examples to reflect new changes * Graphics examples: snow(noise), histogram --- Cargo.toml | 8 ++ build.conf | 2 +- examples/histogram.rs | 46 ++++++++++ examples/pi.rs | 4 +- examples/snow.rs | 25 ++++++ src/arith/mod.rs | 2 + src/defines.rs | 12 +++ src/graphics.rs | 191 ++++++++++++++++++++++++++++++++++++++++++ src/image/mod.rs | 12 +-- src/lib.rs | 5 +- src/util.rs | 8 ++ 11 files changed, 306 insertions(+), 9 deletions(-) create mode 100644 examples/histogram.rs create mode 100644 examples/snow.rs create mode 100644 src/graphics.rs diff --git a/Cargo.toml b/Cargo.toml index 4dc2a3337..acd8889fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,11 @@ path = "examples/helloworld.rs" [[example]] name = "pi" path = "examples/pi.rs" + +[[example]] +name = "snow" +path = "examples/snow.rs" + +[[example]] +name = "histogram" +path = "examples/histogram.rs" diff --git a/build.conf b/build.conf index 56c5e6491..83e1a7677 100644 --- a/build.conf +++ b/build.conf @@ -12,7 +12,7 @@ "build_cpu": "ON", "build_examples": "OFF", "build_test": "OFF", - "build_graphics": "OFF", + "build_graphics": "ON", "glew_static": "OFF", "freeimage_type": "DYNAMIC", diff --git a/examples/histogram.rs b/examples/histogram.rs new file mode 100644 index 000000000..48a7aa1ef --- /dev/null +++ b/examples/histogram.rs @@ -0,0 +1,46 @@ +extern crate arrayfire as af; + +use af::Window; +use std::env; +use std::path::PathBuf; + +#[allow(unused_variables)] +#[allow(unused_must_use)] +fn main() { + af::set_device(0); + af::info(); + + let assets_dir = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("arrayfire").join("assets").join("examples").join("images"); + + let img_wnd = match Window::new(480, 640, String::from("Input Image")) { + Ok(v) => { v.set_position(100, 100).unwrap(); v }, + Err(e)=> panic!("Window creation failed, exiting: {:?}", e), + }; + + let hst_wnd = match Window::new(512, 512, String::from("Input Image Histogram")) { + Ok(v) => { v.set_position(600, 100).unwrap(); v }, + Err(e)=> panic!("Window creation failed, exiting: {:?}", e), + }; + + let (man, hst) = match af::load_image(format!("{}/man.jpg", assets_dir.display()), false) { + Ok(v) => match af::histogram(&v, 256, 0.0, 255.0) { + Ok(h) => (v, h), + Err(e)=> panic!("Histogram computation failed, exiting: {:?}", e), + }, + Err(e)=> panic!("Image loading failed, exiting: {:?}", e), + }; + + let disp_img = man.dims() + .and_then(|x| af::constant(255 as f32, x)) + .and_then(|x| af::div(&man, &x)) + .unwrap(); + + loop { + img_wnd.draw_image(&disp_img, None); + hst_wnd.draw_hist(&hst, 0.0, 255.0, None); + + if img_wnd.is_closed().unwrap() == true { break; } + if hst_wnd.is_closed().unwrap() == true { break; } + } +} diff --git a/examples/pi.rs b/examples/pi.rs index d65800f8e..2a176daec 100644 --- a/examples/pi.rs +++ b/examples/pi.rs @@ -19,9 +19,9 @@ fn main() { let start = PreciseTime::now(); for bench_iter in 0..100 { - let pi_val = af::add(&(x*x), &(y*y)) + let pi_val = af::add(x*x, y*y) .and_then( |z| af::sqrt(&z) ) - .and_then( |z| af::le(&z, &af::constant(1, dims).unwrap()) ) + .and_then( |z| af::le(z, af::constant(1, dims).unwrap()) ) .and_then( |z| af::sum_all(&z) ) .map( |z| z.0 * 4.0/(samples as f64) ) .unwrap(); diff --git a/examples/snow.rs b/examples/snow.rs new file mode 100644 index 000000000..3cf1455ad --- /dev/null +++ b/examples/snow.rs @@ -0,0 +1,25 @@ +extern crate arrayfire as af; + +use af::Dim4; +use af::Window; + +#[allow(unused_variables)] +#[allow(unused_must_use)] +fn main() { + af::set_device(0); + af::info(); + + let wnd = match Window::new(1280, 720, String::from("Snow")) { + Ok(v) => v, + Err(e)=> panic!("Window creation failed, exiting"), + }; + + let dims = Dim4::new(&[1280, 720, 3, 1]); + + loop { + af::randu(dims, af::Aftype::F32).as_ref() + .map(|arr| wnd.draw_image(arr, None)); + + if wnd.is_closed().unwrap() == true { break; } + } +} diff --git a/src/arith/mod.rs b/src/arith/mod.rs index 2a655077a..f81b3fb18 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -207,6 +207,8 @@ macro_rules! convertable_type_def { ) } +convertable_type_def!(u64); +convertable_type_def!(i64); convertable_type_def!(f64); convertable_type_def!(f32); convertable_type_def!(i32); diff --git a/src/defines.rs b/src/defines.rs index fbafc4a8e..59e647449 100644 --- a/src/defines.rs +++ b/src/defines.rs @@ -168,3 +168,15 @@ pub enum NormType { MATRIX_2 = 6, MATRIX_L_PQ = 7, } + +#[repr(C)] +#[derive(Copy, Clone)] +pub enum ColorMap { + DEFAULT = 0, + SPECTRUM= 1, + COLORS = 2, + RED = 3, + MOOD = 4, + HEAT = 5, + BLUE = 6, +} diff --git a/src/graphics.rs b/src/graphics.rs new file mode 100644 index 000000000..09b3c87df --- /dev/null +++ b/src/graphics.rs @@ -0,0 +1,191 @@ +extern crate libc; + +use array::Array; +use defines::AfError; +use defines::ColorMap; +use self::libc::{c_int, c_uint, c_double}; + +type MutWndHandle = *mut self::libc::c_ulonglong; +type WndHandle = self::libc::c_ulonglong; +type AfArray = self::libc::c_longlong; +type CellPtr = *const self::libc::c_void; + +#[allow(dead_code)] +extern { + fn af_create_window(out: MutWndHandle, w: c_int, h: c_int, title: *const u8) -> c_int; + fn af_set_position(wnd: WndHandle, x: c_uint, y: c_uint) -> c_int; + fn af_set_title(wnd: WndHandle, title: *const u8) -> c_int; + fn af_draw_image(wnd: WndHandle, arr: AfArray, props: CellPtr) -> c_int; + fn af_draw_plot(wnd: WndHandle, x: AfArray, y: AfArray, props: CellPtr) -> c_int; + fn af_grid(wnd: WndHandle, rows: c_int, cols: c_int) -> c_int; + fn af_show(wnd: WndHandle) -> c_int; + fn af_is_window_closed(out: *mut c_int, wnd: WndHandle) -> c_int; + fn af_destroy_window(wnd: WndHandle) -> c_int; + + fn af_draw_hist(wnd: WndHandle, x: AfArray, + minval: c_double, maxval: c_double, props: CellPtr) -> c_int; +} + +#[repr(C)] +pub struct Cell { + pub row: i32, + pub col: i32, + pub title: String, + pub cmap: ColorMap, +} + +#[derive(Clone)] +pub struct Window { + handle: u64, + row: i32, + col: i32, + cmap: ColorMap, +} + +impl From for Window { + fn from(t: u64) -> Window { + Window {handle: t, row: -1, col: -1, cmap: ColorMap::DEFAULT} + } +} + +impl Drop for Window { + fn drop(&mut self) { + unsafe { + let err_val = af_destroy_window(self.handle); + match err_val { + 0 => (), + _ => panic!("Window object destruction failed with error code: {}", err_val), + } + } + } +} + +impl Window { + #[allow(unused_mut)] + pub fn new(width: i32, height: i32, title: String) -> Result { + unsafe { + let mut temp: u64 = 0; + let err_val = af_create_window(&mut temp as MutWndHandle, + width as c_int, height as c_int, + title.as_bytes().as_ptr() as *const u8); + match err_val { + 0 => Ok(Window::from(temp)), + _ => Err(AfError::from(err_val)), + } + } + } + + pub fn set_position(&self, x: u32, y: u32) -> Result<(), AfError> { + unsafe { + let err_val = af_set_position(self.handle as WndHandle, x as c_uint, y as c_uint); + match err_val { + 0 => Ok(()), + _ => Err(AfError::from(err_val)), + } + } + } + + pub fn set_title(&self, title: String) -> Result<(), AfError> { + unsafe { + let err_val = af_set_title(self.handle as WndHandle, + title.as_bytes().as_ptr() as *const u8); + match err_val { + 0 => Ok(()), + _ => Err(AfError::from(err_val)), + } + } + } + + pub fn set_colormap(&mut self, cmap: ColorMap) { + self.cmap = cmap; + } + + pub fn is_closed(&self) -> Result { + unsafe { + let mut temp: i32 = 1; + let err_val = af_is_window_closed(&mut temp as *mut c_int, self.handle as WndHandle); + match err_val { + 0 => Ok(temp > 0), + _ => Err(AfError::from(err_val)), + } + } + } + + pub fn grid(&self, rows: i32, cols: i32) -> Result<(), AfError> { + unsafe { + let err_val = af_grid(self.handle as WndHandle, rows as c_int, cols as c_int); + match err_val { + 0 => Ok(()), + _ => Err(AfError::from(err_val)), + } + } + } + + pub fn show(&mut self) -> Result<(), AfError> { + unsafe { + let err_val = af_show(self.handle as WndHandle); + if err_val != 0 { + return Err(AfError::from(err_val)); + } + self.row = -1; + self.col = -1; + Ok(()) + } + } + + pub fn set_view(&mut self, r: i32, c: i32) { + self.row = r; + self.col = c; + } + + pub fn draw_image(&self, input: &Array, title: Option) { + let tstr = match title { + Some(s) => s, + None => format!("Cell({},{}))", self.col, self.row) + }; + let cprops = &Cell {row: self.row, col: self.col, title: tstr.clone(), cmap: self.cmap}; + unsafe { + let err_val = af_draw_image(self.handle as WndHandle, input.get() as AfArray, + cprops as *const Cell as CellPtr); + match err_val { + 0 => (), + _ => panic!("Rendering the image failed: {}", err_val), + } + } + } + + pub fn draw_plot(&self, x: &Array, y: &Array, title: Option) { + let tstr = match title { + Some(s) => s, + None => format!("Cell({},{}))", self.col, self.row) + }; + let cprops = &Cell {row: self.row, col: self.col, title: tstr.clone(), cmap: self.cmap}; + unsafe { + let err_val = af_draw_plot(self.handle as WndHandle, + x.get() as AfArray, + y.get() as AfArray, + cprops as *const Cell as CellPtr); + match err_val { + 0 => (), + _ => panic!("Rendering the image failed: {}", err_val), + } + } + } + + pub fn draw_hist(&self, hst: &Array, minval: f64, maxval: f64, title: Option) { + let tstr = match title { + Some(s) => s, + None => format!("Cell({},{}))", self.col, self.row) + }; + let cprops = &Cell {row: self.row, col: self.col, title: tstr.clone(), cmap: self.cmap}; + unsafe { + let err_val = af_draw_hist(self.handle as WndHandle, hst.get() as AfArray, + minval as c_double, maxval as c_double, + cprops as *const Cell as CellPtr); + match err_val { + 0 => (), + _ => panic!("Rendering the image failed: {}", err_val), + } + } + } +} diff --git a/src/image/mod.rs b/src/image/mod.rs index 710edbd80..8dbcaa49f 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -89,11 +89,12 @@ pub fn gradient(input: &Array) -> Result<(Array, Array), AfError> { } #[allow(unused_mut)] -pub fn load_image(filename: &[u8], is_color: bool) -> Result { +pub fn load_image(filename: String, is_color: bool) -> Result { unsafe { let mut temp: i64 = 0; let err_val = af_load_image(&mut temp as MutAfArray, - filename.as_ptr() as *const u8, is_color as c_int); + filename.as_bytes().as_ptr() as *const u8, + is_color as c_int); match err_val { 0 => Ok(Array::from(temp)), _ => Err(AfError::from(err_val)), @@ -102,9 +103,10 @@ pub fn load_image(filename: &[u8], is_color: bool) -> Result { } #[allow(unused_mut)] -pub fn save_image(filename: &[u8], input: &Array) -> Result<(), AfError> { +pub fn save_image(filename: String, input: &Array) -> Result<(), AfError> { unsafe { - let err_val = af_save_image(filename.as_ptr() as *const u8, input.get() as AfArray); + let err_val = af_save_image(filename.as_bytes().as_ptr() as *const u8, + input.get() as AfArray); match err_val { 0 => Ok(()), _ => Err(AfError::from(err_val)), @@ -266,7 +268,7 @@ pub fn mean_shift(input: &Array, spatial_sigma: f32, chromatic_sigma: f32, macro_rules! filt_func_def { ($fn_name: ident, $ffi_name: ident) => ( #[allow(unused_mut)] - pub fn $fn_name(input: &Array, wlen: i64, wwid: i64, + pub fn $fn_name(input: &Array, wlen: u64, wwid: u64, etype: BorderType) -> Result { unsafe { let mut temp: i64 = 0; diff --git a/src/lib.rs b/src/lib.rs index 420022db2..38743e67a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ mod data; pub use device::{get_version, info, set_device}; mod device; -pub use defines::{Aftype, AfError}; +pub use defines::{Aftype, AfError, ColorMap}; pub use defines::{InterpType, BorderType, MatchType, NormType}; pub use defines::{Connectivity, ConvMode, ConvDomain, ColorSpace, MatProp}; mod defines; @@ -40,6 +40,9 @@ mod defines; pub use dim4::Dim4; mod dim4; +pub use graphics::Window; +mod graphics; + pub use image::{gaussian_kernel, load_image, save_image}; pub use image::{resize, transform, rotate, translate, scale, skew}; pub use image::{dilate, dilate3, erode, erode3, minfilt, maxfilt}; diff --git a/src/util.rs b/src/util.rs index a89af9665..a26a74c0c 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,6 +5,7 @@ use defines::ConvMode; use defines::ConvDomain; use defines::MatProp; use defines::MatchType; +use defines::ColorMap; use std::mem; impl From for AfError { @@ -64,3 +65,10 @@ pub fn to_u32(t: MatProp) -> u32 { MatProp::BLOCKDIAG => 8192, } } + +impl From for ColorMap { + fn from(t: i32) -> ColorMap { + assert!(ColorMap::DEFAULT as i32 <= t && t <= ColorMap::BLUE as i32); + unsafe { mem::transmute(t) } + } +} From 507c226a5185c54d8445aa7577cce2a4f4ae922a Mon Sep 17 00:00:00 2001 From: pradeep Date: Sun, 2 Aug 2015 13:26:44 -0400 Subject: [PATCH 2/3] Removed Convertable trait for Result Also, made necessary changes to examples --- examples/helloworld.rs | 49 ++++++++++++++++++++++++------------------ examples/histogram.rs | 14 ++++++------ examples/pi.rs | 19 ++++++++-------- examples/snow.rs | 9 ++++---- src/arith/mod.rs | 6 ------ 5 files changed, 48 insertions(+), 49 deletions(-) diff --git a/examples/helloworld.rs b/examples/helloworld.rs index a5dfb6719..4ad74a101 100644 --- a/examples/helloworld.rs +++ b/examples/helloworld.rs @@ -1,38 +1,45 @@ extern crate arrayfire as af; -use af::Dim4; -use af::Array; +use af::*; #[allow(unused_must_use)] fn main() { - af::set_device(0); - af::info(); + set_device(0); + info(); let dims = Dim4::new(&[5, 3, 1, 1]); println!("Create a 5-by-3 matrix of random floats on the GPU"); - let a = af::randu(dims, af::Aftype::F32).unwrap(); - af::print(&a); + let a = randu(dims, Aftype::F32).unwrap(); + print(&a); println!("Element-wise arithmetic"); - let b = af::add(af::sin(&a), 1.5).unwrap(); - let b2 = af::add(af::sin(&a), af::cos(&a)).unwrap(); + let b = sin(&a) + .and_then(|x| add(x, 1.5)) + .unwrap(); + + let b2 = sin(&a). + and_then(|x| { + cos(&a) + .and_then(|y| add(x, y)) + }) + .unwrap(); let b3 = ! &a; - println!("sin(a) + 1.5 => "); af::print(&b); - println!("sin(a) + cos(a) => "); af::print(&b2); - println!("!a => "); af::print(&b3); + println!("sin(a) + 1.5 => "); print(&b); + println!("sin(a) + cos(a) => "); print(&b2); + println!("!a => "); print(&b3); let test = &a + &b; - println!("a + b"); af::print(&test); + println!("a + b"); print(&test); // printf("Negate the first three elements of second column\n"); // B(seq(0, 2), 1) = B(seq(0, 2), 1) * -1; // af_print(B); println!("Fourier transform the result"); - let c = &af::fft(&b, 1.0, 0).unwrap(); - af::print(&c); + let c = &fft(&b, 1.0, 0).unwrap(); + print(&c); // printf("Grab last row\n"); // array c = C.row(end); @@ -41,8 +48,8 @@ fn main() { println!("Create 2-by-3 matrix from host data"); let d_dims = Dim4::new(&[2, 3, 1, 1]); let d_input: [i32; 6] = [1, 2, 3, 4, 5, 6]; - let d = &Array::new(d_dims, &d_input, af::Aftype::S32).unwrap(); - af::print(d); + let d = &Array::new(d_dims, &d_input, Aftype::S32).unwrap(); + print(d); // printf("Copy last column onto first\n"); // D.col(0) = D.col(end); @@ -50,12 +57,12 @@ fn main() { // // Sort A println!("Sort A and print sorted array and corresponding indices"); - let (vals, inds) = af::sort_index(&a, 0, true).unwrap(); - af::print(&vals); - af::print(&inds); + let (vals, inds) = sort_index(&a, 0, true).unwrap(); + print(&vals); + print(&inds); println!("u8 constant array"); - let u8_cnst = &af::constant(1 as u8, dims).unwrap(); - af::print(u8_cnst); + let u8_cnst = &constant(1 as u8, dims).unwrap(); + print(u8_cnst); println!("Is u8_cnst array float precision type ? {}", u8_cnst.is_single().unwrap()); } diff --git a/examples/histogram.rs b/examples/histogram.rs index 48a7aa1ef..9f9e113aa 100644 --- a/examples/histogram.rs +++ b/examples/histogram.rs @@ -1,14 +1,14 @@ extern crate arrayfire as af; -use af::Window; +use af::*; use std::env; use std::path::PathBuf; #[allow(unused_variables)] #[allow(unused_must_use)] fn main() { - af::set_device(0); - af::info(); + set_device(0); + info(); let assets_dir = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap()) .join("arrayfire").join("assets").join("examples").join("images"); @@ -23,8 +23,8 @@ fn main() { Err(e)=> panic!("Window creation failed, exiting: {:?}", e), }; - let (man, hst) = match af::load_image(format!("{}/man.jpg", assets_dir.display()), false) { - Ok(v) => match af::histogram(&v, 256, 0.0, 255.0) { + let (man, hst) = match load_image(format!("{}/man.jpg", assets_dir.display()), false) { + Ok(v) => match histogram(&v, 256, 0.0, 255.0) { Ok(h) => (v, h), Err(e)=> panic!("Histogram computation failed, exiting: {:?}", e), }, @@ -32,8 +32,8 @@ fn main() { }; let disp_img = man.dims() - .and_then(|x| af::constant(255 as f32, x)) - .and_then(|x| af::div(&man, &x)) + .and_then(|x| constant(255 as f32, x)) + .and_then(|x| div(man, x)) .unwrap(); loop { diff --git a/examples/pi.rs b/examples/pi.rs index 2a176daec..d4750d1e6 100644 --- a/examples/pi.rs +++ b/examples/pi.rs @@ -2,27 +2,26 @@ extern crate arrayfire as af; extern crate time; use time::PreciseTime; -use af::Dim4; -use af::Aftype; +use af::*; #[allow(unused_must_use)] #[allow(unused_variables)] fn main() { - af::set_device(0); - af::info(); + set_device(0); + info(); let samples = 20_000_000; let dims = Dim4::new(&[samples, 1, 1, 1]); - let x = &af::randu(dims, Aftype::F32).unwrap(); - let y = &af::randu(dims, Aftype::F32).unwrap(); + let x = &randu(dims, Aftype::F32).unwrap(); + let y = &randu(dims, Aftype::F32).unwrap(); let start = PreciseTime::now(); for bench_iter in 0..100 { - let pi_val = af::add(x*x, y*y) - .and_then( |z| af::sqrt(&z) ) - .and_then( |z| af::le(z, af::constant(1, dims).unwrap()) ) - .and_then( |z| af::sum_all(&z) ) + let pi_val = add(x*x, y*y) + .and_then( |z| sqrt(&z) ) + .and_then( |z| le(z, constant(1, dims).unwrap()) ) + .and_then( |z| sum_all(&z) ) .map( |z| z.0 * 4.0/(samples as f64) ) .unwrap(); } diff --git a/examples/snow.rs b/examples/snow.rs index 3cf1455ad..d812680d9 100644 --- a/examples/snow.rs +++ b/examples/snow.rs @@ -1,13 +1,12 @@ extern crate arrayfire as af; -use af::Dim4; -use af::Window; +use af::*; #[allow(unused_variables)] #[allow(unused_must_use)] fn main() { - af::set_device(0); - af::info(); + set_device(0); + info(); let wnd = match Window::new(1280, 720, String::from("Snow")) { Ok(v) => v, @@ -17,7 +16,7 @@ fn main() { let dims = Dim4::new(&[1280, 720, 3, 1]); loop { - af::randu(dims, af::Aftype::F32).as_ref() + randu(dims, Aftype::F32).as_ref() .map(|arr| wnd.draw_image(arr, None)); if wnd.is_closed().unwrap() == true { break; } diff --git a/src/arith/mod.rs b/src/arith/mod.rs index f81b3fb18..e2e792e61 100644 --- a/src/arith/mod.rs +++ b/src/arith/mod.rs @@ -221,12 +221,6 @@ impl Convertable for Array { } } -impl Convertable for Result { - fn convert(&self) -> Array { - self.clone().unwrap() - } -} - macro_rules! overloaded_binary_func { ($fn_name: ident, $help_name: ident, $ffi_name: ident) => ( fn $help_name(lhs: &Array, rhs: &Array) -> Result { From d15eaf626f470246315c04299943a5b4b9569385 Mon Sep 17 00:00:00 2001 From: pradeep Date: Sun, 2 Aug 2015 14:12:31 -0400 Subject: [PATCH 3/3] Added Error & Display traits for AfError type --- examples/helloworld.rs | 16 ++++++++++------ examples/histogram.rs | 8 ++++---- src/defines.rs | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/examples/helloworld.rs b/examples/helloworld.rs index 4ad74a101..779325ff9 100644 --- a/examples/helloworld.rs +++ b/examples/helloworld.rs @@ -10,7 +10,10 @@ fn main() { let dims = Dim4::new(&[5, 3, 1, 1]); println!("Create a 5-by-3 matrix of random floats on the GPU"); - let a = randu(dims, Aftype::F32).unwrap(); + let a = match randu(dims, Aftype::F32) { + Ok(value) => value, + Err(error) => panic!("{}", error), + }; print(&a); println!("Element-wise arithmetic"); @@ -38,8 +41,7 @@ fn main() { // af_print(B); println!("Fourier transform the result"); - let c = &fft(&b, 1.0, 0).unwrap(); - print(&c); + fft(&b, 1.0, 0).map(|x| print(&x)); // printf("Grab last row\n"); // array c = C.row(end); @@ -57,9 +59,11 @@ fn main() { // // Sort A println!("Sort A and print sorted array and corresponding indices"); - let (vals, inds) = sort_index(&a, 0, true).unwrap(); - print(&vals); - print(&inds); + sort_index(&a, 0, true) + .map(| x | { + print(&x.0); + print(&x.1); + }); println!("u8 constant array"); let u8_cnst = &constant(1 as u8, dims).unwrap(); diff --git a/examples/histogram.rs b/examples/histogram.rs index 9f9e113aa..da07773bb 100644 --- a/examples/histogram.rs +++ b/examples/histogram.rs @@ -15,20 +15,20 @@ fn main() { let img_wnd = match Window::new(480, 640, String::from("Input Image")) { Ok(v) => { v.set_position(100, 100).unwrap(); v }, - Err(e)=> panic!("Window creation failed, exiting: {:?}", e), + Err(e)=> panic!("Window creation failed, exiting: {}", e), }; let hst_wnd = match Window::new(512, 512, String::from("Input Image Histogram")) { Ok(v) => { v.set_position(600, 100).unwrap(); v }, - Err(e)=> panic!("Window creation failed, exiting: {:?}", e), + Err(e)=> panic!("Window creation failed, exiting: {}", e), }; let (man, hst) = match load_image(format!("{}/man.jpg", assets_dir.display()), false) { Ok(v) => match histogram(&v, 256, 0.0, 255.0) { Ok(h) => (v, h), - Err(e)=> panic!("Histogram computation failed, exiting: {:?}", e), + Err(e)=> panic!("Histogram computation failed, exiting: {}", e), }, - Err(e)=> panic!("Image loading failed, exiting: {:?}", e), + Err(e)=> panic!("Image loading failed, exiting: {}", e), }; let disp_img = man.dims() diff --git a/src/defines.rs b/src/defines.rs index 59e647449..3fc0bc818 100644 --- a/src/defines.rs +++ b/src/defines.rs @@ -1,3 +1,7 @@ +use std::error::Error; +use std::fmt::{Display, Formatter}; +use std::fmt::Error as FmtError; + #[repr(C)] #[derive(Clone, Copy, Debug)] pub enum AfError { @@ -74,6 +78,35 @@ pub enum AfError { ERR_UNKNOWN = 999 } +impl Display for AfError { + fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { + write!(f, "{}", self.description()) + } +} + +impl Error for AfError { + fn description(&self) -> &str { + match *self { + AfError::SUCCESS => "Function returned successfully", + AfError::ERR_NO_MEM => "The system or device ran out of memory", + AfError::ERR_DRIVER => "Device driver error", + AfError::ERR_RUNTIME => "Error in runtime environment", + AfError::ERR_INVALID_ARRAY => "Input is not a valid Array Object", + AfError::ERR_ARG => "One of the function arguments is incorrect", + AfError::ERR_SIZE => "The size is incorrect", + 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_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", + AfError::ERR_NO_GFX => "This build of ArrayFire was not built with graphics or this device does not support graphics", + AfError::ERR_INTERNAL => "There was an internal error in either ArrayFire or upstream project", + AfError::ERR_UNKNOWN => "Unkown Error", + } + } +} + #[derive(Copy, Clone)] pub enum Aftype { F32 = 0,