embedded3 PERF-3 P1-1: the moving path's host work, digit-identical — impose_from's solid faces by z plane in parallel (1.95 -> 0.62 s per step at 11.6 M cells), the f32 fine export derived from the f64 level the refresh already builds (export_fine 1.04 -> 0.34 s); sub-laps in the mask rebuild; rebuild block 9.4 -> 7.4 s
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
Documentation / Build User Guide (push) Successful in 5s
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
Documentation / Build API Documentation (push) Failing after 7s
CI / Build CPU-Only (Explicit) (push) Failing after 8s
CI / Format Check (push) Failing after 12s
CI / Build (ubuntu-latest) (push) Failing after 1m51s
CI / Clippy Check (push) Failing after 2m5s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m45s
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
Documentation / Build User Guide (push) Successful in 5s
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
Documentation / Build API Documentation (push) Failing after 7s
CI / Build CPU-Only (Explicit) (push) Failing after 8s
CI / Format Check (push) Failing after 12s
CI / Build (ubuntu-latest) (push) Failing after 1m51s
CI / Clippy Check (push) Failing after 2m5s
Performance Benchmarks / Run Benchmarks (push) Successful in 2m45s
Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
103e2576ae
commit
40268ad19b
@@ -5,6 +5,7 @@
|
||||
|
||||
use super::body::Body;
|
||||
use super::wall::{FaceKind, Mask};
|
||||
use rayon::prelude::*;
|
||||
|
||||
/// The imposition band of a cut mask, in cells.
|
||||
pub(crate) const IMPOSE_BAND_CELLS: f64 = 4.0;
|
||||
@@ -52,12 +53,19 @@ impl Mask {
|
||||
Some(c) => (&c.d_u, &c.d_v, &c.d_w),
|
||||
None => (&[], &[], &[]),
|
||||
};
|
||||
for k in 0..nz {
|
||||
// One z plane per task: every solid face is written from the body's
|
||||
// surface velocity alone (no reduction), so the parallel loop is
|
||||
// digit-identical to the serial one (PERF-3 P1-1: 1.95 s of a 9.4 s
|
||||
// step at 11.6 M cells, serial).
|
||||
u.par_chunks_mut(ny * (nx + 1))
|
||||
.take(nz)
|
||||
.enumerate()
|
||||
.for_each(|(k, plane)| {
|
||||
for j in 0..ny {
|
||||
for i in 1..nx {
|
||||
let idx = g.uface(k, j, i);
|
||||
if self.u_kind[idx] == FaceKind::Solid && near(d_u, idx) {
|
||||
u[idx] = body
|
||||
plane[j * (nx + 1) + i] = body
|
||||
.surface_velocity(
|
||||
i as f64 * dx,
|
||||
(j as f64 + 0.5) * dy,
|
||||
@@ -68,11 +76,16 @@ impl Mask {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
v.par_chunks_mut((ny + 1) * nx)
|
||||
.take(nz)
|
||||
.enumerate()
|
||||
.for_each(|(k, plane)| {
|
||||
for j in 1..ny {
|
||||
for i in 0..nx {
|
||||
let idx = g.vface(k, j, i);
|
||||
if self.v_kind[idx] == FaceKind::Solid && near(d_v, idx) {
|
||||
v[idx] = body
|
||||
plane[j * nx + i] = body
|
||||
.surface_velocity(
|
||||
(i as f64 + 0.5) * dx,
|
||||
j as f64 * dy,
|
||||
@@ -83,13 +96,16 @@ impl Mask {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for k in 0..=nz {
|
||||
});
|
||||
w.par_chunks_mut(ny * nx)
|
||||
.take(nz + 1)
|
||||
.enumerate()
|
||||
.for_each(|(k, plane)| {
|
||||
for j in 0..ny {
|
||||
for i in 0..nx {
|
||||
let idx = g.wface(k, j, i);
|
||||
if self.w_kind[idx] == FaceKind::Solid && near(d_w, idx) {
|
||||
w[idx] = body
|
||||
plane[j * nx + i] = body
|
||||
.surface_velocity(
|
||||
(i as f64 + 0.5) * dx,
|
||||
(j as f64 + 0.5) * dy,
|
||||
@@ -100,7 +116,7 @@ impl Mask {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let u_vals: Vec<f64> = self
|
||||
.u_ghosts
|
||||
.iter()
|
||||
|
||||
+1
-1
@@ -255,7 +255,7 @@ impl DeviceCg {
|
||||
let l_key = lap.elapsed();
|
||||
// The V-cycle's finest level follows the operator (its coarser
|
||||
// levels stay): the fine level alone, no hierarchy build.
|
||||
let fine_level = super::export::export_fine(problem);
|
||||
let fine_level = super::export::export_fine_from(&fine);
|
||||
let l_export = lap.elapsed();
|
||||
self.vcycle.refresh_fine(&fine_level);
|
||||
if profile {
|
||||
|
||||
@@ -125,6 +125,40 @@ pub fn export_fine(problem: &Problem) -> LevelExport {
|
||||
}
|
||||
}
|
||||
|
||||
/// As [`export_fine`], from the f64 fine level a caller already built
|
||||
/// (PERF-3 P1-1): the f32 level is the same masked coefficients cast, so this
|
||||
/// is the identical export without a second clone of the problem and a
|
||||
/// second level build.
|
||||
pub fn export_fine_from(lv: &Level<f64>) -> LevelExport {
|
||||
let (_, coarse_of) = lv.coarsen();
|
||||
let to_u32 = |v: &[usize]| {
|
||||
v.iter()
|
||||
.map(|&i| if i == usize::MAX { u32::MAX } else { i as u32 })
|
||||
.collect::<Vec<u32>>()
|
||||
};
|
||||
let cast = |v: &[f64]| v.iter().map(|&x| x as f32).collect::<Vec<f32>>();
|
||||
LevelExport {
|
||||
nx: lv.problem.nx,
|
||||
ny: lv.problem.ny,
|
||||
nz: lv.problem.nz,
|
||||
cells: to_u32(&lv.cells),
|
||||
red: to_u32(&lv.red),
|
||||
black: to_u32(&lv.black),
|
||||
top: to_u32(&lv.top),
|
||||
bot: to_u32(&lv.bot),
|
||||
coarse_of: to_u32(&coarse_of),
|
||||
children_ptr: Vec::new(),
|
||||
children_idx: Vec::new(),
|
||||
ae: cast(&lv.ae),
|
||||
aw: cast(&lv.aw),
|
||||
an: cast(&lv.an),
|
||||
as_: cast(&lv.as_),
|
||||
at: cast(&lv.at),
|
||||
ab: cast(&lv.ab),
|
||||
ap: cast(&lv.ap),
|
||||
}
|
||||
}
|
||||
|
||||
/// `z = M⁻¹ r` by the host f32 V-cycle: the reference a device V-cycle is measured against.
|
||||
pub fn vcycle_f32_reference(
|
||||
problem: &Problem,
|
||||
|
||||
@@ -51,6 +51,7 @@ impl Solver {
|
||||
}
|
||||
}
|
||||
let l_step = lap.elapsed();
|
||||
let sub = std::time::Instant::now();
|
||||
new_mask.impose_from(
|
||||
body,
|
||||
&field.u_old,
|
||||
@@ -61,6 +62,7 @@ impl Solver {
|
||||
&mut field.w,
|
||||
t_new,
|
||||
);
|
||||
let s_impose = sub.elapsed();
|
||||
if new_mask.cut().is_some() {
|
||||
let (table, correction) = match &self.mask {
|
||||
Some(old_mask) => new_mask.gcl_flux_table(old_mask, dt),
|
||||
@@ -69,6 +71,7 @@ impl Solver {
|
||||
self.wall_fluxes = table;
|
||||
self.last_ghost_correction = correction;
|
||||
}
|
||||
let s_gcl = sub.elapsed();
|
||||
if let Some(old) = &self.mask {
|
||||
self.apertures_old = old
|
||||
.cut()
|
||||
@@ -86,10 +89,13 @@ impl Solver {
|
||||
if std::env::var("RTX_E3_MOVING_PROFILE").is_ok() {
|
||||
let ms = |d: std::time::Duration| d.as_secs_f64() * 1e3;
|
||||
eprintln!(
|
||||
" mask laps: build_mask {:.0} ms, refill + step apertures + merging {:.0} ms, impose + GCL + volumes {:.0} ms",
|
||||
" mask laps: build_mask {:.0} ms, refill + step apertures + merging {:.0} ms, impose + GCL + volumes {:.0} ms (impose {:.0}, GCL table {:.0}, old apertures + volumes {:.0})",
|
||||
ms(l_build),
|
||||
ms(l_step - l_build),
|
||||
ms(lap.elapsed() - l_step)
|
||||
ms(lap.elapsed() - l_step),
|
||||
ms(s_impose),
|
||||
ms(s_gcl - s_impose),
|
||||
ms(sub.elapsed() - s_gcl)
|
||||
);
|
||||
}
|
||||
self.mask = Some(new_mask);
|
||||
|
||||
Reference in New Issue
Block a user