Skip to content

Commit 87b0b5e

Browse files
committed
Generating bootstrap paths multi-threaded.
1 parent d8760eb commit 87b0b5e

File tree

1 file changed

+36
-18
lines changed

1 file changed

+36
-18
lines changed

src/lib.rs

+36-18
Original file line numberDiff line numberDiff line change
@@ -577,32 +577,50 @@ pub fn render_mlt(
577577
integrator: &mut Box<MLTIntegrator>,
578578
num_threads: u8,
579579
) {
580+
let num_cores: usize;
581+
if num_threads == 0_u8 {
582+
num_cores = num_cpus::get();
583+
} else {
584+
num_cores = num_threads as usize;
585+
}
580586
if let Some(light_distr) = compute_light_power_distribution(scene) {
587+
println!("Generating bootstrap paths ...");
581588
// generate bootstrap samples and compute normalization constant $b$
582589
let n_bootstrap_samples: u32 = integrator.n_bootstrap * (integrator.max_depth + 1);
583590
let mut bootstrap_weights: Vec<Float> = vec![0.0 as Float; n_bootstrap_samples as usize];
584591
if scene.lights.len() > 0 {
585592
// TODO: ProgressReporter progress(nBootstrap / 256, "Generating bootstrap paths");
586-
let chunk_size: u32 = clamp_t(integrator.n_bootstrap / 128, 1, 8192);
587-
for i in 0..integrator.n_bootstrap {
588-
// generate _i_th bootstrap sample
589-
for depth in 0..(integrator.max_depth + 1) {
590-
let rng_index: u64 = (i * (integrator.max_depth + 1) + depth) as u64;
591-
let mut sampler: MLTSampler = MLTSampler::new(
592-
integrator.mutations_per_pixel as i64,
593-
rng_index,
594-
integrator.sigma,
595-
integrator.large_step_probability,
596-
N_SAMPLE_STREAMS as i32,
597-
);
598-
let mut p_raster: Point2f = Point2f::default();
599-
bootstrap_weights[rng_index as usize] = integrator
600-
.l(scene, &light_distr, &mut sampler, depth, &mut p_raster)
601-
.y();
602-
}
603-
// TODO: if ((i + 1) % 256 == 0) progress.Update();
593+
// let chunk_size: u32 = clamp_t(integrator.n_bootstrap / 128, 1, 8192);
594+
let chunk_size: usize = (n_bootstrap_samples / num_cores as u32) as usize;
595+
{
596+
let bands: Vec<&mut [Float]> = bootstrap_weights.chunks_mut(chunk_size).collect();
597+
let integrator = &integrator;
598+
let light_distr = &light_distr;
599+
crossbeam::scope(|scope| {
600+
for (b, band) in bands.into_iter().enumerate() {
601+
scope.spawn(move || {
602+
for (w, weight) in band.into_iter().enumerate() {
603+
let rng_index: u64 = ((b * chunk_size) + w) as u64;
604+
let depth: u32 =
605+
(rng_index % (integrator.max_depth + 1) as u64) as u32;
606+
let mut sampler: MLTSampler = MLTSampler::new(
607+
integrator.mutations_per_pixel as i64,
608+
rng_index,
609+
integrator.sigma,
610+
integrator.large_step_probability,
611+
N_SAMPLE_STREAMS as i32,
612+
);
613+
let mut p_raster: Point2f = Point2f::default();
614+
*weight = integrator
615+
.l(scene, &light_distr, &mut sampler, depth, &mut p_raster)
616+
.y();
617+
}
618+
});
619+
}
620+
});
604621
}
605622
}
623+
println!("Rendering ...");
606624
let bootstrap: Distribution1D = Distribution1D::new(bootstrap_weights);
607625
let b: Float = bootstrap.func_int * (integrator.max_depth + 1) as Float;
608626
// run _n_chains_ Markov chains in parallel

0 commit comments

Comments
 (0)