Fault injection with the existing host fakes for FixedPatchStepper(
refinements=[]): an initialize upload failure, a BlockHaloCopy,
BlockCurvedBoundary or BlockStep launch failure, and a failing final
stream wait each raise, leave the instance failed (step/download refused)
and keep the completed step count; a failed launch never reaches the wait.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-ups for S1 (f764d68):
- a single level starts its spare buffer NaN, as PeriodicBlockStepper does,
so stale halos cannot hide (multilevel initialization unchanged);
- projected explosion is rejected for a single level;
- new tests/unit/test_single_level.py: NaN spare after initialize, per-step
launch order halo -> BFL (circles only) -> BlockStep with a null kind and
one wait per step(n), circle solids excluded from the state mask;
- the GPU bitwise comparison also covers shifted storage.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A zero-refinement FixedPatchStepper is the PeriodicBlockStepper capability:
one doubly periodic blocked SRT level (no LES, Jets or exchange
observation) whose level_objects[0] are stationary passive circles. The
circle tables come from the same checks, now blocks.static_circle_tables
(moved from block_stepper, pycuda-free); BFL, halo and BlockStep launches
are the shared helpers, with an all-ACTIVE (null) kind. Base-level bodies
stay rejected for depth >= 2. PeriodicBlockStepper and its callers are
unchanged (deleted only after S1's GPU result).
Tests: host contract rejections before CUDA for the single level; GPU
bitwise comparison against PeriodicBlockStepper for every split, with and
without the circle (the S2 gate).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
36ad523 made a manifest file missing from the checkout a 'Source mismatch',
which also broke the tests' manifest-selection helper: it reused
verify_source with hashing neutralised but still read the (renamed) files.
run_refined_dfg.source_manifest(collision, observation_mode) now owns the
frozen-manifest selection; verify_source uses it, then verifies the
checkout. The test helper calls source_manifest directly; source identity
stays owned by test_source_pin. Same errors, manifests and pins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes the regressions from the entry/compiler renames (2b3c2a7, d318911)
that Astra reproduced at d318911:
- run_refined_dfg.verify_source: a manifest file missing from the checkout
is a 'Source mismatch' (was FileNotFoundError); the current-checkout
(Jet scenario) capture hashes the manifest's harness files plus the
checkout's own 'git ls-files src', not historical src paths.
- time_window_dfg: candidate file list names kernels/blocked.cu.
- test_projected_pairs: the a135252-only harness's runtime_source is the
historical receipt value (historical_runtime_source) in the receipt
fixture and the two mocked run_case.main tests; runtime_source itself
stays tested against the a135252 package (historical_package).
Harness files, pins, manifests and thresholds are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The package already exposed it as CelerisLab.cuda.compiler; the module now
has that name and every tip caller, doc and current-tree test imports it
directly (no alias).
Historical-revision tooling is not edited: the Taylor-Green harness
(run_case.py, hash-pinned check_projected_pairs.py, assess receipts) only
runs against a135252, whose package has cuda/compiler_v2.py, and the J
campaign runners and dated docs describe past trees. Its two current-tree
tests now import that package from git (historical_package) instead of the
tip, and the kernel-root test first checks the accepted case.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PeriodicBlockStepper and FixedPatchStepper each built the blocked level's
kernel config (block window NX/NY, neutralized wall/slot/inlet fields,
omega/tau check) and each spelled out the raw BlockHaloCopy and
BlockCurvedBoundary argument lists. These now live once in lbm/blocks.py
(level_config, launch_halo_copy, launch_curved_boundary), so a kernel ABI
change has one host site. Both owners keep their own lifecycle; no new
class, no behaviour or default change. PeriodicBlockStepper now checks its
level config before any device work (same errors). Dense refinement levels
keep their own config check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kernel_v2.cu -> uniform.cu (whole-domain NX/NY, Simulation) and
blocks.cu -> blocked.cu (one block window, every blocked level), with
InitTubeFlow_v2 -> InitTubeFlow. All live callers, include comments,
CONFIG.md, lifecycle doc and current-tree tests move together; no alias.
refinement.cu keeps its name until the dense-route decision.
Historical-revision tooling that names the old files (LES source pins,
timing/J campaign runners, TG run_case, supported_settings citations at
888c8038, development notes) is unchanged on purpose.
No arithmetic change; the PTX symbol InitTubeFlow_v2 is renamed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
generate_config/compile_kernel/load_module also recorded the last build
directory and PTX in ContextVars so that bare compile_kernel() and
load_module() calls worked: a second, implicit interface beside the
explicit build_dir/ptx_path one used by every owner. compile_kernel now
requires build_dir= and load_module requires the PTX path.
Build contract tests use explicit paths; they still check per-build
header/output isolation, interleaved generation, path escapes, refusal of a
removed snapshot, and that a failed compile keeps the previous PTX and
leaves no partial output. No kernel, numerical or launch change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Simulation, PeriodicBlockStepper and FixedPatchStepper levels each repeated
generate_config -> compile_kernel -> load_module -> cleanup and the
d_params pack/upload. They now call compiler.build_module(cfg, entry,
arch=..., n_objects=..., block_root_bc=...) and compiler.set_params.
Simulation no longer keeps its build directory alive until close (nothing
read it after loading). Removes the unused compile_kernel_v2 alias.
Host fakes and lifecycle tests follow the new seam; the close-retry case
for build-directory cleanup goes with the removed cleanup step.
No kernel, numerical or launch change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Per-file class (keep conclusion / tested research code / patch snapshot /
generated pin / raw run output) with size and blob id for research/,
tests/validation/multigrid/*_evidence, output/ and BASELINE_JET_AMR.txt
at 0f8fdbc3. Draft for review; nothing removed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
d_params and the block wall/channel constants are per-module runtime
globals, immutable per stepper instance but not visible to the compiler.
Note that dense and blocked slot roots carry the wall slot as macros vs
d_block_wall respectively.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describes current module/global, table, control and per-step state
ownership for Simulation, PeriodicBlockStepper and FixedPatchStepper,
and the window vs level-wide frame of single vs multi-rectangle levels.
No code change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The views and the PeriodicPatchStepper alias stay for the existing tests
and docs (about 130 references); the comment no longer says REMOVE AFTER.
No code change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The file:line citations pointed at c95a7ba and went stale after P1, the
compile-time root modes and the kernel entry/step split. Each guard is now
named by file plus function (or the kernel #error guard) at source
revision 888c8038. No claim, scope, observation or evidence revision
changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
refinement.cu keeps its header, includes, the curved_double.cu entry
block, the #error guard and the optional CELERIS_REFINEMENT_AUDIT
counters, then includes step/patch_step.cu, which holds patch_collide,
PatchExplode, PatchFineStep and PatchCoarseStep moved verbatim (checked
against the previous refinement.cu) in the same order.
test_refinement_mrt reads refinement.cu + step/patch_step.cu; its
assertions are unchanged. The audit-build tests include refinement.cu
from the build root, so step/patch_step.cu still resolves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
blocks.cu keeps its header, includes and #error guards and then includes
the kernels, as kernel_v2.cu does:
- step/block_transfer.cu: BlockHaloCopy, BlockExplode,
BlockExplodeProjected, BlockCoalesce
- step/block_boundary.cu: BlockCurvedBoundary, BlockAccumulateExchange
- step/block_step.cu: BlockStep (rejects BLOCK_ROOT_BC == 2)
- step/block_channel.cu: unchanged (mode 2 only)
Kernel text moved verbatim (checked against the previous blocks.cu) and in
the same definition order, so the translation unit is the same sequence of
kernels. The two source-reading tests follow the move:
test_projected_explosion reads step/block_transfer.cu, test_refinement_mrt
reads blocks.cu + step/block_step.cu; their assertions are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Horsea's gates showed block_ddf/block_slot change real PTX in
BlockHaloCopy, BlockExplode and BlockExplodeProjected (6/10 modules;
BlockExplodeProjected 38 -> 40 registers) although the results stayed
exact. The stack's bar is byte-identical PTX for naming-only steps, so
those three kernels return to their K3 expressions, the helpers leave
core/layout.cuh, and test_projected_explosion goes back to its K3 form.
fill_invalid stays (its kernels were byte-identical). K4 vs K3 is now
only the NaN-fill helper.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
K4 made BlockExplodeProjected address storage through block_ddf and
block_slot (core/layout.cuh). This host test compiles the kernel text
extracted from blocks.cu, so it now also extracts those two helper
definitions from core/layout.cuh (device qualifiers -> inline) instead of
failing to compile. Assertions and tolerances unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
operators/helpers.cuh already had bounce_back_swap (the uniform steps use
it). It moves verbatim, #pragma unroll included, into its own
operators/bounce_back_swap.cuh, which helpers.cuh includes; the channel
root includes that header and calls it. bounce_back_swap_d2q9 from the
previous commit is removed. bounce_back.cuh keeps only the half-way rows
helper.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- boundary/bounce_back.cuh: apply_wall_bb_d2q9_rows(y, top_row, ...) is
the existing half-way y-wall correction with an explicit top row;
apply_wall_bb_d2q9_y_pull keeps its signature and calls it with NY - 2.
bounce_back_swap_d2q9(f) names the full opposite-pair swap.
- streaming/pull_double_buffer.cuh: load_node(fi, n, f) loads one node's
stored populations.
- step/block_channel.cu uses all three instead of its inline copies: the
wall swap, the outlet donor gather, and rows 1 / ny-2 (now one call with
the physical top row; same y == 1 / y == top_row order and loads).
Same statements, branch order, indices and arithmetic.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- core/layout.cuh: block_ddf(f, block_cell[, cells]) returns the start of a
block's populations and block_slot(block_cell, cells, q) the offset of one
population; BlockHaloCopy, BlockExplode and BlockExplodeProjected use them
instead of repeating (c / cells) * NQ * cells [+ q * cells + c % cells].
BlockExplode keeps its loop-hoisted parent base; types stay uint64_t /
unsigned long; the expressions are the same ones, now named.
- core/cell_kind.cuh: fill_invalid(f) writes the NaN marker; BlockStep,
BlockChannelStep and PatchFineStep call it instead of three copies of the
loop.
No change to operation order, types, launches or arithmetic.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- core/cell_kind.cuh holds KIND_ACTIVE/INNER/OUTER (was a constexpr in
blocks.cu that step/block_channel.cu and the channel_root.cpp shim
relied on or redefined); blocks.cu, block_channel.cu and the shim now
include it.
- blocks.cu checks the lattice/model #error guard before the
BLOCK_ROOT_BC guard and mode includes, so an unsupported build reports
the real reason first.
- operators/block_collision.cuh includes what it uses (params, macro,
SRT/MRT collision) instead of relying on blocks.cu's include order.
Preprocessor-only: same kernels, same statements, same arithmetic.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Manifests and receipts unchanged. Each of the 8 group-A identity tests now
extracts its manifest's recorded commit and verifies hashes there instead of
against the current checkout. Tamper assertions and runner source refusals are
kept; missing recorded history is an explicit failure, not a skip or repin.
Names the exact SRT/MRT parity tests and their sub-case scope (SRT: one
of 18 sub-cases, unidentified; MRT: 12 sub-cases, default outlet settings,
with the runs that recorded the pass), cites blocks.py:134 for tile
divisibility, labels refinement.py:457 as the fine-boundary re-check, and
says 'measured at 36ffc8b1' for the Taylor-Green observation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test-side only; no production, manifest or pin change. Group A identity
checks (test_source_pin and the jets.py pins) are unchanged and stay
failing as recorded.
B test_refined_dfg: receipt/plan fixtures load the frozen manifest JSON
that verify_source returns for a matching tree (frozen_manifest), and
the two manifest-selection assertions call verify_source with only its
working-tree hash comparison neutralised (selected_manifest), so the
malformed/collision/observation-mode/checkout receipt checks run again.
test_source_pin remains the single identity check.
C test_channel_root: int(owner)-1 (uint64-int became float on NumPy 1);
test_shifted_storage: FP32 NaN fill so the arrays stay FP32. Both reach
the intended immutable/representation/FP32/density checks.
D test_block_stepper fake gets _ddf_shifting; test_fine_surface_gpu sets
_boundary_hosts/_level_jets instead of the read-only fine_boundary view;
test_refinement_followup fake_backend sets _layouts/_ddf_shifting/
_level_cfgs instead of the read-only fine_layout view (as reviewed in
32da2d73).
E test_kernel_contracts_reject_before_upload: an inconsistent pair tau is
now first rejected by the hierarchy chain check; the test asserts that
rejection, then bypasses _check_chain to prove the per-level omega/tau
guard still rejects, and asserts no mem_alloc/memcpy_htod in either case.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy tests/integration/test_checkpoint_bodies_gpu.py byte-for-byte from 34b30c434f. Base c95a7baae4. No production or dependency changes. GPU execution is deferred to the assigned executor.
One page listing supported settings, each with the guard enforcing it
(file:line at c95a7ba) and the existing tests exercising it. Measured
observations are labelled by their exact tested case (SRT strict-parity
1/4320 values ~2 ULP with unresolved cause; V3 TG constant explosion
aggregate; curved-wall r1 pilot; V4 NOT_STEADY), not stated as general
bounds. Documentation only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The pinned BUILD_SOURCES are the a135252 qualification build inputs.
generate_config hashes the whole kernel snapshot, so after K1/K2 the
working-tree kernels (legitimately) no longer reproduce them. The test
now archives src/CelerisLab/lbm/kernels at NUMERICAL_REVISION and points
compiler_v2._KERNEL_DIR there; config headers are still rendered by
today's compiler. BUILD_SOURCES and the equality assertion are unchanged;
each size is a subTest; a missing NUMERICAL_REVISION fails (no skip).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
surface_link_velocity already runs jet_link_shapes; CurvedLinkSoA.
assign_surface and _prepare_blocked_boundary then ran it again with the
same jets and hits to fill the host jet cache. A private _surface_links
returns (velocity, aperture, shape, jet_id) from the one call; both
callers use it. surface_link_velocity keeps its two-value public
contract (now a thin wrapper). Same values, same validation order, same
cache contents; host geometry preparation only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drop legacy constructor prose (child=/mutual exclusion), retarget
README and fixed_three_level_multipatch examples to refinements /
level_blocks, and fix stepper error/doc strings that still named
fine_block/base_block or a fixed gap >= 4 (unions use dependency
closure). Wording only; no behavior change.
Removes the legacy entry points now that every caller is migrated:
FixedPatchStepper(cfg, *, context, refinements, coarse_boundary,
level_blocks, level_objects, level_jets, observe_*, explosion) and
initialize(*level_g). Deleted: positional bounds, fine_block, base_block,
fine_objects, jets, child, child_block, child_objects, child_jets,
child_rectangles_in_parent, initialize(coarse_g/fine_g/child_g),
_legacy_levels and _initial_levels. Docstring, README and docs describe
the level lists. Compatibility views (patch, fine_boundary, ...) and the
PeriodicPatchStepper alias are unchanged (separate follow-up).
Error -> rule table (legacy keyword check -> level-list rule now firing):
- several patches without fine_block/base_block -> _check_levels
'several patches require fine_block and base_block' (unchanged rule)
- base_block without fine_block -> 'a blocked level requires blocked
refined levels below it'
- nested child without all blocks -> 'three or more levels must all be
blocked' / 'a blocked level requires ...'
- fine_objects/jets with a nested child ('only on L2') -> 'bodies/Jets are
supported only on the finest level of a nested hierarchy'
- child_objects/child_jets without a nested child -> 'level_objects/
level_jets needs one entry per level'
- scalar child with several L1 patches ('scalar child requires one parent
patch') -> hierarchy 'a scalar child requires a scalar parent'
- child vs child_rectangles_in_parent mutually exclusive -> no level-list
equivalent (cannot be expressed); covered by the new explicit
RemovedLegacyAPI test: removed keywords and positional bounds raise
TypeError before any context use, initialize has only *level_g.
The InitialLevels test of the removed adapter is replaced by that test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One local levels(bounds, blocks, objects, jets, **rest) builds the
two-level lists; run_steps and every rejection case use it. All five
before-CUDA rejections, the margin and one-jet checks keep their inputs.
Assertions unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>