nalgebra icon indicating copy to clipboard operation
nalgebra copied to clipboard

Question: is it possible to modify different DMatrix columns in parallel (via Rayon) without Mutex?

Open pgagarinov opened this issue 3 years ago • 4 comments

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 struct ColumnIterMut<'_, f64, Dynamic, Dynamic, VecStorage<f64, Dynamic, Dynamic>> in the current scope the method par_bridge exists but the following trait bounds were not satisfied: 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>>: 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!

pgagarinov avatar Mar 10 '21 16:03 pgagarinov

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.

sebcrozet avatar Mar 13 '21 22:03 sebcrozet

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?

SallySoul avatar Apr 20 '22 20:04 SallySoul

I am also very keen on having this feature and created a PR for this in #1165

geo-ant avatar Oct 21 '22 07:10 geo-ant

the aforementioned PR is merged and I believe this issue can be resolved.

geo-ant avatar Sep 14 '23 04:09 geo-ant