Skip to content

Commit

Permalink
FIX: Update par_azip!() to use the same syntax as azip!()
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
bluss committed Sep 20, 2019
1 parent f7645e8 commit 0c1a3d7
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 57 deletions.
2 changes: 1 addition & 1 deletion benches/par_rayon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ fn rayon_add(bench: &mut Bencher) {
let c = Array2::<f64>::zeros((ADDN, ADDN));
let d = Array2::<f64>::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();
});
});
Expand Down
57 changes: 6 additions & 51 deletions src/parallel/zipmacro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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)*)
};
}
11 changes: 6 additions & 5 deletions tests/par_azip.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![cfg(feature = "rayon")]

#[cfg(feature = "approx")]
use itertools::enumerate;
use ndarray::parallel::prelude::*;
use ndarray::prelude::*;
Expand All @@ -9,15 +10,15 @@ 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);
}

#[test]
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);
}

Expand All @@ -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();
});
Expand All @@ -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]
Expand All @@ -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);
});
Expand Down

0 comments on commit 0c1a3d7

Please sign in to comment.