|
1 | | -use ndarray::{Array, Dim}; |
2 | 1 | use rayon::iter::*; |
3 | | -use std::time::{Duration, Instant}; |
4 | | -use std::num::Wrapping; |
5 | 2 |
|
6 | | -const SIZE: usize = 10000; |
7 | | - |
8 | | -enum Procs { |
9 | | - Sequential, |
10 | | - Parallel, |
11 | | -} |
12 | | - |
13 | | -fn scan_sequential<T, P, I>(init: I, id: T, scan_op: P) -> Vec<T> |
14 | | -where |
15 | | - T: Clone, |
16 | | - I: Fn() -> T, |
17 | | - P: FnMut(&mut T, &T) -> Option<T>, |
18 | | -{ |
19 | | - let v = vec![init(); SIZE]; |
20 | | - let scan = v.iter().scan(id, scan_op); |
21 | | - scan.collect() |
22 | | -} |
23 | | - |
24 | | -fn scan_parallel<T, P, I>(init: I, id: T, scan_op: P) -> Vec<T> |
25 | | -where |
26 | | - T: Clone + Send + Sync, |
27 | | - I: Fn() -> T, |
28 | | - P: Fn(&T, &T) -> T + Sync, |
29 | | -{ |
30 | | - let v = vec![init(); SIZE]; |
31 | | - let scan = v.into_par_iter().with_min_len(SIZE / 100).scan(&scan_op, id); |
32 | | - scan.collect() |
33 | | -} |
34 | | - |
35 | | -/******* Addition with artificial delay *******/ |
36 | | - |
37 | | -const DELAY: Duration = Duration::from_nanos(10); |
38 | | -fn wait() -> i32 { |
39 | | - let time = Instant::now(); |
40 | | - |
41 | | - let mut sum = 0; |
42 | | - while time.elapsed() < DELAY { |
43 | | - sum += 1; |
44 | | - } |
45 | | - sum |
46 | | -} |
47 | | - |
48 | | -fn scan_add(procs: Procs) -> Vec<i32> { |
49 | | - let init = || 2; |
50 | | - let id = 0; |
51 | | - |
52 | | - match procs { |
53 | | - Procs::Sequential => { |
54 | | - let f = |state: &mut i32, x: &i32| { |
55 | | - test::black_box(wait()); |
56 | | - *state += x; |
57 | | - Some(*state) |
58 | | - }; |
59 | | - scan_sequential(init, id, f) |
60 | | - } |
61 | | - Procs::Parallel => { |
62 | | - let f = |x: &i32, y: &i32| { |
63 | | - test::black_box(wait()); |
64 | | - *x + *y |
65 | | - }; |
66 | | - scan_parallel(init, id, f) |
67 | | - } |
68 | | - } |
69 | | -} |
70 | | - |
71 | | -#[bench] |
72 | | -fn scan_add_sequential(b: &mut test::Bencher) { |
73 | | - b.iter(|| scan_add(Procs::Sequential)); |
74 | | -} |
75 | | - |
76 | | -#[bench] |
77 | | -fn scan_add_parallel(b: &mut test::Bencher) { |
78 | | - b.iter(|| scan_add(Procs::Parallel)); |
79 | | -} |
| 3 | +mod scan; |
| 4 | +use self::scan::{scan_matmul, Procs}; |
80 | 5 |
|
81 | 6 | #[test] |
82 | | -fn test_scan_add() { |
83 | | - assert_eq!(scan_add(Procs::Sequential), scan_add(Procs::Parallel)); |
| 7 | +fn test_scan_matmul() { |
| 8 | + assert_eq!( |
| 9 | + scan_matmul(Procs::Sequential, 10), |
| 10 | + scan_matmul(Procs::Parallel, 10) |
| 11 | + ); |
84 | 12 | } |
85 | 13 |
|
86 | | -/******** Matrix multiplication with wrapping arithmetic *******/ |
87 | | - |
88 | | -type Matrix = Array<Wrapping<i32>, Dim<[usize; 2]>>; |
89 | | -fn scan_matmul(procs: Procs) -> Vec<Matrix> { |
90 | | - const MAT_SIZE: usize = 50; |
91 | | - let init = || { |
92 | | - Array::from_iter((0..((MAT_SIZE * MAT_SIZE) as i32)).map(|x| Wrapping(x))) |
93 | | - .into_shape((MAT_SIZE, MAT_SIZE)) |
94 | | - .unwrap() |
| 14 | +#[test] |
| 15 | +fn test_scan_addition() { |
| 16 | + let init = 0u64; |
| 17 | + let op = |state: &mut u64, x: &u64| { |
| 18 | + *state += x; |
| 19 | + Some(*state) |
95 | 20 | }; |
96 | | - let id = Array::eye(MAT_SIZE); |
97 | | - |
98 | | - match procs { |
99 | | - Procs::Sequential => { |
100 | | - let f = |state: &mut Matrix, x: &Matrix| { |
101 | | - *state = state.dot(x); |
102 | | - Some(state.clone()) |
103 | | - }; |
| 21 | + let op_par = |state: &u64, x: &u64| *state + x; |
104 | 22 |
|
105 | | - scan_sequential(init, id, f) |
106 | | - } |
107 | | - Procs::Parallel => scan_parallel(init, id, |x, y| x.dot(y)), |
| 23 | + for len in 0..100 { |
| 24 | + let v = vec![1u64; len]; |
| 25 | + let scan_seq = v.iter().scan(init, op).collect::<Vec<u64>>(); |
| 26 | + let scan_par = v.into_par_iter().scan(op_par, init).collect::<Vec<u64>>(); |
| 27 | + assert_eq!(scan_seq, scan_par); |
108 | 28 | } |
109 | 29 | } |
110 | 30 |
|
111 | | -#[bench] |
112 | | -fn scan_matmul_sequential(b: &mut test::Bencher) { |
113 | | - b.iter(|| scan_matmul(Procs::Sequential)); |
114 | | -} |
115 | | - |
116 | | -#[bench] |
117 | | -fn scan_matmul_parallel(b: &mut test::Bencher) { |
118 | | - b.iter(|| scan_matmul(Procs::Parallel)); |
119 | | -} |
120 | | - |
121 | | -#[test] |
122 | | -fn test_scan_matmul() { |
123 | | - assert_eq!(scan_matmul(Procs::Sequential), scan_matmul(Procs::Parallel)); |
124 | | -} |
| 31 | +#[cfg(test)] |
| 32 | +mod bench; |
0 commit comments