I have following function:
pub fn calculate_std_dev(matrices: &[DMatrix<f64>]) -> Option<DMatrix<f64>> {
if matrices.is_empty() || matrices.iter().any(|m| m.shape() != matrices[0].shape()) {
return None;
}
let len = matrices.len() as f64;
let mean = matrices.iter().sum::<DMatrix<f64>>() / len;
Some(
matrices
// .iter() never panics
.par_iter() // always panic with Cannot compute `sum` of empty iterator.
.map(|x| x.zip_map(&mean, |a, b| (a - b).powf(2.0)))
.sum::<DMatrix<f64>>()
.map(|x| (x / len).sqrt()),
)
}
when using iter it works pretty fast, but still 50% slower than C++ eigen, I think maybe using parallel computing can be faster, so I choose rayon and used par_iter()
, but it panics at the beginning sum, can somebody explain it to me? thanks
Please (always) post the full output of the error that you get in the terminal (copy-paste, not an image). Otherwise, to answer your question someone will need to compile your code and reproduce the problem, and even then they won't be sure it is the same error you're seeing.
here's my full output:
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
thread '<unnamed>' panicked at /home/dennis/.cargo/registry/src/mirrors.ustc.edu.cn-5857e57f01837ef8/nalgebra-0.33.2/src/base/ops.rs:404:13:
Cannot compute `sum` of empty iterator.
Rayon uses empty sums as a proxy for zero values while it's splitting parallel work, but that doesn't really make sense for DMatrix
(dynamically sized?) if they can't know what size zero-matrix will be addable to the rest of the actual matrices. Note that it's the nalgebra
code raising the panic.
Maybe .reduce_with(add)
would work better for you?
1 Like
thanks, with reduce_with
it works, but it seems to be exactly same performance as original one without rayon, I guess either my datasets are too small or nalgebra did rayon already inside of its iter implementation.
Just checkout nalgebra source code, it does not use rayon, and using rayon on large datasets turns out to be slower than nalgebra itself