2022-10-18 15:03:52 +08:00
|
|
|
//! this module implements parallelators to make matrices work with
|
|
|
|
//! the rayon crate seamlessly
|
|
|
|
|
|
|
|
use crate::{
|
2022-10-21 14:51:41 +08:00
|
|
|
iter::{ColumnIter, ColumnIterMut},
|
|
|
|
Dim, Matrix, MatrixSlice, MatrixSliceMut, RawStorage, RawStorageMut, U1,
|
2022-10-18 15:03:52 +08:00
|
|
|
};
|
2022-10-21 14:51:41 +08:00
|
|
|
use core::fmt::Debug;
|
|
|
|
use rayon::{iter::plumbing::bridge, prelude::*};
|
2022-10-18 15:03:52 +08:00
|
|
|
|
2022-10-21 14:44:35 +08:00
|
|
|
/// A rayon parallel iterator over the colums of a matrix
|
2022-10-18 15:03:52 +08:00
|
|
|
pub struct ParColumnIter<'a, T, R: Dim, Cols: Dim, S: RawStorage<T, R, Cols>> {
|
|
|
|
mat: &'a Matrix<T, R, Cols, S>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T, R: Dim, Cols: Dim, S: RawStorage<T, R, Cols>> ParColumnIter<'a, T, R, Cols, S> {
|
2022-10-21 14:44:35 +08:00
|
|
|
/// create a new parallel iterator for the given matrix
|
2022-10-18 15:03:52 +08:00
|
|
|
fn new(matrix: &'a Matrix<T, R, Cols, S>) -> Self {
|
|
|
|
Self { mat: matrix }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T, R: Dim, Cols: Dim, S: RawStorage<T, R, Cols>> ParallelIterator
|
|
|
|
for ParColumnIter<'a, T, R, Cols, S>
|
|
|
|
where
|
|
|
|
T: Sync + Send + Clone + Debug + PartialEq + 'static,
|
|
|
|
S: Sync,
|
|
|
|
{
|
|
|
|
type Item = MatrixSlice<'a, T, R, U1, S::RStride, S::CStride>;
|
|
|
|
|
|
|
|
fn drive_unindexed<Consumer>(self, consumer: Consumer) -> Consumer::Result
|
|
|
|
where
|
|
|
|
Consumer: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
|
|
|
|
{
|
|
|
|
bridge(self, consumer)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn opt_len(&self) -> Option<usize> {
|
|
|
|
Some(self.mat.ncols())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T, R: Dim, Cols: Dim, S: RawStorage<T, R, Cols>> IndexedParallelIterator
|
|
|
|
for ParColumnIter<'a, T, R, Cols, S>
|
|
|
|
where
|
|
|
|
T: Send + Sync + Clone + Debug + PartialEq + 'static,
|
|
|
|
S: Sync,
|
|
|
|
{
|
|
|
|
fn len(&self) -> usize {
|
|
|
|
self.mat.ncols()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn drive<C: rayon::iter::plumbing::Consumer<Self::Item>>(self, consumer: C) -> C::Result {
|
|
|
|
bridge(self, consumer)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn with_producer<CB: rayon::iter::plumbing::ProducerCallback<Self::Item>>(
|
|
|
|
self,
|
|
|
|
callback: CB,
|
|
|
|
) -> CB::Output {
|
|
|
|
let producer = ColumnIter::new(self.mat);
|
|
|
|
callback.callback(producer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T, R: Dim, Cols: Dim, S: RawStorage<T, R, Cols>> Matrix<T, R, Cols, S>
|
|
|
|
where
|
|
|
|
T: Send + Sync + Clone + Debug + PartialEq + 'static,
|
|
|
|
S: Sync,
|
|
|
|
{
|
2022-10-21 14:44:35 +08:00
|
|
|
/// Iterate through the columns of the matrix in parallel using rayon.
|
2022-10-19 15:51:46 +08:00
|
|
|
pub fn par_column_iter(&self) -> ParColumnIter<'_, T, R, Cols, S> {
|
2022-10-18 15:03:52 +08:00
|
|
|
ParColumnIter::new(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-21 14:44:35 +08:00
|
|
|
/// A rayon parallel iterator through the mutable columns of a matrix
|
2022-10-21 14:51:41 +08:00
|
|
|
pub struct ParColumnIterMut<
|
|
|
|
'a,
|
|
|
|
T,
|
|
|
|
R: Dim,
|
|
|
|
Cols: Dim,
|
|
|
|
S: RawStorage<T, R, Cols> + RawStorageMut<T, R, Cols>,
|
|
|
|
> {
|
|
|
|
mat: &'a mut Matrix<T, R, Cols, S>,
|
2022-10-18 15:03:52 +08:00
|
|
|
}
|
|
|
|
|
2022-10-21 14:51:41 +08:00
|
|
|
impl<'a, T, R, Cols, S> ParColumnIterMut<'a, T, R, Cols, S>
|
|
|
|
where
|
|
|
|
R: Dim,
|
|
|
|
Cols: Dim,
|
|
|
|
S: RawStorage<T, R, Cols> + RawStorageMut<T, R, Cols>,
|
|
|
|
{
|
2022-10-21 14:44:35 +08:00
|
|
|
/// create a new parallel iterator for the given matrix
|
2022-10-21 14:51:41 +08:00
|
|
|
fn new(mat: &'a mut Matrix<T, R, Cols, S>) -> Self {
|
|
|
|
Self { mat }
|
2022-10-18 15:03:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-21 14:51:41 +08:00
|
|
|
impl<'a, T, R, Cols, S> ParallelIterator for ParColumnIterMut<'a, T, R, Cols, S>
|
|
|
|
where
|
|
|
|
R: Dim,
|
|
|
|
Cols: Dim,
|
|
|
|
S: RawStorage<T, R, Cols> + RawStorageMut<T, R, Cols>,
|
|
|
|
T: Send + Sync + Debug + PartialEq + Clone + 'static,
|
|
|
|
S: Send + Sync,
|
|
|
|
{
|
2022-10-18 15:03:52 +08:00
|
|
|
type Item = MatrixSliceMut<'a, T, R, U1, S::RStride, S::CStride>;
|
|
|
|
fn drive_unindexed<C>(self, consumer: C) -> C::Result
|
2022-10-21 14:51:41 +08:00
|
|
|
where
|
|
|
|
C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
|
|
|
|
{
|
|
|
|
bridge(self, consumer)
|
2022-10-18 15:03:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn opt_len(&self) -> Option<usize> {
|
|
|
|
Some(self.mat.ncols())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-21 14:51:41 +08:00
|
|
|
impl<'a, T, R, Cols, S> IndexedParallelIterator for ParColumnIterMut<'a, T, R, Cols, S>
|
|
|
|
where
|
|
|
|
R: Dim,
|
|
|
|
Cols: Dim,
|
|
|
|
S: RawStorage<T, R, Cols> + RawStorageMut<T, R, Cols>,
|
|
|
|
T: Send + Sync + Debug + PartialEq + Clone + 'static,
|
|
|
|
S: Send + Sync,
|
|
|
|
{
|
2022-10-18 15:03:52 +08:00
|
|
|
fn drive<C: rayon::iter::plumbing::Consumer<Self::Item>>(self, consumer: C) -> C::Result {
|
2022-10-21 14:51:41 +08:00
|
|
|
bridge(self, consumer)
|
2022-10-18 15:03:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
fn len(&self) -> usize {
|
|
|
|
self.mat.ncols()
|
|
|
|
}
|
|
|
|
|
2022-10-21 14:51:41 +08:00
|
|
|
fn with_producer<CB: rayon::iter::plumbing::ProducerCallback<Self::Item>>(
|
|
|
|
self,
|
|
|
|
callback: CB,
|
|
|
|
) -> CB::Output {
|
2022-10-18 15:03:52 +08:00
|
|
|
let producer = ColumnIterMut::new(self.mat);
|
|
|
|
callback.callback(producer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-21 14:51:41 +08:00
|
|
|
impl<'a, T, R: Dim, Cols: Dim, S: RawStorage<T, R, Cols> + RawStorageMut<T, R, Cols>>
|
|
|
|
Matrix<T, R, Cols, S>
|
2022-10-18 15:03:52 +08:00
|
|
|
where
|
|
|
|
T: Send + Sync + Clone + Debug + PartialEq + 'static,
|
|
|
|
S: Sync,
|
|
|
|
{
|
2022-10-21 14:44:35 +08:00
|
|
|
/// Mutably iterate through the columns of this matrix in parallel using rayon
|
2022-10-19 15:51:46 +08:00
|
|
|
pub fn par_column_iter_mut(&mut self) -> ParColumnIterMut<'_, T, R, Cols, S> {
|
2022-10-18 15:03:52 +08:00
|
|
|
ParColumnIterMut::new(self)
|
|
|
|
}
|
|
|
|
}
|