I implemented matrix multiplication using functional approach.
struct Matrix { vals: Vec<i32>, rows: usize, cols: usize,}fn mul(a: &Matrix, b: &Matrix) -> Matrix { assert_eq!(a.cols, b.rows); let vals = a .vals .par_chunks(a.cols) .map(|row| { (0..b.cols).map(|i| { row .iter() .zip(b.vals.iter().skip(i).step_by(b.cols)) .map(|(a, b)| a * b) .sum() }) }) .flatten() .collect(); Matrix { vals, rows: a.rows, cols: b.cols, }}
I tried to parallelize this algorithm by using par_chunks
from Rayon 1.8.1 instead of chunks
, so each row is constructed in a separate thread. With chunks
the algorithm works, but with par_chunks
it results in two errors:
error[E0277]: the trait bound `std::iter::Map<std::ops::Range<usize>, {closure@src\main.rs:145:23: 145:26}>: rayon::iter::ParallelIterator` is not satisfied --> src\main.rs:153:6 |153 | .flatten() | ^^^^^^^ the trait `rayon::iter::ParallelIterator` is not implemented for `std::iter::Map<std::ops::Range<usize>, {closure@src\main.rs:145:23: 145:26}>`
and
error[E0599]: the method `collect` exists for struct `Flatten<Map<Chunks<'_, i32>, {closure@main.rs:144:10}>>`, but its trait bounds were not satisfied --> src\main.rs:154:6 |141 | let vals = a | ______________-142 | | .vals143 | | .par_chunks(a.cols)144 | | .map(|row| {... |153 | | .flatten()154 | | .collect(); | | -^^^^^^^ method cannot be called due to unsatisfied trait bounds | |_____| | | ::: C:\rust\.rustup\toolchains\stable-x86_64-pc-windows-gnu\lib/rustlib/src/rust\library\core\src\iter\adapters\map.rs:62:1 |62 | pub struct Map<I, F> { | -------------------- doesn't satisfy `_: IntoParallelIterator` | ::: C:\rust\.cargo\registry\src\index.crates.io-6f17d22bba15001f\rayon-1.8.1\src\iter\flatten.rs:11:1 |11 | pub struct Flatten<I: ParallelIterator> { | --------------------------------------- | | | doesn't satisfy `_: Iterator` | doesn't satisfy `_: ParallelIterator`
I have no idea what is going on. I suspect that it might be somehow related to sharing second matrix between threads but it is read-only and is guaranteed to stay in the scope until threads have finished their jobs. Error messages don't help at all. What am I doing wrong? How do I even read this error message?