From 0c1a3d749efcb2112ec73e3adf8b75951175aaff Mon Sep 17 00:00:00 2001 From: bluss Date: Fri, 20 Sep 2019 17:39:56 +0200 Subject: [PATCH] FIX: Update par_azip!() to use the same syntax as azip!() We simplify the duplication in par_azip a lot, since we can now just reuse `azip`'s internal rule and pass it the name of the finisher method, which is `par_apply`. --- benches/par_rayon.rs | 2 +- src/parallel/zipmacro.rs | 57 +++++----------------------------------- tests/par_azip.rs | 11 ++++---- 3 files changed, 13 insertions(+), 57 deletions(-) diff --git a/benches/par_rayon.rs b/benches/par_rayon.rs index 03de37825..e8c4cfef3 100644 --- a/benches/par_rayon.rs +++ b/benches/par_rayon.rs @@ -131,7 +131,7 @@ fn rayon_add(bench: &mut Bencher) { let c = Array2::::zeros((ADDN, ADDN)); let d = Array2::::zeros((ADDN, ADDN)); bench.iter(|| { - par_azip!(mut a, b, c, d in { + par_azip!((a in &mut a, b in &b, c in &c, d in &d) { *a += b.exp() + c.exp() + d.exp(); }); }); diff --git a/src/parallel/zipmacro.rs b/src/parallel/zipmacro.rs index a61ae88d4..99c3807f8 100644 --- a/src/parallel/zipmacro.rs +++ b/src/parallel/zipmacro.rs @@ -13,10 +13,12 @@ /// This is a version of the [`azip`] macro that requires the crate feature /// `rayon` to be enabled. /// +/// See the [`azip`] macro for more details about the macro syntax! +/// /// This example: /// /// ```rust,ignore -/// par_azip!(mut a, b, c in { *a = b + c }) +/// par_azip!((a in &mut a, &b in &b, &c in &c) { *a = b + c }) /// ``` /// /// Is equivalent to: @@ -47,60 +49,13 @@ /// // Compute a simple ternary operation: /// // elementwise addition of b and c, stored in a /// -/// par_azip!(mut a, b, c in { *a = b + c }); +/// par_azip!((a in &mut a, &b in &b, &c in &c) *a = b + c); /// /// assert_eq!(a, &b + &c); /// } /// ``` macro_rules! par_azip { - // Build Zip Rule (index) - (@parse [index => $a:expr, $($aa:expr,)*] $t1:tt in $t2:tt) => { - $crate::par_azip!(@finish ($crate::Zip::indexed($a)) [$($aa,)*] $t1 in $t2) - }; - // Build Zip Rule (no index) - (@parse [$a:expr, $($aa:expr,)*] $t1:tt in $t2:tt) => { - $crate::par_azip!(@finish ($crate::Zip::from($a)) [$($aa,)*] $t1 in $t2) - }; - // Build Finish Rule (both) - (@finish ($z:expr) [$($aa:expr,)*] [$($p:pat,)+] in { $($t:tt)*}) => { - use $crate::parallel::prelude::*; - #[allow(unused_mut)] - ($z) - $( - .and($aa) - )* - .par_apply(|$($p),+| { - $($t)* - }) - }; - // parsing stack: [expressions] [patterns] (one per operand) - // index uses empty [] -- must be first - (@parse [] [] index $i:pat, $($t:tt)*) => { - $crate::par_azip!(@parse [index =>] [$i,] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] mut $x:ident ($e:expr) $($t:tt)*) => { - $crate::par_azip!(@parse [$($exprs)* $e,] [$($pats)* mut $x,] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] mut $x:ident $($t:tt)*) => { - $crate::par_azip!(@parse [$($exprs)* &mut $x,] [$($pats)* mut $x,] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] , $($t:tt)*) => { - $crate::par_azip!(@parse [$($exprs)*] [$($pats)*] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] ref $x:ident ($e:expr) $($t:tt)*) => { - $crate::par_azip!(@parse [$($exprs)* $e,] [$($pats)* $x,] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] ref $x:ident $($t:tt)*) => { - $crate::par_azip!(@parse [$($exprs)* &$x,] [$($pats)* $x,] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] $x:ident ($e:expr) $($t:tt)*) => { - $crate::par_azip!(@parse [$($exprs)* $e,] [$($pats)* &$x,] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] $x:ident $($t:tt)*) => { - $crate::par_azip!(@parse [$($exprs)* &$x,] [$($pats)* &$x,] $($t)*); - }; - (@parse [$($exprs:tt)*] [$($pats:tt)*] $($t:tt)*) => { }; ($($t:tt)*) => { - $crate::par_azip!(@parse [] [] $($t)*); - } + $crate::azip!(@build par_apply $($t)*) + }; } diff --git a/tests/par_azip.rs b/tests/par_azip.rs index da1bbe72c..e5dc02c4e 100644 --- a/tests/par_azip.rs +++ b/tests/par_azip.rs @@ -1,5 +1,6 @@ #![cfg(feature = "rayon")] +#[cfg(feature = "approx")] use itertools::enumerate; use ndarray::parallel::prelude::*; use ndarray::prelude::*; @@ -9,7 +10,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; fn test_par_azip1() { let mut a = Array::zeros(62); let b = Array::from_elem(62, 42); - par_azip!(mut a in { *a = 42 }); + par_azip!((a in &mut a) { *a = 42 }); assert_eq!(a, b); } @@ -17,7 +18,7 @@ fn test_par_azip1() { fn test_par_azip2() { let mut a = Array::zeros((5, 7)); let b = Array::from_shape_fn(a.dim(), |(i, j)| 1. / (i + 2 * j) as f32); - par_azip!(mut a, b in { *a = b; }); + par_azip!((a in &mut a, &b in &b, ) *a = b ); assert_eq!(a, b); } @@ -33,7 +34,7 @@ fn test_par_azip3() { *elt = i as f32; } - par_azip!(mut a (&mut a[..]), b (&b[..]), mut c (&mut c[..]) in { + par_azip!((a in &mut a[..], &b in &b[..], c in &mut c[..]) { *a += b / 10.; *c = a.sin(); }); @@ -48,7 +49,7 @@ fn test_zip_dim_mismatch_1() { let mut d = a.raw_dim(); d[0] += 1; let b = Array::from_shape_fn(d, |(i, j)| 1. / (i + 2 * j) as f32); - par_azip!(mut a, b in { *a = b; }); + par_azip!((a in &mut a, &b in &b) { *a = b; }); } #[test] @@ -59,7 +60,7 @@ fn test_indices_1() { } let count = AtomicUsize::new(0); - par_azip!(index i, elt (&a1) in { + par_azip!((index i, &elt in &a1) { count.fetch_add(1, Ordering::SeqCst); assert_eq!(elt, i); });