test(simulation): post-adversarial workshop benches — population survey, chunk rung, S2 density, global tier

hydrology_equilibrium_bench: bench_population_survey_all_committed_bodies
(all 267 real heightmaps solved independently — zero carved cells population-
wide, ~0.86s total, byte-exact determinism; closes Troblum B1) +
bench_per_basin_size_distribution_real_population (22,270 basins: dense wins
100% for lake carriers). bmv_gridunit_bench: chunk-64m per-cell + deep-step
canvas benches (1,838 ns/cell, ~1.7s full 4K; Option D's missing row) + S2
courses-density benches (+38-87% at chunk/block, mechanism traced to station
spacing scaling with rung cutoff). bmv_global_tier_bench (new): real per-body
radii from systems.db via BodyParamsReader — global tier ~8.85MB PNG across
the population (supersedes the ~174MB mis-priced figure), rung-0 derive
~16-21ms/body measured. All #[ignore]d release tests, stability re-run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-24 10:57:27 +02:00
co-authored by Claude Fable 5
parent 63e299adc6
commit b613443d51
5 changed files with 1252 additions and 0 deletions
+391
View File
@@ -121,6 +121,7 @@ use settled_reach_server::atlas::drainage;
use settled_reach_server::atlas::features::TerrainAnalysis;
use settled_reach_server::atlas::heightmap::{load_heightmap_png, BodyHeightmap};
use settled_reach_server::atlas::layer_proxy::{build_district_window_layer, WindowGranularity};
use settled_reach_server::atlas::river_course::{self, InventedCourse};
use settled_reach_server::atlas::scale;
use settled_reach_server::seed::{SeedChain, SeedDomain};
@@ -851,3 +852,393 @@ fn bench_block_cutoff_confirms_savings() {
}
println!();
}
// ---------------------------------------------------------------------------
// Interview-2 redirect: chunk (64 m) — the never-benched rung, now the
// proposed deepest Atlas ladder rung (Jeroen, interview 2: "the actual tile
// level rung seems unusable. maybe replace with 64?" — tile/voxel dropped
// from the Atlas ladder; chunk becomes the bottom). Same discipline as the
// original T-1154 benches above: call `derive_at_metres` directly (no
// wire-facing cutoff band exists below Quarter's 1,024 m `MIN_WL_BANDS_M`
// floor either), matched cutoff = spacing (Nyquist), 4,096-cell sweep for
// direct comparability with the existing Block/Tile row above, plus a
// realistic deep-step VIEWPORT canvas at chunk spacing (replacing the old
// 216x384m/1m-spacing deep-step bench, which measured the now-dropped tile
// rung).
// ---------------------------------------------------------------------------
/// Chunk (64 m) per-cell derive cost, matched to the existing Block/Tile
/// 4,096-cell sweep shape (`bench_block_and_tile_spacing_4096_cells` above)
/// so this row slots directly into the same comparison table. This is the
/// ONE rung on the D-243 ladder nobody had measured before interview 2 (T-1154
/// tested Block 128m and Tile-adjacent 1m/4m; chunk's 64m spacing sits
/// between them and was never run). `VOXEL_OCTAVE_WAVELENGTHS_M`'s finest
/// entry is 128m (`detail_scatter.rs:46`), so per the SAME cutoff-mechanism
/// finding `bench_block_cutoff_confirms_savings` already established for
/// Block, a cutoff at 64m (finer than every entry in that array) should
/// truncate nothing either — this bench CONFIRMS that expectation for chunk
/// specifically rather than assuming it transfers from Block's own result.
#[test]
#[ignore]
fn bench_chunk_spacing_4096_cells() {
let hm = bench_hm();
let ta = bench_ta(&hm);
let params = bench_params();
let climate = ClimateConstants::default();
let seed = SeedChain::root(99).derive(SeedDomain::Body, 1);
let grid_side = 64u32; // 4,096 cells — matches the Block/Tile sweep above
println!("\n=== Interview-2: chunk (64m) spacing derive_at_metres benchmark (4,096-cell sweep) ===");
println!(
"grid: {grid_side}x{grid_side} = {} cells/sweep\n",
grid_side * grid_side
);
let chunk_m = scale::CHUNK_M as f64; // 64 m
let block_m = scale::BLOCK_M as f64; // 128 m, for direct side-by-side
for (label, step_m, cutoff_m) in [
("chunk (64m), cutoff=64m", chunk_m, chunk_m),
("chunk (64m), UNCUT (cutoff=0)", chunk_m, 0.0),
("block (128m), cutoff=128m [reference row]", block_m, block_m),
] {
let n_cells = (grid_side * grid_side) as u64;
let t0 = Instant::now();
for row in 0..grid_side {
for col in 0..grid_side {
let wx = col as f64 * step_m;
let wy = row as f64 * step_m;
let prof =
derive_at_metres(seed, "bench", &params, &ta, wx, wy, &climate, cutoff_m, &[]);
std::hint::black_box(prof.elev_q);
}
}
let elapsed = t0.elapsed();
let per_cell_ns = elapsed.as_secs_f64() * 1e9 / n_cells as f64;
println!(
" {label:<44}: {:>8.2} ms total, {:>7.1} ns/cell ({:.3} us/cell)",
elapsed.as_secs_f64() * 1000.0,
per_cell_ns,
per_cell_ns / 1000.0
);
}
println!();
}
/// The NEW realistic deepest-step canvas — chunk (64 m) spacing replacing
/// the dropped tile (1 m) rung. Jeroen's interview-2 ruling: the old
/// 10px/tile bottom-out ("full 1920 screen at 10px/tile shows ~192x108m") is
/// in-world viewport territory (Phase 5), not Atlas map content — chunk (64
/// m, D-243's "stream/derive unit") is the new floor.
///
/// Display-band derivation for the new bottom-out, stated precisely (this is
/// the number Tyre's amendment text needs): at 1x1 px-per-gridunit (the
/// workshop's own ideal ratio, premise 5), a 3840x2160 canvas at 64 m
/// spacing covers `2160 * 64 = 138,240 m` (~138.2 km) on the smaller axis and
/// `3840 * 64 = 245,760 m` (~245.8 km) on the larger axis — i.e. the
/// bottom-out is "1 screen px per 64m gridunit", NOT "10 px per chunk" (10
/// px/gridunit would need a canvas 10x larger in EXTENT for the same pixel
/// budget, which no longer makes sense once chunk stands in for what tile's
/// 10x margin was there to buy: legibility of a 1m ground feature at low
/// pixel density; chunk itself IS the smallest legible Atlas content unit
/// now, so it wants 1x1, not a magnification margin on top of 1x1). Full
/// working: `canvas_px / gridunit_spacing_m = world_extent_m` per axis (the
/// same arithmetic the old tile bottom-out used, just at 64m instead of 1m
/// and without the 10x margin factor tile's own screen-legibility problem
/// needed). This bench uses the FULL 3840x2160 canvas at 1x1 (matching every
/// other rung's fixed-px-budget convention, per round 2 §(c) — chunk is the
/// first deepest rung that does NOT need the display-ratio-sized-canvas
/// exception the old tile rung required, precisely because it's not
/// undersized relative to a legibility margin the way 1m/10px was).
#[test]
#[ignore]
fn bench_chunk_deep_step_realistic_canvas() {
let hm = bench_hm();
let ta = bench_ta(&hm);
let params = bench_params();
let climate = ClimateConstants::default();
let seed = SeedChain::root(99).derive(SeedDomain::Body, 1);
// Full 3840x2160 canvas, 1 gridunit per screen px, 64 m spacing.
let cols = 3840u32;
let rows = 2160u32;
let cells = (rows as u64) * (cols as u64);
let step_m = scale::CHUNK_M as f64; // 64 m
let cutoff_m = step_m; // Nyquist-matched
let world_w_km = cols as f64 * step_m / 1000.0;
let world_h_km = rows as f64 * step_m / 1000.0;
println!("\n=== Interview-2: chunk (64m) deep-step realistic-canvas bench (3840x2160 @ 1x1 px/gridunit) ===");
println!(
" geometry: 3840x2160 canvas @ 64m/gridunit, 1x1 px-per-gridunit -> {world_w_km:.1} km x {world_h_km:.1} km world extent"
);
println!(" cells = 3840 * 2160 = {cells}");
println!(" {}\n", rayon_threads_report());
let (elapsed_par, ns_per_cell_par) = rect_window_replica(
seed, "bench", &params, &ta, &climate, cols, rows, step_m, cutoff_m,
);
println!(
" PARALLEL (row-chunked): {:.2} ms, {:.1} ns/cell ({:.3} us/cell)",
elapsed_par.as_secs_f64() * 1000.0,
ns_per_cell_par,
ns_per_cell_par / 1000.0
);
let pool = rayon::ThreadPoolBuilder::new()
.num_threads(1)
.build()
.expect("build single-thread rayon pool");
let (elapsed_seq, ns_per_cell_seq) = pool.install(|| {
rect_window_replica(
seed, "bench", &params, &ta, &climate, cols, rows, step_m, cutoff_m,
)
});
println!(
" SINGLE-THREAD: {:.2} ms, {:.1} ns/cell ({:.3} us/cell)",
elapsed_seq.as_secs_f64() * 1000.0,
ns_per_cell_seq,
ns_per_cell_seq / 1000.0
);
println!(
" speedup: {:.2}x\n",
elapsed_seq.as_secs_f64() / elapsed_par.as_secs_f64()
);
}
// ---------------------------------------------------------------------------
// S2 (ruled: before filing) — deep-step x high-river-density COURSES-INCLUSIVE
// cost. The last zero-data-point cell: every courses-inclusive number
// measured so far (Cross-check 1 in the results doc, 18 courses/331,776
// cells) is at District spacing. Nothing has measured courses-on cost at the
// NEW deepest rung (chunk, 64m, per interview 2) or at Block (128m) — both
// below District, where a real river window would have MORE edges in view
// per unit area (finer spacing = smaller world extent per canvas, but a real
// river network's edge density near a river is roughly constant per unit
// ground area, so a narrower window can still contain a densely-braided
// stretch). Builds real InventedCourse fixtures via the actual PUBLIC
// invention pipeline (`river_course::build_edges` + `river_course::invent_course`
// — both `pub`, unlike `layer_proxy::invent_courses_near_window` itself,
// which is private to that module; this bench replicates its per-edge
// invention loop using the same public primitives, same discipline as
// `rect_window_replica` already replicates `build_district_window_layer`'s
// internals elsewhere in this file).
// ---------------------------------------------------------------------------
/// Build a high-density `InventedCourse` set from the REAL GJ1c river
/// network — every edge whose invented course falls within
/// `inflate_m` of the given world-metre window, at the given station
/// spacing/cutoff. This is the densest REAL course set available in this
/// repo (GJ1c is the only body with a river network already wired into a
/// bench fixture) rather than a synthetic worst case — real geometry is
/// preferred per this workshop's own measurement discipline (T-1178's cross-
/// check pattern: synthetic first, then confirm on real geometry). Returns
/// the course list plus the count found, so callers can report density
/// alongside cost.
fn build_gj1c_courses_near_window(
seed: SeedChain,
ta: &TerrainAnalysis,
params: &BodyParams,
river_network: &settled_reach_server::atlas::body_world_state::RiverNetwork,
win_x0: f64,
win_y0: f64,
win_x1: f64,
win_y1: f64,
station_spacing_m: f64,
min_wavelength_m: f64,
) -> Vec<InventedCourse> {
let edges = river_course::build_edges(river_network);
let r_km = params.body_radius_km.expect("body_radius_km required");
// Inline the same pixel->world-metres formula the existing GJ1c
// cross-check bench above already uses (district_profile::pixel_to_world_m
// is `pub(crate)`, not reachable from an integration test — this is the
// SAME formula, inlined, not a different one; consistent with how
// `bench_square_window_production_fn_gj1c_real_body_crosscheck` and
// zoom_ladder_bench.rs's `bench_course_cost_on_vs_off` already do this).
let to_world = |row: u16, col: u16| -> (f64, f64) {
(
col as f64 / ta.w as f64 * (std::f64::consts::TAU * r_km * 1000.0),
(row as f64 / (ta.h - 1) as f64 - 0.5) * (std::f64::consts::PI * r_km * 1000.0),
)
};
let mut courses = Vec::new();
for edge in &edges {
let anchor_a = to_world(edge.upstream.0, edge.upstream.1);
let anchor_b = to_world(edge.downstream.0, edge.downstream.1);
let chord_m = ((anchor_a.0 - anchor_b.0).powi(2) + (anchor_a.1 - anchor_b.1).powi(2)).sqrt();
// Same 0.08 inflation fraction layer_proxy.rs's COURSE_BBOX_INFLATION_FRACTION
// uses (that constant itself is private; the value is stated in its
// own doc and reproduced here for the same bbox-cull purpose — a
// bench-local approximation of the real cull, not a claim of exact
// production parity for the cull step itself, which doesn't affect
// measured PER-CELL cost once a course is in the list).
let inflate_m = chord_m * 0.08;
let (bx0, bx1) = (
anchor_a.0.min(anchor_b.0) - inflate_m,
anchor_a.0.max(anchor_b.0) + inflate_m,
);
let (by0, by1) = (
anchor_a.1.min(anchor_b.1) - inflate_m,
anchor_a.1.max(anchor_b.1) + inflate_m,
);
if bx1 < win_x0 || bx0 > win_x1 || by1 < win_y0 || by0 > win_y1 {
continue;
}
courses.push(river_course::invent_course(
seed,
edge,
ta,
params,
station_spacing_m,
min_wavelength_m,
));
}
courses
}
/// S2: courses-on vs courses-off, at BOTH the new deepest rung (chunk, 64m)
/// and Block (128m), over a window picked to maximize real river-edge
/// density (the densest real region in the only river-network fixture this
/// repo's benches have — GJ1c). Reports the delta as both absolute ms and
/// percentage, matching `bench_course_cost_on_vs_off`'s own reporting shape
/// (District's own courses-on-vs-off number: +0.09-0.21ms against a ~5ms
/// baseline, under 5%) so this fills in the two remaining zero-data-point
/// cells on the same comparison axis.
#[test]
#[ignore]
fn bench_s2_courses_density_at_chunk_and_block() {
let (hm, ta) = gj1c_fixture();
let dr = drainage::analyze(&hm.data, hm.width, hm.height, hm.sea_level);
let rn = dr.river_network.clone();
let params = bench_params();
let climate = ClimateConstants::default();
let seed = SeedChain::root(0xC0FFEE_u64).derive(SeedDomain::Body, 7);
assert!(
!rn.river_cells.is_empty(),
"GJ1c at production working resolution must have river cells for this bench to be meaningful"
);
// Find the highest-density river region: scan river cells and pick the
// one with the most OTHER river cells within a fixed pixel radius — a
// proxy for confluence/braided density, maximizing edges-per-window
// rather than picking an arbitrary river cell as the existing single
// cross-check bench does.
let radius_px = 8i64; // small radius = local confluence density, not just "near any river"
let mut best_cell = rn.river_cells[0];
let mut best_count = -1i64;
for &cell in &rn.river_cells {
let mut count = 0i64;
for &other in &rn.river_cells {
let dr_ = cell.0 as i64 - other.0 as i64;
let dc_ = cell.1 as i64 - other.1 as i64;
if dr_ * dr_ + dc_ * dc_ <= radius_px * radius_px {
count += 1;
}
}
if count > best_count {
best_count = count;
best_cell = cell;
}
}
let r_km = params.body_radius_km.expect("body_radius_km required");
let to_world = |row: u16, col: u16| -> (f64, f64) {
(
col as f64 / ta.w as f64 * (std::f64::consts::TAU * r_km * 1000.0),
(row as f64 / (ta.h - 1) as f64 - 0.5) * (std::f64::consts::PI * r_km * 1000.0),
)
};
let center_world = to_world(best_cell.0, best_cell.1);
println!("\n=== S2: courses-on vs courses-off density bench (chunk 64m + block 128m, densest GJ1c river region) ===");
println!(
" densest river cell: {best_cell:?} ({best_count} river cells within {radius_px}px radius), world center {center_world:?}"
);
for (label, step_m) in [("chunk (64m)", scale::CHUNK_M as f64), ("block (128m)", scale::BLOCK_M as f64)] {
// Realistic-shape window at this spacing: 64x64 cells (4,096, matching
// this file's other 4,096-cell sweeps for direct comparability).
let grid_side = 64u32;
let half_extent_m = (grid_side as f64 / 2.0) * step_m;
let win_x0 = center_world.0 - half_extent_m;
let win_x1 = center_world.0 + half_extent_m;
let win_y0 = center_world.1 - half_extent_m;
let win_y1 = center_world.1 + half_extent_m;
let courses = build_gj1c_courses_near_window(
seed, &ta, &params, &rn, win_x0, win_y0, win_x1, win_y1, step_m, step_m,
);
let total_points: usize = courses.iter().map(|c| c.points.len()).sum();
let avg_points = if courses.is_empty() {
0.0
} else {
total_points as f64 / courses.len() as f64
};
println!(
"\n --- {label}: {grid_side}x{grid_side} window ({:.0}m x {:.0}m), courses_in_window={}, avg_points_per_course={:.1} (station_spacing_m={step_m}) ---",
half_extent_m * 2.0,
half_extent_m * 2.0,
courses.len(),
avg_points
);
let n_cells = (grid_side * grid_side) as u64;
let iterations = 200; // higher rep count — a single 4,096-cell sweep is sub-10ms, noisy at n=1
// Courses OFF.
let t_off = Instant::now();
for _ in 0..iterations {
for row in 0..grid_side {
for col in 0..grid_side {
let wx = win_x0 + col as f64 * step_m;
let wy = win_y0 + row as f64 * step_m;
let prof = derive_at_metres(
seed, "GJ1c", &params, &ta, wx, wy, &climate, step_m, &[],
);
std::hint::black_box(prof.elev_q);
}
}
}
let elapsed_off = t_off.elapsed();
// Courses ON.
let t_on = Instant::now();
for _ in 0..iterations {
for row in 0..grid_side {
for col in 0..grid_side {
let wx = win_x0 + col as f64 * step_m;
let wy = win_y0 + row as f64 * step_m;
let prof = derive_at_metres(
seed, "GJ1c", &params, &ta, wx, wy, &climate, step_m, &courses,
);
std::hint::black_box(prof.elev_q);
}
}
}
let elapsed_on = t_on.elapsed();
let ms_off_per_sweep = elapsed_off.as_secs_f64() * 1000.0 / iterations as f64;
let ms_on_per_sweep = elapsed_on.as_secs_f64() * 1000.0 / iterations as f64;
let delta_ms = ms_on_per_sweep - ms_off_per_sweep;
let delta_pct = 100.0 * delta_ms / ms_off_per_sweep;
let ns_per_cell_off = elapsed_off.as_secs_f64() * 1e9 / (n_cells * iterations as u64) as f64;
let ns_per_cell_on = elapsed_on.as_secs_f64() * 1e9 / (n_cells * iterations as u64) as f64;
println!(
" courses OFF: {ms_off_per_sweep:.4} ms/sweep ({ns_per_cell_off:.1} ns/cell)"
);
println!(
" courses ON: {ms_on_per_sweep:.4} ms/sweep ({ns_per_cell_on:.1} ns/cell)"
);
println!(
" delta: {delta_ms:+.4} ms/sweep ({delta_pct:+.2}%), {} courses in window",
courses.len()
);
}
println!();
}