Reputation: 3001
I have the toy example below, where I am iterating over a simple vector of structs and doing a parallel operation on them. After the parallel operation, I want to load all of the results into a sparse matrix.
extern crate rayon;
extern crate sprs;
use rayon::prelude::*;
use sprs::TriMat;
pub struct Data {
i: usize,
}
fn eval<'a>(d: &Data) -> usize {
d.i * 2
}
fn main() {
let data = vec![1, 2, 3, 4];
let mut recs = Vec::new();
for x in data {
let s = Data { i: x };
recs.push(s);
}
let results = recs.par_iter().map(eval);
let mut matrix = TriMat::new((4, 2));
results.enumerate().for_each(|(j, scores)| {
matrix.add_triplet(j, j as usize, 1);
});
}
The code leads to the error:
error[E0387]: cannot borrow data mutably in a captured outer variable in an `Fn` closure
--> src/main.rs:26:9
|
26 | matrix.add_triplet(j, j as usize, 1);
| ^^^^^^
|
help: consider changing this closure to take self by mutable reference
--> src/main.rs:25:34
|
25 | results.enumerate().for_each(|(j, scores)| {
| __________________________________^
26 | | matrix.add_triplet(j, j as usize, 1);
27 | | });
| |_____^
I don't understand how the data are being borrowed mutably.
Upvotes: 0
Views: 62
Reputation: 65077
It is because map
doesn't actually do anything.. it creates a new iterator that is yet to be iterated.
Once we hit the matrix.add_triplet(j, j as usize, 1);
code, that iterator is being iterated over but ... its a ParallelIterator
... and therefore the Rust compiler is now concerned about data races.
You've got two options I can see.
First, you can force evaluation of the iterator straight away..:
let results: Vec<_> = recs.par_iter().map(eval).collect();
// ...
results.iter().enumerate() // ...
Or you can wrap access to the matrix in a Mutex
(or another sync mechanism):
use std::sync::Mutex;
// ...
let mut matrix = Mutex::new(TriMat::new((4, 2)));
// ...
matrix.lock().unwrap().add_triplet(j, j as usize, 1);
What is best for you I'm not entirely sure given the small sample you've shared with us, but hopefully that gives you an idea of what is happening.
Upvotes: 1