test(rtx-fsi): closure schedule by tip speed (CRESCUE_SPEED=<f>), default off
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
CI / Build CPU-Only (Explicit) (push) Canceled after 0s
CI / Python Bindings (maturin) (macos-latest) (push) Canceled after 0s
Performance Benchmarks / Run Benchmarks (push) Canceled after 0s
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Format Check (push) Canceled after 0s
CI / Clippy Check (push) Canceled after 0s
CI / Build (macos-latest) (push) Canceled after 0s
CI / Build (ubuntu-latest) (push) Canceled after 0s
CI / Test (macos-latest) (push) Canceled after 0s
CI / Python Bindings (maturin) (ubuntu-latest) (push) Canceled after 0s
CI / WASM Build + Size Check (push) Canceled after 0s
CI / Distributed Training Tests (push) Canceled after 0s
CI / CI Success (push) Canceled after 0s
Documentation / Build API Documentation (push) Canceled after 0s
Documentation / Build User Guide (push) Canceled after 0s
Route 1 of omni-cortex docs/coupling_rescue_campaign.md §12, registered in docs/closure_scheduling_campaign.md: whenever the last committed tip jump exceeds f x its trailing-2000 peak, open a coarse episode (the s=2 interpolated closure, CRESCUE_COARSE=<M> steps, re-evaluated at each end) BEFORE the step — preventive, because the s=1 closure incubates the crossing instability inside the healthy envelope and no signature-triggered rescue acts early enough (rungs A, C, A' refuted). Speed episodes are expected twice per period: not counted against the runaway-episode cap; the coarse fraction is printed at the end of the march. Verified: FSI2 committed default digit-identical knob-off vs the same-day baseline; fmt + clippy clean. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01X2GmJXeQ2njUecEKiJZ1G2
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
b66f73aeef
commit
19d8307ae4
@@ -143,6 +143,16 @@ pub struct MarchConfig {
|
||||
/// whole march stays under 1.72×; the (1.27, 2.0) death crosses 3×
|
||||
/// 145 steps before its panic and never during growth.
|
||||
pub increment_factor: f64,
|
||||
/// Route 1 of the closure-scheduling campaign
|
||||
/// (`RTX_{prefix}_CRESCUE_SPEED=<f>`, default 0 = off; needs
|
||||
/// `coupling_rescue` and `coarse_episode`): whenever the last
|
||||
/// committed tip jump exceeds f × its trailing-2000 peak, open a
|
||||
/// coarse episode BEFORE the step — the s = 2 closure at every
|
||||
/// crossing, preventively, because the s = 1 closure incubates the
|
||||
/// crossing instability inside the healthy envelope
|
||||
/// (coupling_rescue_campaign.md §12). Speed episodes are expected
|
||||
/// twice per period: not capped, reported as a coarse fraction.
|
||||
pub speed_fraction: f64,
|
||||
/// C^1 interface motion (constant acceleration across the step from
|
||||
/// the previous end velocity) instead of a constant velocity with a
|
||||
/// jump at the step boundary. See `Fsi2Harness::advance_subcycled`.
|
||||
@@ -201,6 +211,7 @@ impl MarchConfig {
|
||||
coarse_episode: num("CRESCUE_COARSE", defaults.coarse_episode as f64) as usize,
|
||||
inc_trace: std::env::var(key("INCTRACE")).ok().or(defaults.inc_trace),
|
||||
increment_factor: num("CRESCUE_INC", defaults.increment_factor),
|
||||
speed_fraction: num("CRESCUE_SPEED", defaults.speed_fraction),
|
||||
c1_interface: num("C1", f64::from(u8::from(defaults.c1_interface))) != 0.0,
|
||||
predictor: std::env::var(key("PREDICTOR")).unwrap_or(defaults.predictor),
|
||||
quiescent_release: num("QUIESCENT", f64::from(u8::from(defaults.quiescent_release)))
|
||||
@@ -355,6 +366,7 @@ pub fn run_march(case: BenchmarkCase, config: &MarchConfig) -> MarchResult {
|
||||
coarse_episode,
|
||||
ref inc_trace,
|
||||
increment_factor,
|
||||
speed_fraction,
|
||||
c1_interface,
|
||||
ref predictor,
|
||||
quiescent_release,
|
||||
@@ -500,6 +512,9 @@ pub fn run_march(case: BenchmarkCase, config: &MarchConfig) -> MarchResult {
|
||||
// Rung A′: the trailing window of predictor increments and its median.
|
||||
let mut inc_window: std::collections::VecDeque<f64> = std::collections::VecDeque::new();
|
||||
let mut running_inc_median: Option<f64> = None;
|
||||
// Route 1 bookkeeping: speed-triggered episodes and coarse steps taken.
|
||||
let mut speed_episodes = 0usize;
|
||||
let mut coarse_steps_taken = 0usize;
|
||||
let mut inc_trace_file = inc_trace.as_ref().map(|p| {
|
||||
let mut w = std::io::BufWriter::new(std::fs::File::create(p).expect("inctrace path"));
|
||||
writeln!(
|
||||
@@ -557,6 +572,7 @@ pub fn run_march(case: BenchmarkCase, config: &MarchConfig) -> MarchResult {
|
||||
Ok(o) => {
|
||||
flag_state = o.state;
|
||||
committed_nodal = o.nodal;
|
||||
coarse_steps_taken += 2;
|
||||
worst_conservation = worst_conservation.max(o.worst_conservation);
|
||||
total_skipped += o.skipped;
|
||||
total_subiterations += o.passes;
|
||||
@@ -567,7 +583,11 @@ pub fn run_march(case: BenchmarkCase, config: &MarchConfig) -> MarchResult {
|
||||
}
|
||||
let t_end_c = t_release + (step + 2) as f64 * dt;
|
||||
if $new_episode {
|
||||
coarse_episodes.push(step);
|
||||
// Speed episodes are expected every half-period;
|
||||
// only runaway-triggered ones count against the cap.
|
||||
if $reason != "tip speed" {
|
||||
coarse_episodes.push(step);
|
||||
}
|
||||
coupling_rescues += 1;
|
||||
let record = super::rescue::RescueRecord {
|
||||
step,
|
||||
@@ -664,6 +684,41 @@ pub fn run_march(case: BenchmarkCase, config: &MarchConfig) -> MarchResult {
|
||||
step += 2;
|
||||
continue;
|
||||
}
|
||||
// Route 1: the s = 2 closure whenever the tip is fast, before any
|
||||
// pass — preventive, not rescuing (closure_scheduling_campaign.md).
|
||||
if coupling_rescue
|
||||
&& coarse_episode > 0
|
||||
&& speed_fraction > 0.0
|
||||
&& step + 1 < coupled_steps
|
||||
&& uy_series.len() > super::rescue::TIP_JUMP_WINDOW
|
||||
{
|
||||
let n = uy_series.len();
|
||||
let last_jump = (uy_series[n - 1] - uy_series[n - 2]).abs();
|
||||
let peak = uy_series[n - super::rescue::TIP_JUMP_WINDOW - 1..]
|
||||
.windows(2)
|
||||
.map(|w| (w[1] - w[0]).abs())
|
||||
.fold(0.0f64, f64::max);
|
||||
if peak > 0.0 && last_jump > speed_fraction * peak {
|
||||
let fs = solver.borrow().snapshot();
|
||||
let ff = field.borrow().clone();
|
||||
let ss = flag_state.clone();
|
||||
let sn = committed_nodal.clone();
|
||||
speed_episodes += 1;
|
||||
coarse_now!(
|
||||
"tip speed",
|
||||
last_jump / peak,
|
||||
f64::NAN,
|
||||
true,
|
||||
&fs,
|
||||
&ff,
|
||||
&ss,
|
||||
&sn
|
||||
);
|
||||
coarse_remaining = coarse_episode.saturating_sub(2);
|
||||
step += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let d_n = extract(&flag_state);
|
||||
let v_n: Option<Vec<f64>> = c1_interface.then(|| extract_velocity(&flag_state));
|
||||
|
||||
@@ -1167,6 +1222,13 @@ pub fn run_march(case: BenchmarkCase, config: &MarchConfig) -> MarchResult {
|
||||
step += 1;
|
||||
}
|
||||
|
||||
if speed_fraction > 0.0 {
|
||||
println!(
|
||||
" closure schedule (f = {speed_fraction}): {speed_episodes} speed episodes, \
|
||||
{coarse_steps_taken} of {coupled_steps} coupled steps under the s = 2 closure ({:.1}%)",
|
||||
100.0 * coarse_steps_taken as f64 / coupled_steps.max(1) as f64
|
||||
);
|
||||
}
|
||||
let coupled_elapsed = phase_start.elapsed().as_secs_f64();
|
||||
let (f, s, l) = (t_fluid.get(), t_structure.get(), t_sample.get());
|
||||
let pct = |x: f64| 100.0 * x / coupled_elapsed.max(1e-9);
|
||||
|
||||
Reference in New Issue
Block a user