FixedPatchStepper: exchange metadata on the boundary record; _boundaries name

- _exchange_spacing/_exchange_centers (two more per-level lists, only read
  for levels that have a boundary) become _BlockedBoundary.spacing/centers.
- _level_blocks dropped: remap_finest reads each layout's own .block.
- _device_boundaries -> _boundaries: the record holds host geometry, tables,
  Jets and device handles, so 'device' was misleading (the old host-only
  _boundaries list no longer exists). Tests migrated mechanically.
Remaining per-level lists (_layouts, _level_cfgs, _leaf, _state, _boundaries)
are the immutable construction plan, built before the memory preflight and
kept after close; _levels holds device handles only and is cleared on close.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-28 11:41:13 +00:00
1 parent c5a3cdb757
commit 442979b4db
18 files changed
+85 -84

No files matched your search

@@ -59,7 +59,7 @@ class ExchangeWindowCPU(unittest.TestCase):
stack.enter_context(patch.object(cuda, "memcpy_dtoh",
side_effect=lambda out, src: out.fill(0)))
backend = build(m)
b = backend._device_boundaries[1]
b = backend._boundaries[1]
self.assertIsNotNone(b.window_integral)
with self.assertRaises(RuntimeError):
backend.start_exchange_window() # not initialized
@@ -96,7 +96,7 @@ class ExchangeWindowCPU(unittest.TestCase):
with mocked_backend() as m, ExitStack() as stack:
stack.enter_context(patch.object(cuda, "memset_d8_async"))
backend = build(m, window=False)
self.assertIsNone(backend._device_boundaries[1].window_integral)
self.assertIsNone(backend._boundaries[1].window_integral)
backend.initialize(*[np.full(l.shape, 1 / 9, np.float32) for l in backend._levels])
backend.step(1)
self.assertEqual(len(accumulations(m)), 2)
@@ -120,7 +120,7 @@ class ExchangeWindowGPU(unittest.TestCase):
windowed.step(2)
plain.step(2)
windowed.start_exchange_window()
b = windowed._device_boundaries[1]
b = windowed._boundaries[1]
count = len(b.tables["cell"])
factors = np.array([.25, .25, .125, .25]) # h*dt, h*h*dt, h*h for level-1 h=.5
scale = np.zeros(4)
@@ -212,7 +212,7 @@ class ExchangeWindowShiftedMRTGPU(unittest.TestCase):
run.step(2)
if run is not plain:
run.start_exchange_window()
b = windowed._device_boundaries[1]
b = windowed._boundaries[1]
count = len(b.tables["cell"])
record = dict(scale=np.zeros(4), substeps=0)
audit_substeps(windowed, b, count, record)
@@ -228,7 +228,7 @@ class ExchangeWindowShiftedMRTGPU(unittest.TestCase):
same_bits(self, a, e)
rows = [np.empty((count, 4), np.float64) for _ in range(2)]
cuda.memcpy_dtoh(rows[0], b.window_integral)
cuda.memcpy_dtoh(rows[1], split._device_boundaries[1].window_integral)
cuda.memcpy_dtoh(rows[1], split._boundaries[1].window_integral)
np.testing.assert_array_equal(rows[0].view(np.uint64), rows[1].view(np.uint64))
out = windowed.read_exchange_window(0, level=1)