Rayon par_iter().for_each trying to mutate a captured variable

⚓ Rust    📅 2025-08-16    👤 surdeus    👁️ 4      

surdeus

With the below code I get the compiler error:
"cannot borrow sum1 as mutable, as it is a captured variable in a Fn closure"
How can I do what I want without the compiler complaining?

use ndarray::prelude::*;
use rayon::prelude::*;

fn func(x:f64, a1:f64, a2:f64, a3:f64) -> f64 {
    x+a1*a2+a3
}

fn sum_over() -> (Vec::<Array1::<f64>>,Vec::<Array1::<f64>>) {
    let ni: usize = 100;
    let a1 = Array1::<f64>::zeros(ni) + 2.0;
    let a2 = Array1::<f64>::zeros(ni) + 2.0;
    let a3 = Array1::<f64>::zeros(ni) + 2.0;
    let a4 = Array1::<f64>::zeros(ni) + 2.0;
    let a5 = Array1::<f64>::zeros(ni) + 2.0;

    let mut i1 = Array1::<usize>::zeros(ni);
    let mut i2 = Array1::<usize>::zeros(ni);

    for i in 1..ni {
        i1[i] = i * 5;
        i2[i] = 400 + i * 5;
    }

    let nj: usize = 1000;
    let nthreads = rayon::current_num_threads();
    let mut sum1 = Vec::<Array1::<f64>>::new();
    let mut sum2 = Vec::<Array1::<f64>>::new();
    for _j in  0..nthreads {
        sum1.push(Array1::<f64>::zeros(nj));
        sum2.push(Array1::<f64>::zeros(nj));
    }
    let x = Array1::<f64>::zeros(nj);

    let ii: Vec<usize> = (0..ni).collect();
    ii.par_iter().for_each(|i| {
        let ith = rayon::current_thread_index().unwrap();
        let mut su1 = &mut sum1[ith];
        let mut su2 = &mut sum2[ith];

        for j in i1[*i]..i2[*i] {
            let tmp = func(x[j], a1[*i], a2[*i], a3[*i]);
            su1[j] += a4[*i] * tmp;
            su2[j] += a5[*i] * tmp;
        }
    });

    (sum1, sum2)
}

fn main() {
    let (_sum1, _sum2) = sum_over();
}
``

2 posts - 2 participants

Read full topic

🏷️ Rust_feed