Skip to content

Commit 7c2e386

Browse files
committed
Merge pull request #27 from arrayfire/feature/index
Indexing
2 parents c15abc1 + 714771e commit 7c2e386

File tree

8 files changed

+270
-10
lines changed

8 files changed

+270
-10
lines changed

arrayfire

Submodule arrayfire updated 544 files

examples/helloworld.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ fn main() {
77
set_device(0);
88
info();
99

10-
let dims = Dim4::new(&[5, 3, 1, 1]);
10+
let num_rows: u64 = 5;
11+
let num_cols: u64 = 3;
12+
let values: &[f32] = &[1.0, 2.0, 3.0];
13+
let indices = Array::new(Dim4::new(&[3, 1, 1, 1]), values, Aftype::F32).unwrap();
14+
15+
let dims = Dim4::new(&[num_rows, num_cols, 1, 1]);
1116

1217
println!("Create a 5-by-3 matrix of random floats on the GPU");
1318
let a = match randu(dims, Aftype::F32) {
@@ -36,16 +41,35 @@ fn main() {
3641
let test = &a + &b;
3742
println!("a + b"); print(&test);
3843

44+
// Index array using sequences
45+
let seqs = &[Seq::new(1.0, 3.0, 1.0), Seq::default()];
46+
let sub = index(&a, seqs).unwrap();
47+
println!("a(seq(1,3,1), span)"); print(&sub);
48+
49+
//Index array using array and sequence
50+
let seq4gen = Seq::new(0.0, 2.0, 1.0);
51+
52+
let mut idxrs = match Indexer::new() {
53+
Ok(v) => v,
54+
Err(e) => panic!("{}",e),
55+
};
56+
idxrs.set_index(&indices, 0, None);
57+
idxrs.set_index(&seq4gen, 1, Some(false));
58+
59+
let sub2 = index_gen(&a, idxrs).unwrap();
60+
println!("a(indices, seq(0, 2, 1))"); print(&sub2);
61+
3962
// printf("Negate the first three elements of second column\n");
4063
// B(seq(0, 2), 1) = B(seq(0, 2), 1) * -1;
4164
// af_print(B);
4265

4366
println!("Fourier transform the result");
4467
fft(&b, 1.0, 0).map(|x| print(&x));
4568

46-
// printf("Grab last row\n");
47-
// array c = C.row(end);
48-
// af_print(c);
69+
println!("Grab last row & col of the random matrix");
70+
print(&a);
71+
print(&row(&a, num_rows - 1).unwrap());
72+
print(&col(&a, num_cols - 1).unwrap());
4973

5074
println!("Create 2-by-3 matrix from host data");
5175
let d_dims = Dim4::new(&[2, 3, 1, 1]);

src/array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl Array {
153153
self.handle
154154
}
155155

156-
pub fn host(&self, data:&mut [f64]) -> Result<(), AfError> {
156+
pub fn host<T>(&self, data: &mut [T]) -> Result<(), AfError> {
157157
unsafe {
158158
let ret_val = af_get_data_ptr(data.as_mut_ptr() as *mut c_void, self.handle as AfArray);
159159
match ret_val {

src/graphics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl Window {
6767
let mut temp: u64 = 0;
6868
let err_val = af_create_window(&mut temp as MutWndHandle,
6969
width as c_int, height as c_int,
70-
title.as_bytes().as_ptr() as *const u8);
70+
title.clone().as_bytes().as_ptr() as *const u8);
7171
match err_val {
7272
0 => Ok(Window::from(temp)),
7373
_ => Err(AfError::from(err_val)),
@@ -88,7 +88,7 @@ impl Window {
8888
pub fn set_title(&self, title: String) -> Result<(), AfError> {
8989
unsafe {
9090
let err_val = af_set_title(self.handle as WndHandle,
91-
title.as_bytes().as_ptr() as *const u8);
91+
title.clone().as_bytes().as_ptr() as *const u8);
9292
match err_val {
9393
0 => Ok(()),
9494
_ => Err(AfError::from(err_val)),

src/image/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub fn load_image(filename: String, is_color: bool) -> Result<Array, AfError> {
9393
unsafe {
9494
let mut temp: i64 = 0;
9595
let err_val = af_load_image(&mut temp as MutAfArray,
96-
filename.as_bytes().as_ptr() as *const u8,
96+
filename.clone().as_bytes().as_ptr() as *const u8,
9797
is_color as c_int);
9898
match err_val {
9999
0 => Ok(Array::from(temp)),
@@ -105,7 +105,7 @@ pub fn load_image(filename: String, is_color: bool) -> Result<Array, AfError> {
105105
#[allow(unused_mut)]
106106
pub fn save_image(filename: String, input: &Array) -> Result<(), AfError> {
107107
unsafe {
108-
let err_val = af_save_image(filename.as_bytes().as_ptr() as *const u8,
108+
let err_val = af_save_image(filename.clone().as_bytes().as_ptr() as *const u8,
109109
input.get() as AfArray);
110110
match err_val {
111111
0 => Ok(()),

src/index.rs

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
extern crate libc;
2+
3+
use array::Array;
4+
use defines::AfError;
5+
use seq::Seq;
6+
use self::libc::{c_int, c_uint, c_longlong};
7+
8+
type MutAfIndex = *mut self::libc::c_longlong;
9+
type MutAfArray = *mut self::libc::c_longlong;
10+
type AfArray = self::libc::c_longlong;
11+
type DimT = self::libc::c_longlong;
12+
type IndexT = self::libc::c_longlong;
13+
14+
#[allow(dead_code)]
15+
extern {
16+
fn af_create_indexers(indexers: MutAfIndex) -> c_int;
17+
fn af_set_array_indexer(indexer: MutAfIndex, idx: AfArray, dim: DimT) -> c_int;
18+
fn af_set_seq_indexer(indexer: MutAfIndex, idx: *const Seq, dim: DimT, is_batch: c_int) -> c_int;
19+
fn af_release_indexers(indexers: MutAfIndex) -> c_int;
20+
21+
fn af_index(out: MutAfArray, input: AfArray, ndims: c_uint, index: *const Seq) -> c_int;
22+
fn af_lookup(out: MutAfArray, arr: AfArray, indices: AfArray, dim: c_uint) -> c_int;
23+
fn af_assign_seq(out: MutAfArray, lhs: AfArray, ndims: c_uint, indices: *const Seq, rhs: AfArray) -> c_int;
24+
fn af_index_gen(out: MutAfArray, input: AfArray, ndims: DimT, indices: *const IndexT) -> c_int;
25+
fn af_assign_gen(out: MutAfArray, lhs: AfArray, ndims: DimT, indices: *const IndexT, rhs: AfArray) -> c_int;
26+
}
27+
28+
pub struct Indexer {
29+
handle: i64,
30+
count: u32,
31+
}
32+
33+
pub trait Indexable {
34+
fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option<bool>) -> Result<(), AfError>;
35+
}
36+
37+
impl Indexable for Array {
38+
#[allow(unused_variables)]
39+
fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option<bool>) -> Result<(), AfError> {
40+
unsafe {
41+
let err_val = af_set_array_indexer(idxr.clone().get() as MutAfIndex,
42+
self.get() as AfArray,
43+
dim as DimT);
44+
match err_val {
45+
0 => Ok(()),
46+
_ => Err(AfError::from(err_val)),
47+
}
48+
}
49+
}
50+
}
51+
52+
impl Indexable for Seq {
53+
fn set(&self, idxr: &Indexer, dim: u32, is_batch: Option<bool>) -> Result<(), AfError> {
54+
unsafe {
55+
let err_val = af_set_seq_indexer(idxr.clone().get() as MutAfIndex, self as *const Seq,
56+
dim as DimT, is_batch.unwrap() as c_int);
57+
match err_val {
58+
0 => Ok(()),
59+
_ => Err(AfError::from(err_val)),
60+
}
61+
}
62+
}
63+
}
64+
65+
impl Indexer {
66+
#[allow(unused_mut)]
67+
pub fn new() -> Result<Indexer, AfError> {
68+
unsafe {
69+
let mut temp: i64 = 0;
70+
let err_val = af_create_indexers(&mut temp as MutAfIndex);
71+
match err_val {
72+
0 => Ok(Indexer{handle: temp, count: 0}),
73+
_ => Err(AfError::from(err_val)),
74+
}
75+
}
76+
}
77+
78+
pub fn set_index<T: Indexable>(&mut self, idx: &T, dim: u32, is_batch: Option<bool>) -> Result<(), AfError> {
79+
self.count = self.count + 1;
80+
idx.set(self, dim, is_batch)
81+
}
82+
83+
pub fn get(&self) -> i64 {
84+
self.handle
85+
}
86+
87+
pub fn len(&self) -> u32 {
88+
self.count
89+
}
90+
}
91+
92+
impl Drop for Indexer {
93+
fn drop(&mut self) {
94+
unsafe {
95+
let ret_val = af_release_indexers(self.handle as MutAfIndex);
96+
match ret_val {
97+
0 => (),
98+
_ => panic!("Failed to release indexers resource: {}", ret_val),
99+
}
100+
}
101+
}
102+
}
103+
104+
pub fn index(input: &Array, seqs: &[Seq]) -> Result<Array, AfError> {
105+
unsafe {
106+
let mut temp: i64 = 0;
107+
let err_val = af_index(&mut temp as MutAfArray
108+
, input.get() as AfArray, seqs.len() as u32
109+
, seqs.as_ptr() as *const Seq);
110+
match err_val {
111+
0 => Ok(Array::from(temp)),
112+
_ => Err(AfError::from(err_val)),
113+
}
114+
}
115+
}
116+
117+
pub fn row(input: &Array, row_num: u64) -> Result<Array, AfError> {
118+
let dims_err = input.dims();
119+
let dims = match dims_err {
120+
Ok(dim) => dim.clone(),
121+
Err(e) => panic!("Error unwrapping dims in row(): {}", e),
122+
};
123+
124+
index(input, &[Seq::new(row_num as f64, row_num as f64, 1.0)
125+
,Seq::new(0.0, dims[1] as f64 - 1.0, 1.0)])
126+
}
127+
128+
pub fn col(input: &Array, col_num: u64) -> Result<Array, AfError> {
129+
let dims_err = input.dims();
130+
let dims = match dims_err {
131+
Ok(dim) => dim.clone(),
132+
Err(e) => panic!("Error unwrapping dims in row(): {}", e),
133+
};
134+
135+
index(input, &[Seq::new(0.0, dims[0] as f64 - 1.0, 1.0)
136+
,Seq::new(col_num as f64, col_num as f64, 1.0)])
137+
}
138+
139+
pub fn lookup(input: &Array, indices: &Array, seq_dim: i32) -> Result<Array, AfError> {
140+
unsafe {
141+
let mut temp: i64 = 0;
142+
let err_val = af_lookup(&mut temp as MutAfArray, input.get() as AfArray,
143+
indices.get() as AfArray, seq_dim as c_uint);
144+
match err_val {
145+
0 => Ok(Array::from(temp)),
146+
_ => Err(AfError::from(err_val)),
147+
}
148+
}
149+
}
150+
151+
pub fn assign_seq(lhs: &Array, ndims: usize, seqs: &[Seq], rhs: &Array) -> Result<Array, AfError> {
152+
unsafe{
153+
let mut temp: i64 = 0;
154+
let err_val = af_assign_seq(&mut temp as MutAfArray, lhs.get() as AfArray,
155+
ndims as c_uint, seqs.as_ptr() as *const Seq,
156+
rhs.get() as AfArray);
157+
match err_val {
158+
0 => Ok(Array::from(temp)),
159+
_ => Err(AfError::from(err_val)),
160+
}
161+
}
162+
}
163+
164+
pub fn index_gen(input: &Array, indices: Indexer) -> Result<Array, AfError> {
165+
unsafe{
166+
let mut temp: i64 = 0;
167+
let err_val = af_index_gen(&mut temp as MutAfArray, input.get() as AfArray,
168+
indices.len() as DimT, indices.get() as *const IndexT);
169+
match err_val {
170+
0 => Ok(Array::from(temp)),
171+
_ => Err(AfError::from(err_val)),
172+
}
173+
}
174+
}
175+
176+
pub fn assign_gen(lhs: &Array, indices: &Indexer, rhs: &Array) -> Result<Array, AfError> {
177+
unsafe{
178+
let mut temp: i64 = 0;
179+
let err_val = af_assign_gen(&mut temp as MutAfArray, lhs.get() as AfArray,
180+
indices.len() as DimT, indices.get() as *const IndexT,
181+
rhs.get() as AfArray);
182+
match err_val {
183+
0 => Ok(Array::from(temp)),
184+
_ => Err(AfError::from(err_val)),
185+
}
186+
}
187+
}

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ mod defines;
4444
pub use dim4::Dim4;
4545
mod dim4;
4646

47+
pub use index::{Indexer, index, row, col, lookup, assign_seq, index_gen, assign_gen};
48+
mod index;
49+
50+
pub use seq::Seq;
51+
mod seq;
52+
4753
pub use graphics::Window;
4854
mod graphics;
4955

src/seq.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
extern crate libc;
2+
3+
use std::fmt;
4+
use std::default::Default;
5+
use self::libc::{c_double};
6+
7+
#[derive(Copy, Clone)]
8+
#[repr(C)]
9+
pub struct Seq {
10+
begin: c_double,
11+
end: c_double,
12+
step: c_double,
13+
}
14+
15+
impl Default for Seq {
16+
fn default() -> Seq {
17+
Seq { begin: 1.0, end: 1.0, step: 0.0, }
18+
}
19+
}
20+
21+
impl fmt::Display for Seq {
22+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23+
write!(f, "[begin: {}, end: {}, step: {}]", self.begin, self.end, self.step)
24+
}
25+
}
26+
27+
impl Seq {
28+
pub fn new(begin: f64, end: f64, step: f64) -> Seq {
29+
Seq { begin: begin, end: end, step: step, }
30+
}
31+
32+
pub fn begin(&self) -> f64 {
33+
self.begin as f64
34+
}
35+
36+
pub fn end(&self) -> f64 {
37+
self.end as f64
38+
}
39+
40+
pub fn step(&self) -> f64 {
41+
self.step as f64
42+
}
43+
}

0 commit comments

Comments
 (0)