@@ -4,6 +4,9 @@ use num_traits::real::Real;
44use num_traits:: { Float , FromPrimitive , One , Zero } ;
55use rand:: rngs:: StdRng ;
66use rand:: { thread_rng, Rng , SeedableRng } ;
7+ use rayon:: iter:: IndexedParallelIterator ;
8+ use rayon:: iter:: ParallelIterator ;
9+ use rayon:: prelude:: { IntoParallelRefIterator , IntoParallelRefMutIterator } ;
710use std:: fmt:: Debug ;
811use std:: iter:: Sum ;
912use std:: mem;
@@ -411,9 +414,15 @@ fn svd_opb<T: Float>(A: &dyn SMat<T>, x: &[T], y: &mut [T], temp: &mut [T], tran
411414}
412415
413416// constant times a vector plus a vector
414- fn svd_daxpy < T : Float + AddAssign > ( da : T , x : & [ T ] , y : & mut [ T ] ) {
415- for ( xval, yval) in x. iter ( ) . zip ( y. iter_mut ( ) ) {
416- * yval += da * * xval
417+ fn svd_daxpy < T : Float + AddAssign + Send + Sync > ( da : T , x : & [ T ] , y : & mut [ T ] ) {
418+ if x. len ( ) < 1000 {
419+ for ( xval, yval) in x. iter ( ) . zip ( y. iter_mut ( ) ) {
420+ * yval += da * * xval
421+ }
422+ } else {
423+ y. par_iter_mut ( ) . zip ( x. par_iter ( ) ) . for_each ( |( yval, xval) | {
424+ * yval += da * * xval
425+ } ) ;
417426 }
418427}
419428
@@ -466,12 +475,16 @@ fn svd_pythag<T: SvdFloat + FromPrimitive>(a: T, b: T) -> T {
466475}
467476
468477// dot product of two vectors
469- fn svd_ddot < T : Float + Sum < T > > ( x : & [ T ] , y : & [ T ] ) -> T {
470- x. iter ( ) . zip ( y) . map ( |( a, b) | * a * * b) . sum ( )
478+ fn svd_ddot < T : Float + Sum < T > + Send + Sync > ( x : & [ T ] , y : & [ T ] ) -> T {
479+ if x. len ( ) < 1000 {
480+ x. iter ( ) . zip ( y) . map ( |( a, b) | * a * * b) . sum ( )
481+ } else {
482+ x. par_iter ( ) . zip ( y. par_iter ( ) ) . map ( |( a, b) | * a * * b) . sum ( )
483+ }
471484}
472485
473486// norm (length) of a vector
474- fn svd_norm < T : Float + Sum < T > > ( x : & [ T ] ) -> T {
487+ fn svd_norm < T : Float + Sum < T > + Send + Sync > ( x : & [ T ] ) -> T {
475488 svd_ddot ( x, x) . sqrt ( )
476489}
477490
@@ -483,9 +496,15 @@ fn svd_datx<T: Float + Sum<T>>(d: T, x: &[T], y: &mut [T]) {
483496}
484497
485498// scales an input vector 'x' by a constant, modifying 'x'
486- fn svd_dscal < T : Float + MulAssign > ( d : T , x : & mut [ T ] ) {
487- for elem in x. iter_mut ( ) {
488- * elem *= d;
499+ fn svd_dscal < T : Float + MulAssign + Send + Sync > ( d : T , x : & mut [ T ] ) {
500+ if x. len ( ) < 1000 {
501+ for elem in x. iter_mut ( ) {
502+ * elem *= d;
503+ }
504+ } else {
505+ x. par_iter_mut ( ) . for_each ( |elem| {
506+ * elem *= d;
507+ } ) ;
489508 }
490509}
491510
@@ -1526,6 +1545,7 @@ impl<T: Float + Zero + AddAssign + Clone> SMat<T> for nalgebra_sparse::csr::CsrM
15261545
15271546 /// takes an n-vector x and returns A*x in y
15281547 fn svd_opa ( & self , x : & [ T ] , y : & mut [ T ] , transposed : bool ) {
1548+ //TODO parallelize me please
15291549 let nrows = if transposed { self . ncols ( ) } else { self . nrows ( ) } ;
15301550 let ncols = if transposed { self . nrows ( ) } else { self . ncols ( ) } ;
15311551 assert_eq ! ( x. len( ) , ncols, "svd_opa: x must be A.ncols() in length, x = {}, A.ncols = {}" , x. len( ) , ncols) ;
0 commit comments