//! this module implements parallelators to make matrices work with //! the rayon crate seamlessly use core::{ fmt::Debug, }; use rayon::{ iter::plumbing::{bridge}, prelude::*, }; use crate::{ iter::{ColumnIter, ColumnIterMut}, DMatrix, Dim, Matrix, MatrixSlice, MatrixSliceMut, RawStorage, RawStorageMut, U1, }; /// a rayon parallel iterator over the columns of a matrix pub struct ParColumnIter<'a, T, R: Dim, Cols: Dim, S: RawStorage> { mat: &'a Matrix, } impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> ParColumnIter<'a, T, R, Cols, S> { fn new(matrix: &'a Matrix) -> Self { Self { mat: matrix } } } impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> 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(self, consumer: Consumer) -> Consumer::Result where Consumer: rayon::iter::plumbing::UnindexedConsumer, { bridge(self, consumer) } fn opt_len(&self) -> Option { Some(self.mat.ncols()) } } impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> 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>(self, consumer: C) -> C::Result { bridge(self, consumer) } fn with_producer>( self, callback: CB, ) -> CB::Output { let producer = ColumnIter::new(self.mat); callback.callback(producer) } } impl<'a, T, R: Dim, Cols: Dim, S: RawStorage> Matrix where T: Send + Sync + Clone + Debug + PartialEq + 'static, S: Sync, { /// TODO pub fn par_column_iter(&self) -> ParColumnIter<'_, T, R, Cols, S> { ParColumnIter::new(self) } } /// TODO pub struct ParColumnIterMut<'a,T,R:Dim ,Cols:Dim, S:RawStorage+RawStorageMut> { mat : &'a mut Matrix, } impl<'a,T,R,Cols,S> ParColumnIterMut<'a,T,R,Cols,S> where R: Dim, Cols : Dim, S:RawStorage + RawStorageMut { /// TODO pub fn new(mat : &'a mut Matrix) -> Self { Self { mat, } } } impl<'a,T,R,Cols,S> ParallelIterator for ParColumnIterMut<'a,T,R,Cols,S> where R: Dim, Cols : Dim, S:RawStorage + RawStorageMut, T : Send + Sync + Debug + PartialEq + Clone + 'static, S : Send + Sync { type Item = MatrixSliceMut<'a, T, R, U1, S::RStride, S::CStride>; fn drive_unindexed(self, consumer: C) -> C::Result where C: rayon::iter::plumbing::UnindexedConsumer { bridge(self,consumer) } fn opt_len(&self) -> Option { Some(self.mat.ncols()) } } impl<'a,T,R,Cols,S> IndexedParallelIterator for ParColumnIterMut<'a,T,R,Cols,S> where R: Dim, Cols : Dim, S:RawStorage + RawStorageMut, T : Send + Sync + Debug + PartialEq + Clone + 'static, S : Send + Sync { fn drive>(self, consumer: C) -> C::Result { bridge(self,consumer) } fn len(&self) -> usize { self.mat.ncols() } fn with_producer>(self, callback: CB) -> CB::Output { let producer = ColumnIterMut::new(self.mat); callback.callback(producer) } } impl<'a, T, R: Dim, Cols: Dim, S: RawStorage + RawStorageMut> Matrix where T: Send + Sync + Clone + Debug + PartialEq + 'static, S: Sync, { /// TODO pub fn par_column_iter_mut(&mut self) -> ParColumnIterMut<'_, T, R, Cols, S> { ParColumnIterMut::new(self) } }