Add boolean for switching serial/parallel execution

This commit is contained in:
Magnus Ulimoen 2021-03-26 00:00:42 +01:00
parent a33e1d37ba
commit 52c21dbbe9
1 changed files with 58 additions and 20 deletions

View File

@ -21,18 +21,33 @@ struct System {
operators: Vec<Box<dyn SbpOperator2d>>, operators: Vec<Box<dyn SbpOperator2d>>,
} }
use std::sync::atomic::{AtomicBool, Ordering};
pub(crate) static MULTITHREAD: AtomicBool = AtomicBool::new(false);
impl integrate::Integrable for System { impl integrate::Integrable for System {
type State = Vec<euler::Field>; type State = Vec<euler::Field>;
type Diff = Vec<euler::Field>; type Diff = Vec<euler::Field>;
fn assign(s: &mut Self::State, o: &Self::State) { fn assign(s: &mut Self::State, o: &Self::State) {
s.par_iter_mut() if MULTITHREAD.load(Ordering::Acquire) {
.zip(o.par_iter()) s.par_iter_mut()
.for_each(|(s, o)| euler::Field::assign(s, o)) .zip(o.par_iter())
.for_each(|(s, o)| euler::Field::assign(s, o))
} else {
s.iter_mut()
.zip(o.iter())
.for_each(|(s, o)| euler::Field::assign(s, o))
}
} }
fn scaled_add(s: &mut Self::State, o: &Self::Diff, scale: Float) { fn scaled_add(s: &mut Self::State, o: &Self::Diff, scale: Float) {
s.par_iter_mut() if MULTITHREAD.load(Ordering::Acquire) {
.zip(o.par_iter()) s.par_iter_mut()
.for_each(|(s, o)| euler::Field::scaled_add(s, o, scale)) .zip(o.par_iter())
.for_each(|(s, o)| euler::Field::scaled_add(s, o, scale))
} else {
s.iter_mut()
.zip(o.iter())
.for_each(|(s, o)| euler::Field::scaled_add(s, o, scale))
}
} }
} }
@ -94,7 +109,29 @@ impl System {
let rhs = move |fut: &mut Vec<euler::Field>, prev: &Vec<euler::Field>, time: Float| { let rhs = move |fut: &mut Vec<euler::Field>, prev: &Vec<euler::Field>, time: Float| {
let prev_all = &prev; let prev_all = &prev;
rayon::scope(|s| { if MULTITHREAD.load(Ordering::Acquire) {
rayon::scope(|s| {
for (((((((fut, prev), wb), grid), metrics), op), bt), eb) in fut
.iter_mut()
.zip(prev.iter())
.zip(wb.iter_mut())
.zip(grids)
.zip(metrics.iter())
.zip(operators.iter())
.zip(bt.iter())
.zip(eb.iter_mut())
{
s.spawn(move |_| {
let bc = euler::boundary_extracts(prev_all, bt, prev, grid, eb, time);
if op.upwind().is_some() {
euler::RHS_upwind(&**op, fut, prev, metrics, &bc, &mut wb.0);
} else {
euler::RHS_trad(&**op, fut, prev, metrics, &bc, &mut wb.0);
}
})
}
});
} else {
for (((((((fut, prev), wb), grid), metrics), op), bt), eb) in fut for (((((((fut, prev), wb), grid), metrics), op), bt), eb) in fut
.iter_mut() .iter_mut()
.zip(prev.iter()) .zip(prev.iter())
@ -105,16 +142,14 @@ impl System {
.zip(bt.iter()) .zip(bt.iter())
.zip(eb.iter_mut()) .zip(eb.iter_mut())
{ {
s.spawn(move |_| { let bc = euler::boundary_extracts(prev_all, bt, prev, grid, eb, time);
let bc = euler::boundary_extracts(prev_all, bt, prev, grid, eb, time); if op.upwind().is_some() {
if op.upwind().is_some() { euler::RHS_upwind(&**op, fut, prev, metrics, &bc, &mut wb.0);
euler::RHS_upwind(&**op, fut, prev, metrics, &bc, &mut wb.0); } else {
} else { euler::RHS_trad(&**op, fut, prev, metrics, &bc, &mut wb.0);
euler::RHS_trad(&**op, fut, prev, metrics, &bc, &mut wb.0); }
}
})
} }
}); }
}; };
integrate::integrate::<integrate::Rk4, System, _>( integrate::integrate::<integrate::Rk4, System, _>(
@ -259,10 +294,13 @@ fn main() {
{ {
let nthreads = opt.jobs.unwrap_or(1); let nthreads = opt.jobs.unwrap_or(1);
rayon::ThreadPoolBuilder::new() if nthreads > 1 {
.num_threads(nthreads) MULTITHREAD.store(true, Ordering::Release);
.build_global() rayon::ThreadPoolBuilder::new()
.unwrap(); .num_threads(nthreads)
.build_global()
.unwrap();
}
} }
let should_output = |itime| { let should_output = |itime| {