P1 (11/n): multipatch GPU/CPU tests use the level-list constructor
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>
This commit is contained in:
1 parent
050d12b76c
commit
84b76f49cc
1 file changed
+24
-19
@@ -26,6 +26,12 @@ FACE = ((4, 4, 8, 12), (12, 4, 16, 12))
|
|||||||
S1 = ((4, 4, 12, 12), (20, 4, 28, 12))
|
S1 = ((4, 4, 12, 12), (20, 4, 28, 12))
|
||||||
|
|
||||||
|
|
||||||
|
def levels(bounds, blocks=(None, None), objects=(), jets=(), **rest):
|
||||||
|
"""Two-level constructor keywords: one L1 rectangle or set, per-level blocks, L1 bodies/Jets."""
|
||||||
|
return dict(refinements=[bounds], level_blocks=list(blocks),
|
||||||
|
level_objects=[(), tuple(objects)], level_jets=[(), tuple(jets)], **rest)
|
||||||
|
|
||||||
|
|
||||||
def level_fine(patch_set, windows):
|
def level_fine(patch_set, windows):
|
||||||
"""Level-wide fine array with each patch window filled from `windows`."""
|
"""Level-wide fine array with each patch window filled from `windows`."""
|
||||||
out = np.full((9, *patch_set.fine_shape), np.nan, np.float32)
|
out = np.full((9, *patch_set.fine_shape), np.nan, np.float32)
|
||||||
@@ -45,21 +51,21 @@ class MultipatchCPU(unittest.TestCase):
|
|||||||
def test_rejections_before_cuda(self):
|
def test_rejections_before_cuda(self):
|
||||||
cfg = config("periodic")
|
cfg = config("periodic")
|
||||||
context = object() # never activated: every case must fail first
|
context = object() # never activated: every case must fail first
|
||||||
for kw in (dict(), dict(fine_block=(8, 4)), dict(base_block=(4, 4)),
|
for kw in (dict(), dict(blocks=(None, (8, 4))), dict(blocks=((4, 4), None)),
|
||||||
dict(fine_block=(8, 4), base_block=(4, 4), fine_objects=[circle()]),
|
dict(blocks=((4, 4), (8, 4)), objects=[circle()]),
|
||||||
dict(fine_block=(5, 4), base_block=(4, 4))):
|
dict(blocks=((4, 4), (5, 4)))):
|
||||||
with self.subTest(kw=kw), self.assertRaises(ValueError):
|
with self.subTest(kw=kw), self.assertRaises(ValueError):
|
||||||
FixedPatchStepper(cfg, ((4, 4, 8, 12), (14, 4, 18, 12)), context=context, **kw)
|
FixedPatchStepper(cfg, context=context, **levels(((4, 4, 8, 12), (14, 4, 18, 12)), **kw))
|
||||||
with self.assertRaisesRegex(ValueError, "margin"):
|
with self.assertRaisesRegex(ValueError, "margin"):
|
||||||
FixedPatchStepper(cfg, ((1, 4, 8, 12), (10, 4, 14, 12)), context=context,
|
FixedPatchStepper(cfg, context=context,
|
||||||
fine_block=(8, 4), base_block=(4, 4))
|
**levels(((1, 4, 8, 12), (10, 4, 14, 12)), blocks=((4, 4), (8, 4))))
|
||||||
from CelerisLab.body.jets import Jet, Parallel, Tube
|
from CelerisLab.body.jets import Jet, Parallel, Tube
|
||||||
cfg32 = LBMConfig(nx=32, ny=16, viscosity=.1)
|
cfg32 = LBMConfig(nx=32, ny=16, viscosity=.1)
|
||||||
span = Jet(Tube((5., 8.), 0., 22., .6), Parallel(0.), amplitude=0.)
|
span = Jet(Tube((5., 8.), 0., 22., .6), Parallel(0.), amplitude=0.)
|
||||||
with self.assertRaisesRegex(ValueError, "one jet"): # same obj_id cannot bypass it
|
with self.assertRaisesRegex(ValueError, "one jet"): # same obj_id cannot bypass it
|
||||||
FixedPatchStepper(cfg32, ((2, 2, 14, 14), (18, 2, 30, 14)), context=context,
|
FixedPatchStepper(cfg32, context=context,
|
||||||
fine_block=(4, 4), base_block=(4, 4),
|
**levels(((2, 2, 14, 14), (18, 2, 30, 14)), blocks=((4, 4), (4, 4)),
|
||||||
fine_objects=[body(8., 8.), body(24., 8.)], jets=[span])
|
objects=[body(8., 8.), body(24., 8.)], jets=[span]))
|
||||||
|
|
||||||
|
|
||||||
class MultipatchGPU(unittest.TestCase):
|
class MultipatchGPU(unittest.TestCase):
|
||||||
@@ -67,7 +73,7 @@ class MultipatchGPU(unittest.TestCase):
|
|||||||
|
|
||||||
def run_steps(self, context, cfg, bounds, coarse, fine, **kw):
|
def run_steps(self, context, cfg, bounds, coarse, fine, **kw):
|
||||||
out = []
|
out = []
|
||||||
with FixedPatchStepper(cfg, bounds, context=context, **kw) as backend:
|
with FixedPatchStepper(cfg, context=context, **levels(bounds, **kw)) as backend:
|
||||||
backend.initialize(coarse, fine)
|
backend.initialize(coarse, fine)
|
||||||
for step in self.STEPS:
|
for step in self.STEPS:
|
||||||
backend.step(step - backend.step_count)
|
backend.step(step - backend.step_count)
|
||||||
@@ -82,7 +88,7 @@ class MultipatchGPU(unittest.TestCase):
|
|||||||
p = FixedPatch2D.from_config(cfg, BOUNDS)
|
p = FixedPatch2D.from_config(cfg, BOUNDS)
|
||||||
s = FixedPatchSet2D.from_config(cfg, (BOUNDS,))
|
s = FixedPatchSet2D.from_config(cfg, (BOUNDS,))
|
||||||
coarse, fine = state(NY, NX, 1), state(*p.fine_shape, 2)
|
coarse, fine = state(NY, NX, 1), state(*p.fine_shape, 2)
|
||||||
kw = dict(coarse_boundary=mode, fine_block=(8, 4), base_block=(3, 4))
|
kw = dict(coarse_boundary=mode, blocks=((3, 4), (8, 4)))
|
||||||
old = self.run_steps(context, cfg, BOUNDS, coarse, fine, **kw)
|
old = self.run_steps(context, cfg, BOUNDS, coarse, fine, **kw)
|
||||||
new = self.run_steps(context, cfg, (BOUNDS,), coarse, level_fine(s, [fine]), **kw)
|
new = self.run_steps(context, cfg, (BOUNDS,), coarse, level_fine(s, [fine]), **kw)
|
||||||
for step, a, b in zip(self.STEPS, old, new):
|
for step, a, b in zip(self.STEPS, old, new):
|
||||||
@@ -99,7 +105,7 @@ class MultipatchGPU(unittest.TestCase):
|
|||||||
one = FixedPatchSet2D.from_config(cfg16, (S1[0],))
|
one = FixedPatchSet2D.from_config(cfg16, (S1[0],))
|
||||||
two = FixedPatchSet2D.from_config(cfg32, S1)
|
two = FixedPatchSet2D.from_config(cfg32, S1)
|
||||||
coarse, fine = state(16, 16, 3), state(*one.patches[0].fine_shape, 4)
|
coarse, fine = state(16, 16, 3), state(*one.patches[0].fine_shape, 4)
|
||||||
kw = dict(fine_block=(4, 4), base_block=(4, 4))
|
kw = dict(blocks=((4, 4), (4, 4)))
|
||||||
with CudaContext(0) as context:
|
with CudaContext(0) as context:
|
||||||
ref = self.run_steps(context, cfg16, (S1[0],), coarse, level_fine(one, [fine]), **kw)
|
ref = self.run_steps(context, cfg16, (S1[0],), coarse, level_fine(one, [fine]), **kw)
|
||||||
tiled = np.concatenate([coarse, coarse], axis=2)
|
tiled = np.concatenate([coarse, coarse], axis=2)
|
||||||
@@ -118,7 +124,7 @@ class MultipatchGPU(unittest.TestCase):
|
|||||||
s = FixedPatchSet2D.from_config(cfg, FACE)
|
s = FixedPatchSet2D.from_config(cfg, FACE)
|
||||||
coarse = state(16, 24, 5)
|
coarse = state(16, 24, 5)
|
||||||
fine = level_fine(s, [state(*p.fine_shape, 6 + i) for i, p in enumerate(s.patches)])
|
fine = level_fine(s, [state(*p.fine_shape, 6 + i) for i, p in enumerate(s.patches)])
|
||||||
kw = dict(fine_block=(4, 4), base_block=(4, 4))
|
kw = dict(blocks=((4, 4), (4, 4)))
|
||||||
leaf = s.fine_kind == ACTIVE
|
leaf = s.fine_kind == ACTIVE
|
||||||
support = s.fine_layout((4, 4)).owned
|
support = s.fine_layout((4, 4)).owned
|
||||||
outer = support & (s.fine_kind == OUTER_GHOST)
|
outer = support & (s.fine_kind == OUTER_GHOST)
|
||||||
@@ -164,7 +170,7 @@ class MultipatchBodiesGPU(unittest.TestCase):
|
|||||||
|
|
||||||
def run_steps(self, context, cfg, bounds, coarse, fine, switch=None, **kw):
|
def run_steps(self, context, cfg, bounds, coarse, fine, switch=None, **kw):
|
||||||
out = []
|
out = []
|
||||||
with FixedPatchStepper(cfg, bounds, context=context, **kw) as backend:
|
with FixedPatchStepper(cfg, context=context, **levels(bounds, **kw)) as backend:
|
||||||
backend.initialize(coarse, fine)
|
backend.initialize(coarse, fine)
|
||||||
for step in self.STEPS:
|
for step in self.STEPS:
|
||||||
if switch is not None and step == 8:
|
if switch is not None and step == 8:
|
||||||
@@ -182,8 +188,7 @@ class MultipatchBodiesGPU(unittest.TestCase):
|
|||||||
p = FixedPatch2D.from_config(cfg, BOUNDS)
|
p = FixedPatch2D.from_config(cfg, BOUNDS)
|
||||||
s = FixedPatchSet2D.from_config(cfg, (BOUNDS,))
|
s = FixedPatchSet2D.from_config(cfg, (BOUNDS,))
|
||||||
coarse, fine = state(NY, NX, 1), state(*p.fine_shape, 2)
|
coarse, fine = state(NY, NX, 1), state(*p.fine_shape, 2)
|
||||||
kw = dict(coarse_boundary=mode, fine_block=(8, 4), base_block=(3, 4),
|
kw = dict(coarse_boundary=mode, blocks=((3, 4), (8, 4)), objects=[circle()])
|
||||||
fine_objects=[circle()])
|
|
||||||
old = self.run_steps(context, cfg, BOUNDS, coarse, fine, **kw)
|
old = self.run_steps(context, cfg, BOUNDS, coarse, fine, **kw)
|
||||||
new = self.run_steps(context, cfg, (BOUNDS,), coarse, level_fine(s, [fine]), **kw)
|
new = self.run_steps(context, cfg, (BOUNDS,), coarse, level_fine(s, [fine]), **kw)
|
||||||
for step, a, b in zip(self.STEPS, old, new):
|
for step, a, b in zip(self.STEPS, old, new):
|
||||||
@@ -202,17 +207,17 @@ class MultipatchBodiesGPU(unittest.TestCase):
|
|||||||
two = FixedPatchSet2D.from_config(cfg32, self.PATCHES)
|
two = FixedPatchSet2D.from_config(cfg32, self.PATCHES)
|
||||||
coarse, fine = state(16, 16, 3), state(*one.patches[0].fine_shape, 4)
|
coarse, fine = state(16, 16, 3), state(*one.patches[0].fine_shape, 4)
|
||||||
jet = lambda x: Jet(Tube((x, 8.), 0., 6., .6), Parallel(0.), amplitude=.002)
|
jet = lambda x: Jet(Tube((x, 8.), 0., 6., .6), Parallel(0.), amplitude=.002)
|
||||||
kw = dict(fine_block=(4, 4), base_block=(4, 4))
|
kw = dict(blocks=((4, 4), (4, 4)))
|
||||||
with CudaContext(0) as context:
|
with CudaContext(0) as context:
|
||||||
for jets in ((), (jet(5.),)):
|
for jets in ((), (jet(5.),)):
|
||||||
ref = self.run_steps(context, cfg16, self.PATCHES[:1], coarse, level_fine(one, [fine]),
|
ref = self.run_steps(context, cfg16, self.PATCHES[:1], coarse, level_fine(one, [fine]),
|
||||||
switch=[(0, -.001)] if jets else None,
|
switch=[(0, -.001)] if jets else None,
|
||||||
fine_objects=[body(8., 8.)], jets=jets, **kw)
|
objects=[body(8., 8.)], jets=jets, **kw)
|
||||||
both = jets and (jet(5.), jet(21.))
|
both = jets and (jet(5.), jet(21.))
|
||||||
got = self.run_steps(context, cfg32, self.PATCHES, np.concatenate([coarse, coarse], 2),
|
got = self.run_steps(context, cfg32, self.PATCHES, np.concatenate([coarse, coarse], 2),
|
||||||
level_fine(two, [fine, fine]),
|
level_fine(two, [fine, fine]),
|
||||||
switch=[(0, -.001), (1, -.001)] if jets else None,
|
switch=[(0, -.001), (1, -.001)] if jets else None,
|
||||||
fine_objects=[body(8., 8., 5), body(24., 8., 5)],
|
objects=[body(8., 8., 5), body(24., 8., 5)],
|
||||||
jets=both or (), **kw)
|
jets=both or (), **kw)
|
||||||
for step, a, b in zip(self.STEPS, ref, got):
|
for step, a, b in zip(self.STEPS, ref, got):
|
||||||
label = f"jets={len(jets)} step {step}"
|
label = f"jets={len(jets)} step {step}"
|
||||||
|
|||||||
Reference in new issue
Block a user