Skip to content

Commit 63ddace

Browse files
author
Ian
committed
First test of parallelization
1 parent 5f8ccdd commit 63ddace

File tree

3 files changed

+142
-24
lines changed

3 files changed

+142
-24
lines changed

Cargo.lock

Lines changed: 111 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ license-file = "SVDLIBC-LICENSE.txt"
1212
nalgebra-sparse = "0.10.0"
1313
ndarray = "0.16.1"
1414
num-traits = "0.2.19"
15-
rand = "0.8.5"
15+
rand = "0.9.0"
16+
rayon = "1.10.0"
1617
thiserror = "2.0.9"

src/new.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use num_traits::real::Real;
44
use num_traits::{Float, FromPrimitive, One, Zero};
55
use rand::rngs::StdRng;
66
use rand::{thread_rng, Rng, SeedableRng};
7+
use rayon::iter::IndexedParallelIterator;
8+
use rayon::iter::ParallelIterator;
9+
use rayon::prelude::{IntoParallelRefIterator, IntoParallelRefMutIterator};
710
use std::fmt::Debug;
811
use std::iter::Sum;
912
use 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

Comments
 (0)