PERF-2 P0: intra-step profiler — StepTimers on the overset solver (RTX_PROFILE; overlap build / predictors / patch BiCGSTAB / background Poisson with its setup-vs-iterate split / round exchange / apply / end exchange), PoissonSolution carries setup_ns and iterate_ns, the harness times advance / restore / snapshot / load sampling / force / FEA predictor and prints the wall split of the coupled phase; no clock is read when profiling is off; the reclassified/step progress denominator fixed (was ×4)
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
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Format Check (push) Failing after 6s
CI / Build (ubuntu-latest) (push) Failing after 5s
CI / Clippy Check (push) Failing after 5s
Documentation / Build User Guide (push) Successful in 6s
Performance Benchmarks / Run Benchmarks (push) Failing after 27s
CI / Build CPU-Only (Explicit) (push) Failing after 1m24s
Documentation / Build API Documentation (push) Failing after 1m34s
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
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Format Check (push) Failing after 6s
CI / Build (ubuntu-latest) (push) Failing after 5s
CI / Clippy Check (push) Failing after 5s
Documentation / Build User Guide (push) Successful in 6s
Performance Benchmarks / Run Benchmarks (push) Failing after 27s
CI / Build CPU-Only (Explicit) (push) Failing after 1m24s
Documentation / Build API Documentation (push) Failing after 1m34s
Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01YJPeT6WA2e7YvAnS875AHL
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
2d2fed7181
commit
172a26dee4
@@ -218,6 +218,14 @@ pub struct OversetFluid {
|
||||
/// Patch regenerations and their wall time.
|
||||
pub regen_count: Cell<usize>,
|
||||
pub regen_seconds: Cell<f64>,
|
||||
/// PERF-2 P0 wall-time buckets [s]: the composite step (`advance`), the
|
||||
/// per-pass restore, the per-step snapshot, the load sampling and the
|
||||
/// force measurement (`docs/perf2_campaign.md`).
|
||||
pub t_advance: Cell<f64>,
|
||||
pub t_restore: Cell<f64>,
|
||||
pub t_snapshot: Cell<f64>,
|
||||
pub t_sample: Cell<f64>,
|
||||
pub t_force: Cell<f64>,
|
||||
/// Background cells reclassified, summed over every fluid step.
|
||||
pub reclassified_total: Cell<usize>,
|
||||
pub fresh_total: Cell<usize>,
|
||||
@@ -441,6 +449,11 @@ impl OversetFluid {
|
||||
sweeps,
|
||||
regen_count: Cell::new(0),
|
||||
regen_seconds: Cell::new(0.0),
|
||||
t_advance: Cell::new(0.0),
|
||||
t_restore: Cell::new(0.0),
|
||||
t_snapshot: Cell::new(0.0),
|
||||
t_sample: Cell::new(0.0),
|
||||
t_force: Cell::new(0.0),
|
||||
reclassified_total: Cell::new(0),
|
||||
fresh_total: Cell::new(0),
|
||||
rounds_total: Cell::new(0),
|
||||
@@ -895,6 +908,7 @@ impl OversetFluid {
|
||||
|
||||
/// One fluid step at the current wall.
|
||||
pub fn step(&mut self) -> CfdResult<OversetResult> {
|
||||
let t0 = std::time::Instant::now();
|
||||
let r = match futures::executor::block_on(
|
||||
self.solver.advance(&mut self.field, self.dt_fluid),
|
||||
) {
|
||||
@@ -919,6 +933,8 @@ impl OversetFluid {
|
||||
.set(self.rounds_total.get() + r.rounds.iter().sum::<usize>());
|
||||
self.correctors_total
|
||||
.set(self.correctors_total.get() + r.rounds.len());
|
||||
self.t_advance
|
||||
.set(self.t_advance.get() + t0.elapsed().as_secs_f64());
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
@@ -987,11 +1003,14 @@ impl OversetFluid {
|
||||
|
||||
/// Drag and lift on cylinder + flag from the patch's wall stress.
|
||||
pub fn measure_force(&self) -> (f64, f64) {
|
||||
let t0 = std::time::Instant::now();
|
||||
let f = self
|
||||
.solver
|
||||
.patch()
|
||||
.surface_force(&self.field.patch, PatchSide::Inner, self.solver.time())
|
||||
.total();
|
||||
self.t_force
|
||||
.set(self.t_force.get() + t0.elapsed().as_secs_f64());
|
||||
(f[0], f[1])
|
||||
}
|
||||
|
||||
@@ -1000,6 +1019,14 @@ impl OversetFluid {
|
||||
/// Faces on the cylinder proper are skipped; the fillets' load goes
|
||||
/// to the nearest (clamped) root nodes.
|
||||
pub fn sample_load(&self, d: &[f64]) -> (Vec<(NodeId, Vector3<f64>)>, f64, usize) {
|
||||
let t0 = std::time::Instant::now();
|
||||
let out = self.sample_load_inner(d);
|
||||
self.t_sample
|
||||
.set(self.t_sample.get() + t0.elapsed().as_secs_f64());
|
||||
out
|
||||
}
|
||||
|
||||
fn sample_load_inner(&self, d: &[f64]) -> (Vec<(NodeId, Vector3<f64>)>, f64, usize) {
|
||||
let mut faces = Vec::new();
|
||||
let mut tractions: Vec<Vector3<f64>> = Vec::new();
|
||||
for (centre, normal, len, traction) in self.solver.patch().wall_tractions(
|
||||
@@ -1117,12 +1144,63 @@ impl OversetFluid {
|
||||
}
|
||||
|
||||
pub fn snapshot(&self) -> (OversetSolverState, OversetField) {
|
||||
(self.solver.snapshot(), self.field.clone())
|
||||
let t0 = std::time::Instant::now();
|
||||
let out = (self.solver.snapshot(), self.field.clone());
|
||||
self.t_snapshot
|
||||
.set(self.t_snapshot.get() + t0.elapsed().as_secs_f64());
|
||||
out
|
||||
}
|
||||
|
||||
pub fn restore(&mut self, saved: &(OversetSolverState, OversetField)) {
|
||||
let t0 = std::time::Instant::now();
|
||||
self.solver.restore(&saved.0);
|
||||
self.field = saved.1.clone();
|
||||
self.t_restore
|
||||
.set(self.t_restore.get() + t0.elapsed().as_secs_f64());
|
||||
}
|
||||
|
||||
/// PERF-2 P0: the solver's own split of `advance` (when `RTX_PROFILE`
|
||||
/// is set) as one printable line, with the background Poisson's
|
||||
/// setup / iterate split.
|
||||
pub fn profile_line(&self) -> Option<String> {
|
||||
let t = self.solver.timers()?;
|
||||
let (ps, pi, pc) = self.solver.background().poisson_profile();
|
||||
let s = |ns: u64| ns as f64 * 1e-9;
|
||||
let adv = s(t.advance_ns).max(1e-300);
|
||||
let pct = |ns: u64| 100.0 * s(ns) / adv;
|
||||
Some(format!(
|
||||
" advance split over {} steps ({} rounds), {:.0} s: overlap build {:.0} s ({:.1}%), predictor bg {:.0} s ({:.1}%), predictor patch {:.0} s ({:.1}%), bg Poisson {:.0} s ({:.1}%) [setup {:.0} s, iterate {:.0} s, {} solves], patch BiCGSTAB {:.0} s ({:.1}%), round exchange {:.0} s ({:.1}%), apply {:.0} s ({:.1}%), end exchange {:.0} s ({:.1}%), other {:.0} s",
|
||||
t.steps,
|
||||
t.rounds,
|
||||
adv,
|
||||
s(t.overlap_build_ns),
|
||||
pct(t.overlap_build_ns),
|
||||
s(t.predictor_bg_ns),
|
||||
pct(t.predictor_bg_ns),
|
||||
s(t.predictor_patch_ns),
|
||||
pct(t.predictor_patch_ns),
|
||||
s(t.bg_solve_ns),
|
||||
pct(t.bg_solve_ns),
|
||||
s(ps),
|
||||
s(pi),
|
||||
pc,
|
||||
s(t.patch_solve_ns),
|
||||
pct(t.patch_solve_ns),
|
||||
s(t.round_exchange_ns),
|
||||
pct(t.round_exchange_ns),
|
||||
s(t.apply_ns),
|
||||
pct(t.apply_ns),
|
||||
s(t.end_exchange_ns),
|
||||
pct(t.end_exchange_ns),
|
||||
adv - s(t.overlap_build_ns
|
||||
+ t.predictor_bg_ns
|
||||
+ t.predictor_patch_ns
|
||||
+ t.bg_solve_ns
|
||||
+ t.patch_solve_ns
|
||||
+ t.round_exchange_ns
|
||||
+ t.apply_ns
|
||||
+ t.end_exchange_ns),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn time(&self) -> f64 {
|
||||
|
||||
Reference in New Issue
Block a user