nalgebra
nalgebra copied to clipboard
Question: is it possible to modify different DMatrix columns in parallel (via Rayon) without Mutex?
I'm trying to make the following code work:
use nalgebra::*;
use rayon::prelude::*;
let mut m = DMatrix::<f64>::from_vec(2, 3, (0..6).map(|n| n as f64).collect());
dbg!(&m);
m.column_iter_mut()
.par_bridge()
.for_each(|mut c| c[0] = 111.0);
dbg!(&m);
But the code doesn't compile:
no method named
par_bridge
found for structColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>
in the current scope the methodpar_bridge
exists but the following trait bounds were not satisfied:ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: Send
which is required byColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: rayon::iter::ParallelBridge
&ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: Send
which is required by&ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: rayon::iter::ParallelBridge
&ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: Iterator
which is required by&ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: rayon::iter::ParallelBridge
&mut ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: Send
which is required by&mut ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>>: rayon::iter::ParallelBridge
Is there a relatively short path for making the code above work (with some changes to either the code or nalgebra source code)? I can do some digging on my own, I just need the direction. Thanks!
Hi! We never attempted to make this kind of parallelisation possible with rayon so far. So I don’t have much advice to give. I don’t believe &ColumnIterMut
can be modified to make it implement Send
. So I feel like we would have to implement custom parallel iterators for nalgebra
matrices.
One "simple" workaround I can think of is to convert the matrix to a slice and iterate on chunks:
matrix
.as_mut_slice()
.par_chunks(matrix.nrows())
.for_each(|col| col[0] = 111.0)
This works because the matrix is stored in column-major order. Though is is much less ergonomic than what a custom parallel iterator would offer.
I don't mean to commit myself to anything right now, but would y'all be amenable to a rayon feature for nalgebra that added support for parallel iterators over rows, columns, coefficients, ect? What would scoping out work like that entail?
I am also very keen on having this feature and created a PR for this in #1165
the aforementioned PR is merged and I believe this issue can be resolved.