Skip to content

Commit 4334fa5

Browse files
committed
test: integrate convergence runs into ./mfc.sh test
Convergence tests now register as TestCases (kind='convergence') with a 'Convergence -> {1D,2D,Sod,Temporal} -> <scheme>' trace prefix, dispatched through _handle_case to the runner library in toolchain/mfc/test/convergence.py. Skipped by default; opt in via --only Convergence. Drops the four standalone run_*.py runner scripts and the _convergence_common helper module — their content moved into toolchain/mfc/test/convergence.py. The convergence.yml workflow shrinks from 4 hand-rolled jobs invoking python runners to a single ./mfc.sh test --only Convergence call.
1 parent 0d1a8e2 commit 4334fa5

10 files changed

Lines changed: 528 additions & 744 deletions

File tree

.github/workflows/convergence.yml

Lines changed: 7 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ env:
1010
OMPI_MCA_rmaps_base_oversubscribe: 1
1111

1212
jobs:
13-
convergence-1d:
14-
name: "1D Advection Convergence"
13+
convergence:
14+
name: "Convergence"
1515
runs-on: ubuntu-latest
16-
timeout-minutes: 60
16+
timeout-minutes: 240
1717

1818
steps:
1919
- uses: actions/checkout@v4
@@ -29,98 +29,8 @@ jobs:
2929
with:
3030
python-version: "3.12"
3131

32-
- name: Initialize MFC
33-
run: ./mfc.sh init
32+
- name: Build MFC
33+
run: ./mfc.sh build -j 4
3434

35-
- name: Run 1D convergence tests
36-
run: |
37-
source build/venv/bin/activate
38-
python toolchain/mfc/test/run_convergence_1d.py \
39-
--resolutions 64 128 256 512 1024 \
40-
--num-ranks 4
41-
42-
convergence-2d:
43-
name: "2D Isentropic Vortex Convergence"
44-
runs-on: ubuntu-latest
45-
timeout-minutes: 60
46-
47-
steps:
48-
- uses: actions/checkout@v4
49-
50-
- name: Setup Ubuntu
51-
run: |
52-
sudo apt update -y
53-
sudo apt install -y cmake gcc g++ python3 python3-dev \
54-
openmpi-bin libopenmpi-dev
55-
56-
- name: Setup Python
57-
uses: actions/setup-python@v5
58-
with:
59-
python-version: "3.12"
60-
61-
- name: Initialize MFC
62-
run: ./mfc.sh init
63-
64-
- name: Run 2D convergence tests
65-
run: |
66-
source build/venv/bin/activate
67-
python toolchain/mfc/test/run_convergence.py \
68-
--resolutions 32 64 128 \
69-
--num-ranks 4
70-
71-
convergence-sod:
72-
name: "1D Sod Shock Tube L1 Convergence"
73-
runs-on: ubuntu-latest
74-
timeout-minutes: 90
75-
76-
steps:
77-
- uses: actions/checkout@v4
78-
79-
- name: Setup Ubuntu
80-
run: |
81-
sudo apt update -y
82-
sudo apt install -y cmake gcc g++ python3 python3-dev \
83-
openmpi-bin libopenmpi-dev
84-
85-
- name: Setup Python
86-
uses: actions/setup-python@v5
87-
with:
88-
python-version: "3.12"
89-
90-
- name: Initialize MFC
91-
run: ./mfc.sh init
92-
93-
- name: Run Sod shock tube L1 convergence tests
94-
run: |
95-
source build/venv/bin/activate
96-
python toolchain/mfc/test/run_sod.py \
97-
--resolutions 64 128 256 512 \
98-
--num-ranks 4
99-
100-
convergence-temporal:
101-
name: "RK3 Temporal Order"
102-
runs-on: ubuntu-latest
103-
timeout-minutes: 60
104-
105-
steps:
106-
- uses: actions/checkout@v4
107-
108-
- name: Setup Ubuntu
109-
run: |
110-
sudo apt update -y
111-
sudo apt install -y cmake gcc g++ python3 python3-dev \
112-
openmpi-bin libopenmpi-dev
113-
114-
- name: Setup Python
115-
uses: actions/setup-python@v5
116-
with:
117-
python-version: "3.12"
118-
119-
- name: Initialize MFC
120-
run: ./mfc.sh init
121-
122-
- name: Run temporal order tests
123-
run: |
124-
source build/venv/bin/activate
125-
python toolchain/mfc/test/run_temporal_order.py \
126-
--num-ranks 4
35+
- name: Run convergence tests
36+
run: ./mfc.sh test --only Convergence --no-build -j 1

toolchain/mfc/test/_convergence_common.py

Lines changed: 0 additions & 134 deletions
This file was deleted.

toolchain/mfc/test/case.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,16 @@ class TestCase(case.Case):
155155
trace: str
156156
override_tol: Optional[float] = None
157157
restart_check: bool = False
158+
kind: str = "golden"
159+
convergence_spec: Optional[dict] = None
158160

159-
def __init__(self, trace: str, mods: dict, ppn: int = None, override_tol: float = None, restart_check: bool = False) -> None:
161+
def __init__(self, trace: str, mods: dict, ppn: int = None, override_tol: float = None, restart_check: bool = False, kind: str = "golden", convergence_spec: Optional[dict] = None) -> None:
160162
self.trace = trace
161163
self.ppn = ppn or 1
162164
self.override_tol = override_tol
163165
self.restart_check = restart_check
166+
self.kind = kind
167+
self.convergence_spec = convergence_spec
164168
merge = {**BASE_CFG.copy(), **mods}
165169
merge = {key: val for key, val in merge.items() if val is not None}
166170
super().__init__(merge)
@@ -361,11 +365,18 @@ class TestCaseBuilder:
361365
functor: Optional[Callable]
362366
override_tol: Optional[float] = None
363367
restart_check: bool = False
368+
kind: str = "golden"
369+
convergence_spec: Optional[dict] = None
364370

365371
def get_uuid(self) -> str:
366372
return trace_to_uuid(self.trace)
367373

368374
def to_case(self) -> TestCase:
375+
if self.kind == "convergence":
376+
# Convergence cases drive their own runs — the BASE_CFG mods/path
377+
# machinery is unused. Trace + spec are the only inputs.
378+
return TestCase(self.trace, {}, self.ppn, self.override_tol, self.restart_check, kind=self.kind, convergence_spec=self.convergence_spec)
379+
369380
dictionary = {}
370381
if self.path:
371382
dictionary.update(input.load(self.path, self.args, do_print=False).params)
@@ -411,6 +422,15 @@ def define_case_f(trace: str, path: str, args: List[str] = None, ppn: int = None
411422
return TestCaseBuilder(trace, mods or {}, path, args or [], ppn or 1, functor, override_tol)
412423

413424

425+
def define_convergence_case(trace: str, spec: dict, ppn: int = None) -> TestCaseBuilder:
426+
"""Register a convergence-rate test (kind='convergence').
427+
428+
`spec` must include a `runner` key naming a runner in
429+
`toolchain/mfc/test/convergence.py` plus runner-specific arguments.
430+
"""
431+
return TestCaseBuilder(trace, {}, None, None, ppn or 1, None, None, False, kind="convergence", convergence_spec=spec)
432+
433+
414434
def define_case_d(stack: CaseGeneratorStack, newTrace: str, newMods: dict, ppn: int = None, functor: Callable = None, override_tol: float = None, restart_check: bool = False) -> TestCaseBuilder:
415435
mods: dict = {}
416436

0 commit comments

Comments
 (0)