stepper: bind moving-circle kernels only for D2Q9 double buffer
Both kernels are compiled under DIM == 2, but LBMStepper requested them for every double-buffer module, so stationary D3Q19 double-buffer construction would fail at get_function. Moving circles already reject D3Q19 and EsoPull at initialize. Stale latch comment updated. Parametrized CPU test with a module double that lacks the symbols. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
0d6df6e6b8
commit
353a7b03c4
@@ -21,7 +21,7 @@ class LBMStepper:
|
|||||||
|
|
||||||
self._esopull = (cfg.streaming == "esopull")
|
self._esopull = (cfg.streaming == "esopull")
|
||||||
# Set by the owner when a step would be wrong (translating circles
|
# Set by the owner when a step would be wrong (translating circles
|
||||||
# excluded from the packed links before the moving kernels exist).
|
# without attached moving tables, a pending target, or a failed step).
|
||||||
self.blocked: str | None = None
|
self.blocked: str | None = None
|
||||||
self.moving = None # MovingTables attached by the owner (translating circles)
|
self.moving = None # MovingTables attached by the owner (translating circles)
|
||||||
|
|
||||||
@@ -39,8 +39,10 @@ class LBMStepper:
|
|||||||
self.apply_esopull_curved_fn = module.get_function("ApplyEsoPullCurvedKernel")
|
self.apply_esopull_curved_fn = module.get_function("ApplyEsoPullCurvedKernel")
|
||||||
self.sensor_fn = module.get_function("SensorKernel")
|
self.sensor_fn = module.get_function("SensorKernel")
|
||||||
self.force_region_fn = module.get_function("ForceRegionKernel")
|
self.force_region_fn = module.get_function("ForceRegionKernel")
|
||||||
self.moving_fn = None if self._esopull else module.get_function("MovingCircleLinks")
|
# Moving-circle kernels exist only in D2Q9 double-buffer modules.
|
||||||
self.moving_cells_fn = None if self._esopull else module.get_function("MovingCircleCells")
|
moving = not self._esopull and cfg.is_d2q9
|
||||||
|
self.moving_fn = module.get_function("MovingCircleLinks") if moving else None
|
||||||
|
self.moving_cells_fn = module.get_function("MovingCircleCells") if moving else None
|
||||||
|
|
||||||
tpb = cfg.threads_per_block
|
tpb = cfg.threads_per_block
|
||||||
self.block = (tpb, 1, 1)
|
self.block = (tpb, 1, 1)
|
||||||
|
|||||||
@@ -310,6 +310,24 @@ def test_zero_motion_target_is_consumed_by_run_one(monkeypatch):
|
|||||||
assert ("step", 3, False) in writes
|
assert ("step", 3, False) in writes
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("streaming,d2q9,bound", [("double_buffer", True, True),
|
||||||
|
("double_buffer", False, False),
|
||||||
|
("esopull", True, False)])
|
||||||
|
def test_moving_kernels_bound_only_for_d2q9_double_buffer(monkeypatch, streaming, d2q9, bound):
|
||||||
|
from CelerisLab.lbm import stepper as stepper_module
|
||||||
|
monkeypatch.setattr(stepper_module.cuda, "mem_alloc", lambda n: object())
|
||||||
|
moving = {"MovingCircleLinks", "MovingCircleCells"}
|
||||||
|
|
||||||
|
def get_function(name):
|
||||||
|
if name in moving and not (d2q9 and streaming == "double_buffer"):
|
||||||
|
raise KeyError(name) # absent from D3Q19 / EsoPull modules
|
||||||
|
return lambda *a, **k: None
|
||||||
|
cfg = SimpleNamespace(streaming=streaming, threads_per_block=128, is_d2q9=d2q9,
|
||||||
|
nx=16, ny=8, nz=4, nq=9 if d2q9 else 19)
|
||||||
|
stepper = stepper_module.LBMStepper(SimpleNamespace(), SimpleNamespace(get_function=get_function), cfg)
|
||||||
|
assert (stepper.moving_fn is not None) == bound and (stepper.moving_cells_fn is not None) == bound
|
||||||
|
|
||||||
|
|
||||||
def test_moving_diagnostics_empty_shape_matches_layout(monkeypatch):
|
def test_moving_diagnostics_empty_shape_matches_layout(monkeypatch):
|
||||||
from CelerisLab.body.motion import MovingTables
|
from CelerisLab.body.motion import MovingTables
|
||||||
sim = make_simulation(monkeypatch)
|
sim = make_simulation(monkeypatch)
|
||||||
|
|||||||
Reference in New Issue
Block a user