Files
CelerisLab/docs/lifecycle.md
T
ClaudeandClaude Opus 5.5 e18f7abe2b refinement: remove the dense refinement route; level_blocks is required (D2)
Deleted: kernels/refinement.cu and step/patch_step.cu (PatchExplode,
PatchFineStep, PatchCoarseStep, the CELERIS_REFINEMENT_AUDIT counters);
in FixedPatchStepper the dense branches of _build_level/_build_pair/_hop,
_apply_fine_boundary, the fine-level CurvedLinkSoA wiring (_fine_curved,
_fine_flags, _curved, _link_tables, its set_jet_amplitude/initialize/close
paths) and the now-vacuous 'requires all-blocked' guards (shifted,
projected, channel, raw exchange, several L1 rectangles, depth >= 3).

level_blocks is required: one tile (by, bx) of positive integers per level,
else ValueError before any device work naming the whole-level tile
((ny, nx) at the root, the fine window shape for one rectangle) as always
valid. No automatic tile choice. Removed route: None in level_blocks
(dense or mixed dense/blocked storage); parity of D/D, D/B and B/B is
recorded at 1573942 and 2469af7.

Kept: the uniform-grid solver (uniform.cu, Simulation, CurvedLinkSoA,
CurvedBoundaryKernel), FixedPatch2D, pinned historical runners.
Docs: compiler entries, BlockExplode comment, lifecycle, supported_settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 15:09:13 +00:00

3.0 KiB

Device state lifecycle (uniform Simulation, FixedPatchStepper)

State is grouped by what a change invalidates. This file describes the code as it is; it adds no framework. Line references are to candidate 0f8fdbc3.

Class Contents How it changes Owner rule
1. Module and its globals Compile-time (visible to the compiler, fixed per module): config.h macros incl. NX/NY, COLLISION_MODEL, BLOCK_ROOT_BC, WALL_*. Runtime per-module globals (not visible to the compiler; written by host code): __constant__ d_params, d_w, d_cx, d_cy, d_block_channel, d_block_wall; plus bound kernel handles Globals are written once by the owner right after load_module. Uniform grid: Simulation._recompile (construction, body-topology sync) loads a new module and re-uploads; update_runtime_params rewrites d_params (omega, force, n_objects) between runs. Steppers: never rewritten after construction, so they are immutable for the instance's lifetime although they are runtime values. The blocked slot/reservoir root reads its slot from the d_block_wall constant (the former dense route used WALL_* macros; both were bit-identical in the parity gates). Every owner loads its own module (compiler.load_module = module_from_file, no cache). A loaded module is never shared between live owners: globals are per module, so sharing would share mutable d_params.
2. Geometry, layout, tables flags, curved-link tables, block layouts and halo pairs, transfer (explode/coalesce) tables, block kinds Immutable for the life of an instance. Uniform grid: rebuilt by body sync. FixedPatchStepper: a geometry change is a new instance (remap_child), committed only after a successful transfer. No in-place table edits.
3. Controls and dependent boundary columns Jet amplitude -> per-link surface_velocity; body actions (uniform grid) Between steps, without a table or module rebuild (set_jet_amplitude). Host copy commits only after the device upload succeeded; a device error fails the instance.
4. Per-step state population double buffers and their parity, raw-exchange ledgers, observations Device-only during step(n) / run(n); buffer swaps are host-handle swaps. Valid on the host only after the single wait at the end of the call.

Storage routes are separate concerns:

  • Original uniform grid (uniform.cu, Simulation): whole-domain NX/NY.
  • Blocked levels (blocked.cu; every FixedPatchStepper level, including the single level of refinements=[]): NX/NY are one block window including halo.
  • Dense refinement levels (refinement.cu) were removed: level_blocks is required and every refinement level is blocked.

A single-rectangle refinement (FixedPatch2D) is stored in its own fine window frame (FixedPatchStepper.__init__, BlockLayout2D.build(*pair.fine_shape, ...)). Only a rectangle set (FixedPatchSet2D) uses the level-wide frame (2*ny, 2*nx), whose fine_layout requires that full grid to be divisible by the tile (refinement.py:240-252).