I'm implementing Peter Shirley's Ray Tracing in a Weekend, and I'm running into strange error messages when trying to parallelize rendering using Rayon.
You can a look at the rest of the code, but the important bit is this:
let colors: Vec<Vec3> = (0..ny)
.into_par_iter()
.rev()
.flat_map(|j| {
(0..nx).into_par_iter().map(|i| {
let mut rng = rand::thread_rng();
let mut col = Vec3::new(0.0, 0.0, 0.0);
for _ in 0..ns {
let u = (f64::from(i) + rng.gen::<f64>()) / f64::from(nx);
let v = (f64::from(j) + rng.gen::<f64>()) / f64::from(ny);
let ray = camera.get_ray(u, v);
col = col + color(&ray, &world);
}
col / f64::from(ns)
})
})
.collect();
Which gives this error message:
rror[E0373]: closure may outlive the current function, but it borrows `j`, which is owned by the current function
--> src/main.rs:309:41
|
309 | (0..nx).into_par_iter().map(|i| {
| ^^^ may outlive borrowed value `j`
...
314 | let v = (f64::from(j) + rng.gen::<f64>()) / f64::from(ny);
| - `j` is borrowed here
|
note: closure is returned here
--> src/main.rs:309:13
|
309 | / (0..nx).into_par_iter().map(|i| {
310 | | let mut rng = rand::thread_rng();
311 | | let mut col = Vec3::new(0.0, 0.0, 0.0);
312 | | for _ in 0..ns {
... |
318 | | col / f64::from(ns)
319 | | })
| |______________^
help: to force the closure to take ownership of `j` (and any other referenced variables), use the `move` keyword
|
309 | (0..nx).into_par_iter().map(move |i| {
| ^^^^^^^^
However if I follow the advice and move
the closure, I get this:
error[E0507]: cannot move out of captured variable in an `Fn` closure
--> src/main.rs:309:41
|
298 | let world = HittableList {
| ----- captured outer variable
...
309 | (0..nx).into_par_iter().map(move |i| {
| _________________________________________^
310 | | let mut rng = rand::thread_rng();
311 | | let mut col = Vec3::new(0.0, 0.0, 0.0);
312 | | for _ in 0..ns {
... |
318 | | col / f64::from(ns)
319 | | })
| |_____________^ cannot move out of captured variable in an `Fn` closure
Depending on how else I move around code here, I get other interesting error messages, such as this if I try to collect
the internal map
:
error[E0282]: type annotations needed
--> src/main.rs:308:10
|
308 | .flat_map(|j| {
| ^^^^^^^^ cannot infer type for `PI`