diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..0337a51f1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,75 @@ +--- +name: A generic bug Report +about: Create a bug report to help us improve ArrayFire +title: "[BUG]" +labels: 'Bug' +assignees: '' +--- + + +Description +=========== + + +Reproducible Code and/or Steps +------------------------------ + + +System Information +------------------ + + +Checklist +--------- + +- [ ] Using the latest available ArrayFire release +- [ ] GPU drivers are up to date diff --git a/.github/ISSUE_TEMPLATE/build_error.md b/.github/ISSUE_TEMPLATE/build_error.md new file mode 100644 index 000000000..f13c9172b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/build_error.md @@ -0,0 +1,26 @@ +--- +name: Build Error +about: Create a report for errors during the crate build +title: "[Build]" +labels: 'Bug,Build' +assignees: '9prady9' +--- + +Description +=========== + + +Build Environment +----------------- +Compiler version: +Operating system: +Build environment: + +Error Log +--------- + +``` + +``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..0efe0ffb5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,15 @@ +--- +name: Feature Request +about: Suggest a new idea for Rust wrapper of ArrayFire +title: 'Feature' +labels: 'Feature' +assignees: '9prady9' + +--- + +Description +=========== + diff --git a/.github/ISSUE_TEMPLATE/performance_issue.md b/.github/ISSUE_TEMPLATE/performance_issue.md new file mode 100644 index 000000000..df002a5aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/performance_issue.md @@ -0,0 +1,39 @@ +--- +name: Performance Issue +about: For Issues related to lackluster performance +title: "[Perf]" +labels: 'Bug,Upstream' +assignees: '9prady9' + +--- + +Description +=========== + + + + + +Reproducible Code +----------------- + + +System Information +------------------ +ArrayFire Version: +Device: +Operating System: +Driver version: + +Checklist +--------- +- [ ] I have read [timing ArrayFire C++ API](http://arrayfire.org/docs/timing.htm) diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 000000000..5ff5421dd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,14 @@ +--- +name: Question +about: General questions and potential issues +title: "[Question]" +labels: 'Question' +assignees: '9prady9' + +--- + +Before asking a question on github, please consider if it is more appropriate for these other platforms: + +* [Slack Chat](https://join.slack.com/t/arrayfire-org/shared_invite/MjI4MjIzMDMzMTczLTE1MDI5ODg4NzYtN2QwNGE3ODA5OQ) +* [Google Groups](https://groups.google.com/forum/#!forum/arrayfire-users) +* ArrayFire Services: [Consulting](http://arrayfire.com/consulting/) | [Support](http://arrayfire.com/support/) | [Training](http://arrayfire.com/training/) diff --git a/.github/PULL_REQUEST_TEMPLATE/documentation.md b/.github/PULL_REQUEST_TEMPLATE/documentation.md new file mode 100644 index 000000000..9531979da --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/documentation.md @@ -0,0 +1,20 @@ + + +Description +----------- + +Fixes: # ... + +Checklist +--------- +- [ ] Rebased on latest master +- [ ] Documentation Generation Successful +- [ ] Documentation Tests Pass diff --git a/.github/PULL_REQUEST_TEMPLATE/generic_pr_template.md b/.github/PULL_REQUEST_TEMPLATE/generic_pr_template.md new file mode 100644 index 000000000..fb83f2360 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/generic_pr_template.md @@ -0,0 +1,36 @@ + + + +Description +----------- + +Fixes: # ... + +Changes to Users +---------------- + + +Checklist +--------- + +- [ ] Rebased on latest master +- [ ] Code compiles +- [ ] Tests pass +- [ ] Functions documented diff --git a/.github/PULL_REQUEST_TEMPLATE/new_example.md b/.github/PULL_REQUEST_TEMPLATE/new_example.md new file mode 100644 index 000000000..f823278e6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/new_example.md @@ -0,0 +1,14 @@ + + +Description +----------- + + +Checklist +--------- +- [ ] Rebased on latest master +- [ ] Code compiles diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2512e920..12c257f5c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: name: Build and Test Wrapper runs-on: ubuntu-18.04 env: - AF_VER: 3.7.0 + AF_VER: 3.7.2 steps: - name: Checkout Repository uses: actions/checkout@master diff --git a/src/dim4.rs b/src/dim4.rs index dabaee460..565b0f294 100644 --- a/src/dim4.rs +++ b/src/dim4.rs @@ -1,5 +1,5 @@ use std::fmt; -use std::ops::Index; +use std::ops::{Index, IndexMut}; /// Dim4 is used to store [Array](./struct.Array.html) dimensions #[derive(Copy, Clone, PartialEq, Debug)] @@ -35,6 +35,23 @@ impl Index for Dim4 { } } +/// Enables index operation for Dim4 to modify dimensions +/// +/// # Examples +/// +/// ```rust +/// use arrayfire::Dim4; +/// +/// let mut dims = Dim4::new(&[4, 4, 2, 1]); +/// dims[2] = 4; +/// println!("Dimensions: {}", dims); // note that third dimension changed to 4 +/// ``` +impl IndexMut for Dim4 { + fn index_mut(&mut self, _index: usize) -> &mut Self::Output { + &mut self.dims[_index] + } +} + /// Enables use of Dim4 objects for printing it to display /// /// # Examples diff --git a/src/macros.rs b/src/macros.rs index ddee31df5..105e59683 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -55,7 +55,7 @@ macro_rules! mem_info { [$msg: expr] => { { - let (abytes, abuffs, lbytes, lbuffs) = device_mem_info(); + let (abytes, abuffs, lbytes, lbuffs) = $crate::device_mem_info(); println!("AF Memory: {:?}", $msg); println!("Allocated [Bytes | Buffers] = [ {} | {} ]", abytes, abuffs); println!("In Use [Bytes | Buffers] = [ {} | {} ]", lbytes, lbuffs); @@ -92,7 +92,7 @@ macro_rules! join_many { $( temp_vec.push($x); )* - join_many($dim, temp_vec) + $crate::join_many($dim, temp_vec) } }; } @@ -112,7 +112,7 @@ macro_rules! join_many { macro_rules! af_print { [$msg: expr, $x: expr] => { { - print_gen(String::from($msg), &$x, Some(4)); + $crate::print_gen(String::from($msg), &$x, Some(4)); } }; } @@ -130,3 +130,100 @@ macro_rules! eval { } }; } + +/// Create a dim4 object from provided dimensions +/// +/// The user can pass 1 or more sizes and the left over values will default to 1. +#[macro_export] +macro_rules! dim4 { + ($dim0:literal) => { + $crate::Dim4::new(&[$dim0, 1, 1, 1]) + }; + ($dim0:literal, $dim1:literal) => { + $crate::Dim4::new(&[$dim0, $dim1, 1, 1]) + }; + ($dim0:literal, $dim1:literal, $dim2:literal) => { + $crate::Dim4::new(&[$dim0, $dim1, $dim2, 1]) + }; + ($dim0:literal, $dim1:literal, $dim2:literal, $dim3:literal) => { + $crate::Dim4::new(&[$dim0, $dim1, $dim2, $dim3]) + }; +} + +/// Create a sequence object +/// +/// If type is not provided, then the Seq will default to i32 type +#[macro_export] +macro_rules! seq { + () => { + $crate::Seq::::default() + }; + ($sty:ty; $start:literal : $end:literal : $step:literal) => { + $crate::Seq::<$sty>::new($start, $end, $step) + }; + ($start:literal : $end:literal : $step:literal) => { + $crate::Seq::::new($start, $end, $step) + }; +} + +/// Indexing into an existing Array +/// +/// This macro call with return an Array that has a view of another Array. The Array returned due to +/// the indexing operation will follow copy-on-write semantics. The Array identifier taken by this +/// macro is passed to the relevant internal functions as a borrowed reference. Thus, this identifier +/// will be still available for futher use after the macro call. +/// +/// The following types of inputs are matched by this macro. +/// +/// - A simple Array identifier. +/// - An Array with slicing info for indexing. +/// - An Array with slicing info and other arrays used for indexing. +#[macro_export] +macro_rules! view { + (@af_max_dims) => { + 4 + }; + ( $array_ident:ident ) => { + $array_ident.clone() + }; + ( $array_ident:ident [ $($start:literal : $end:literal : $step:literal),+ ] ) => { + { + let AF_MAX_DIMS: usize = view!(@af_max_dims); + let mut seq_vec = Vec::<$crate::Seq>::with_capacity(AF_MAX_DIMS); + $( + seq_vec.push($crate::seq!($start:$end:$step)); + )* + for span_place_holder in seq_vec.len()..AF_MAX_DIMS { + seq_vec.push($crate::seq!()); + } + $crate::index(&$array_ident, &seq_vec) + } + }; + (@set_indexer $idim:expr, $idxr:ident, $lterm:expr) => { + { + $idxr.set_index(&$lterm, $idim, None); + } + }; + (@set_indexer $idim:expr, $idxr:ident, $hterm:expr, $($tterm:expr),*) => { + { + $idxr.set_index(&$hterm, $idim, None); + view!(@set_indexer $idim + 1, $idxr, $($tterm),*); + } + }; + ($array_ident:ident [ $($_e:expr),+ ]) => { + { + let AF_MAX_DIMS: u32 = view!(@af_max_dims); + let span = $crate::seq!(); + let mut idxrs = $crate::Indexer::default(); + + view!(@set_indexer 0, idxrs, $($_e),*); + + let mut dimIx = idxrs.len() as u32; + while dimIx < AF_MAX_DIMS { + idxrs.set_index(&span, dimIx, None); + dimIx += 1; + } + $crate::index_gen(&$array_ident, idxrs) + } + }; +} diff --git a/tests/index_macro.rs b/tests/index_macro.rs new file mode 100644 index 000000000..f7dc2716c --- /dev/null +++ b/tests/index_macro.rs @@ -0,0 +1,32 @@ +use arrayfire::{af_print, randu, seq, view, Array, Dim4}; + +#[test] +fn array_view() { + let dims = Dim4::new(&[5, 5, 2, 1]); + let a = randu::(dims); + let b = a.clone(); + let c = a.clone(); + let d = a.clone(); + let e = a.clone(); + + let v = view!(a); + af_print!("v = a[None]", v); + + let m = view!(c[1:3:1, 1:3:2]); + af_print!("m = c[:, :]", m); + + let x = seq!(1:3:1); + let y = seq!(1:3:2); + let u = view!(b[x, y]); + af_print!("u = b[seq(), seq()]", u); + + let values: [u32; 3] = [1, 2, 3]; + let indices = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); + let indices2 = Array::new(&values, Dim4::new(&[3, 1, 1, 1])); + + let w = view!(d[indices, indices2]); + af_print!("w = d[Array, Array]", w); + + let z = view!(e[indices, y]); + af_print!("z = e[Array, Seq]", z); +} diff --git a/tests/seq_macro.rs b/tests/seq_macro.rs new file mode 100644 index 000000000..8b069d2da --- /dev/null +++ b/tests/seq_macro.rs @@ -0,0 +1,17 @@ +use arrayfire::{af_print, dim4, index, randu, seq}; + +#[test] +fn array_view() { + let _dim1d = dim4!(2); + let _dim2d = dim4!(2, 3); + let _dim3d = dim4!(2, 3, 4); + + let mut dim4d = dim4!(5, 3, 2, 1); + dim4d[2] = 1; + + let a = randu::(dim4d); + let seqs = &[seq!(1:3:1), seq!()]; + let sub = index(&a, seqs); + af_print!("A", a); + af_print!("Indexed A", sub); +}