Skip to content

Commit 603ce01

Browse files
authored
feat(params): support real(stp) declarations in Fortran codegen (#1458)
1 parent a21bfbf commit 603ce01

9 files changed

Lines changed: 103 additions & 131 deletions

File tree

.claude/rules/common-pitfalls.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
- Grid dimensions: `m`, `n`, `p` (cells in x, y, z). 1D: n=p=0. 2D: p=0.
55
- Interior domain: `0:m`, `0:n`, `0:p`
66
- Buffer/ghost region: `-buff_size:m+buff_size` (similar for n, p in multi-D)
7-
- `buff_size` depends on WENO order and features (typically `2*weno_polyn + 2`)
7+
- `buff_size` is **not** a single formula: it's set per reconstruction scheme (WENO/MUSCL/IGR) in
8+
`s_configure_coordinate_bounds` (`m_helper_basic.fpp`) and floored higher for Lagrange bubbles and IB.
9+
Read that routine for the current value rather than assuming one.
810
- Domain bounds: `idwint(1:3)` (interior `0:m`), `idwbuff(1:3)` (with ghost cells)
911
- Cell-center coords: `x_cc(-buff_size:m+buff_size)`, `y_cc(...)`, `z_cc(...)`
1012
- Cell-boundary coords: `x_cb(-1-buff_size:m+buff_size)`
@@ -38,8 +40,8 @@
3840
- Boundary condition symmetry requirements must be maintained
3941

4042
## Compiler-Specific Issues
41-
- CI-gated compilers (must always pass): gfortran, nvfortran, Cray ftn, and Intel ifx
42-
- AMD flang is additionally supported for `--gpu mp` builds but not in the CI matrix
43+
- See the compiler-backend matrix in `.claude/rules/gpu-and-mpi.md` for which compilers
44+
are CI-gated and which backends each supports.
4345
- Each compiler has different strictness levels and warning behavior
4446
- Fypp macros must expand correctly for both GPU and CPU builds
4547

@@ -54,12 +56,8 @@
5456
- Do not regenerate ALL golden files unless you understand every output change
5557

5658
## PR Checklist
57-
Before submitting a PR:
58-
- [ ] `./mfc.sh format -j 8` (auto-format)
59-
- [ ] `./mfc.sh precheck -j 8` (5 CI lint checks)
60-
- [ ] `./mfc.sh build -j 8` (compiles)
61-
- [ ] `./mfc.sh test --only <relevant> -j 8` (tests pass)
59+
The base loop (format → precheck → build → test → one logical commit) is the
60+
Development Workflow Contract in `CLAUDE.md`. Beyond it, watch for:
6261
- [ ] If adding parameters: definitions.py (_r + _nv) updated; cmake reconfigured; case_validator.py if constraints
6362
- [ ] If modifying `src/common/`: all three targets tested
64-
- [ ] If changing output: golden files regenerated for affected tests
65-
- [ ] One logical change per commit
63+
- [ ] If changing output: golden files regenerated for affected tests (`./mfc.sh test --generate --only <tests>`)

.claude/rules/fortran-conventions.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ Every Fortran module follows this pattern:
1515
- Finalization subroutine: `s_finalize_<feature>_module`
1616

1717
## Naming
18-
- Modules: `m_<feature>`
19-
- Public subroutines: `s_<verb>_<noun>`
20-
- Public functions: `f_<verb>_<noun>`
21-
- Private/local variables: no prefix required
22-
- Constants: descriptive names, not ALL_CAPS
18+
See "Naming Conventions" in `CLAUDE.md`.
2319

2420
## Forbidden Patterns
2521

@@ -57,10 +53,8 @@ Enforced by convention/code review (not automated):
5753
- Fortran-side runtime validation also exists in `m_checker*.fpp` files using `@:PROHIBIT`
5854

5955
## Precision Types
60-
- `wp` (working precision): used for computation. Double by default.
61-
- `stp` (storage precision): used for field data arrays and I/O. Double by default.
62-
- In single-precision mode (`--single`): both become single.
63-
- In mixed-precision mode (`--mixed`): wp=double, stp=half.
56+
`wp`/`stp` are defined in `CLAUDE.md` (`wp` = computation, `stp` = field-data storage + I/O). Detail:
57+
- Modes: default both double; `--single` → both single; `--mixed` → wp=double, stp=half.
6458
- MPI type matching: `mpi_p` must match `wp`, `mpi_io_p` must match `stp`.
6559
- Always use generic intrinsics: `sqrt` not `dsqrt`, `abs` not `dabs`.
6660
- Cast with `real(..., wp)` or `real(..., stp)`, never `dble(...)`.

.claude/rules/gpu-and-mpi.md

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,17 @@ compiles to either OpenACC or OpenMP target offload depending on the build flag:
2323

2424
### Key GPU Macros (always use the `GPU_*` prefix)
2525

26-
Inline macros (use `$:` prefix):
27-
- `$:GPU_PARALLEL_LOOP(collapse=N, private=[...], reduction=[...], reductionOp='+')`
28-
Parallel loop over GPU threads. Most common GPU macro.
29-
- `$:END_GPU_PARALLEL_LOOP()` — Required closing for GPU_PARALLEL_LOOP.
30-
- `$:GPU_LOOP(collapse=N, ...)` — Inner loop within a GPU parallel region.
31-
- `$:GPU_ENTER_DATA(create=[...])` — Allocate device memory (unscoped).
32-
- `$:GPU_EXIT_DATA(delete=[...])` — Free device memory.
33-
- `$:GPU_UPDATE(host=[...])` — Copy device → host (before MPI send).
34-
- `$:GPU_UPDATE(device=[...])` — Copy host → device (after MPI receive).
35-
- `$:GPU_ROUTINE(parallelism='[seq]')` — Mark routine for device compilation.
36-
- `$:GPU_DECLARE(create=[...])` — Declare device-resident data.
37-
- `$:GPU_ATOMIC(atomic='update')` — Atomic operation on device.
38-
- `$:GPU_WAIT()` — Synchronization barrier.
39-
40-
Block macros (use `#:call`/`#:endcall`):
41-
- `GPU_PARALLEL(...)` — GPU parallel region (used for scalar reductions like `maxval`/`minval`).
42-
- `GPU_DATA(copy=..., create=..., ...)` — Scoped data region.
43-
- `GPU_HOST_DATA(use_device_addr=[...])` — Host code with device pointers.
44-
45-
Typical GPU loop pattern (used 750+ times in the codebase):
26+
Full set with signatures in `parallel_macros.fpp`. The ones you reach for most:
27+
- `$:GPU_PARALLEL_LOOP(collapse=N, private=[...], reduction=[...], reductionOp='+')`
28+
+ `$:END_GPU_PARALLEL_LOOP()` — parallel spatial loop; by far the most common (see pattern below).
29+
- `$:GPU_LOOP(collapse=N, ...)` — inner loop *within* a parallel region.
30+
- `$:GPU_UPDATE(host=[...])` / `$:GPU_UPDATE(device=[...])` — device↔host copies (around MPI; see below).
31+
- `#:call GPU_PARALLEL(...)` — block region for scalar reductions (`maxval`/`minval`).
32+
33+
Others in `parallel_macros.fpp`: `GPU_ENTER_DATA`/`GPU_EXIT_DATA`, `GPU_DECLARE`, `GPU_ROUTINE`,
34+
`GPU_ATOMIC`, `GPU_WAIT`, and the block macros `GPU_DATA`, `GPU_HOST_DATA`.
35+
36+
Typical GPU loop pattern (the dominant spatial-loop idiom):
4637
```
4738
$:GPU_PARALLEL_LOOP(private='[i,j,k,l]', collapse=3)
4839
do l = idwbuff(3)%beg, idwbuff(3)%end
@@ -108,16 +99,10 @@ Use `#ifdef` for feature, target, compiler, and library gating:
10899
- `MFC_POST_PROCESS` — Only in post_process builds
109100

110101
### Compiler gating (for compiler-specific workarounds)
111-
- `_CRAYFTN` — Cray Fortran compiler
112-
- `__NVCOMPILER_GPU_UNIFIED_MEM` — NVIDIA unified memory (GH-200 / `--unified`)
113-
- `__PGI` — Legacy PGI/NVIDIA compiler
114-
- `__INTEL_COMPILER` — Intel compiler
115-
- `FRONTIER_UNIFIED` — Frontier HPC unified memory
116-
117-
### Library-specific code
118-
- FFTW (`m_fftw.fpp`) uses heavy `#ifdef` gating for `MFC_GPU` and `__PGI`
119-
- CUDA Fortran (`cudafor` module) is gated behind `__NVCOMPILER_GPU_UNIFIED_MEM`
120-
- SILO/HDF5 interfaces may have conditional paths
102+
Compiler/feature macros: `_CRAYFTN`, `__NVCOMPILER_GPU_UNIFIED_MEM` (NVIDIA unified mem, GH-200 /
103+
`--unified`), `__PGI` (legacy PGI/NVIDIA), `__INTEL_COMPILER`, `FRONTIER_UNIFIED`. Library code is
104+
similarly gated (FFTW in `m_fftw.fpp` on `MFC_GPU`/`__PGI`; CUDA Fortran `cudafor` on
105+
`__NVCOMPILER_GPU_UNIFIED_MEM`; SILO/HDF5 paths). Grep the relevant file for exact usage.
121106

122107
When adding new `#ifdef` blocks, always provide an `#else` or `#endif` path so
123108
the code compiles in all configurations (CPU-only, GPU-ACC, GPU-OMP, with/without MPI).

.claude/rules/parameter-system.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Parameter System
22

33
## Overview
4-
MFC has ~3,400 simulation parameters defined in Python and read by Fortran via namelist files.
4+
MFC's simulation parameters are defined in Python and read by Fortran via namelist files.
55

66
## Parameter Flow: Python → Fortran
77

@@ -37,7 +37,10 @@ at CMake configure time — no manual Fortran edits needed for simple scalar par
3737
**Exceptions — still require manual Fortran edits:**
3838
- Array variables (e.g. `logical, dimension(num_fluids_max)`) → declare in `src/*/m_global_parameters.fpp`
3939
- Derived-type members (`fluid_pp%attr`, `patch_icpp(i)%attr`) → declare in the relevant derived type
40-
- Case-optimization parameters → add to `CASE_OPT_PARAMS` and the `#:else` block in `src/simulation/m_global_parameters.fpp`
40+
- Case-optimization parameters → add to `CASE_OPT_PARAMS` and the `#:else` block in `src/simulation/m_global_parameters.fpp`.
41+
Gotcha: under `--case-optimization` these are baked into the binary and dropped from the simulation namelist
42+
(`case_dicts.py` filters them), so changing one needs a *rebuild*, not just a case edit — and building without
43+
the flag makes them read from `.inp` again.
4144

4245
## Case Files
4346
- Case files are Python scripts (`.py`) that define a dict of parameters
@@ -47,15 +50,24 @@ at CMake configure time — no manual Fortran edits needed for simple scalar par
4750
- Search parameters with `./mfc.sh params <query>`
4851

4952
## Fortran-Side Runtime Validation
50-
Each target has `m_checker*.fpp` files (e.g., `src/simulation/m_checker.fpp`,
51-
`src/common/m_checker_common.fpp`) containing runtime parameter validation using
52-
`@:PROHIBIT(condition, message)`. When adding parameters with physics constraints,
53-
add Fortran-side checks here in addition to `case_validator.py`.
53+
Runtime parameter validation uses `@:PROHIBIT(condition, message)`. Put a check where it runs:
54+
- **Shared across all three targets**`src/common/m_checker_common.fpp` (`s_check_inputs_common`,
55+
with `#ifndef MFC_*` gates for target-specific exclusions). This holds most checks.
56+
- **Simulation-only**`src/simulation/m_checker.fpp` (WENO/MUSCL/IGR/time-stepping/compiler checks).
57+
- **Pre/post-only**`src/{pre,post}_process/m_checker.fpp`. Note: their `s_check_inputs` are
58+
currently empty — that's the right place for a pre/post-only constraint, not `m_checker_common.fpp`.
59+
60+
Add Fortran-side checks in addition to `case_validator.py`.
5461

5562
## Analytical Initial Conditions
5663
String expressions in parameters become Fortran code via `case.py.__get_analytic_ic_fpp()`.
5764
These are compiled into the binary, so syntax errors cause build failures, not runtime errors.
5865

66+
Gotcha: each IC variable (`alpha_rho`, `vel`, `pres`, `alpha`, `Y`, `Bx`...) maps to an `eqn_idx%…`
67+
expression in `QPVF_IDX_VARS` (`case.py`). Adding a conserved variable that patches can set means
68+
updating that map *and* the Fortran `eqn_idx` builder to agree — a mismatch is a silent wrong-index, not
69+
an error. (This is also why `Bx`/`By`/`Bz` use `eqn_idx%B%end-1/%end`, to stay valid in 1D/2D.)
70+
5971
Available variables in analytical IC expressions:
6072
- `x`, `y`, `z` — cell-center coordinates (mapped to `x_cc(i)`, `y_cc(j)`, `z_cc(k)`)
6173
- `xc`, `yc`, `zc` — patch centroid coordinates

CLAUDE.md

Lines changed: 42 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ toolchain for building/running/testing, and supports GPU acceleration via OpenAC
66
OpenMP target offload. It must compile with gfortran, nvfortran, Cray ftn, and Intel ifx (CI-gated).
77
AMD flang is additionally supported for OpenMP target offload GPU builds.
88

9+
## Working Style
10+
11+
Make surgical changes: every changed line should trace to the request. Don't refactor,
12+
reformat, or "improve" adjacent code — in a four-compiler, golden-file-gated codebase,
13+
incidental edits are how regressions slip in. For general behavioral guidance (simplicity,
14+
surfacing assumptions, verifiable success criteria), invoke the `karpathy-guidelines` skill.
15+
916
## Commands
1017

1118
Prefer using `./mfc.sh` as the entry point for building, running, testing, formatting,
@@ -15,81 +22,41 @@ compilers directly unless you have a specific reason.
1522

1623
All commands run from the repo root via `./mfc.sh`.
1724

18-
```bash
19-
# Building
20-
./mfc.sh build -j 8 # Build all 3 targets (pre_process, simulation, post_process)
21-
./mfc.sh build -t simulation -j 8 # Build only simulation
22-
./mfc.sh build --gpu acc -j 8 # Build with OpenACC GPU support
23-
./mfc.sh build --gpu mp -j 8 # Build with OpenMP target offload GPU support
24-
./mfc.sh build --debug -j 8 # Debug build
25-
./mfc.sh build -i case.py --case-optimization -j 8 # Case-optimized build (10x speedup)
26-
27-
# Running
28-
./mfc.sh run case.py -n 4 # Run case with 4 MPI ranks
29-
./mfc.sh run case.py --no-build # Run without rebuilding
30-
./mfc.sh run case.py -e batch -N 2 -n 4 -c phoenix -a ACCOUNT # Batch submit on Phoenix
31-
32-
# Testing
33-
./mfc.sh test -j 8 # Run full test suite (560+ tests)
34-
./mfc.sh test --only 1D -j 8 # Only 1D tests
35-
./mfc.sh test --only 2D Bubbles -j 8 # Only 2D bubble tests
36-
./mfc.sh test --only <UUID> -j 8 # Run one specific test by UUID
37-
./mfc.sh test -l # List all tests with UUIDs and traces
38-
./mfc.sh test -% 10 -j 8 # Run 10% random sample
39-
./mfc.sh test --generate --only <feature> # Regenerate golden files after intentional output change
40-
41-
# Verification (pre-commit CI checks)
42-
./mfc.sh precheck -j 8 # Run all 6 lint checks (same as CI gate)
43-
./mfc.sh format -j 8 # Auto-format Fortran (.fpp/.f90) + Python
44-
./mfc.sh lint # Ruff lint + Python unit tests
45-
./mfc.sh spelling # Spell check
46-
47-
# Module loading (HPC clusters only — must use `source`)
48-
source ./mfc.sh load -c p -m g # Load Phoenix GPU modules
49-
source ./mfc.sh load -c f -m g # Load Frontier GPU modules
50-
source ./mfc.sh load -c p -m c # Load Phoenix CPU modules
51-
52-
# Other
53-
./mfc.sh validate case.py # Validate case file without running
54-
./mfc.sh params <query> # Search 3,400 case parameters
55-
./mfc.sh clean # Remove build artifacts
56-
./mfc.sh new <name> # Create new case from template
57-
```
58-
59-
## System Identification and Module Loading
60-
61-
MFC targets HPC clusters. Before building on a cluster, load the correct modules
62-
via `source ./mfc.sh load -c <slug> -m <mode>`.
63-
64-
To identify the current system, check multiple signals — hostname alone is not always
65-
sufficient (compute nodes may differ from login nodes):
25+
Run `./mfc.sh <command> --help` for the full flag set; the most-used invocations:
6626

6727
```bash
68-
hostname # e.g., login-phoenix-gnr-2.pace.gatech.edu
69-
echo $LMOD_SYSHOST # e.g., "phoenix" (most reliable when set)
70-
echo $CRAY_LD_LIBRARY_PATH # Non-empty → Cray system (Frontier, Carpenter Cray)
71-
echo $MODULESHOME # Confirms module system is available
28+
# Build / run / test (-j N = parallel jobs)
29+
./mfc.sh build -j 8 # all 3 targets; flags: -t <target>, --gpu acc|mp, --debug,
30+
# -i case.py --case-optimization (10x speedup)
31+
./mfc.sh run case.py -n 4 # run with 4 MPI ranks; --no-build; -e batch (toolchain/templates/)
32+
./mfc.sh test -j 8 # full suite; --only <1D|Bubbles|UUID>, -l, -% N (sample),
33+
# --generate (regenerate golden files after an intended output change)
34+
35+
# Verify before committing
36+
./mfc.sh precheck -j 8 # all CI lint checks
37+
./mfc.sh format -j 8 # auto-format Fortran (.fpp/.f90) + Python
38+
./mfc.sh lint # ruff lint + Python unit tests (spelling: ./mfc.sh spelling)
39+
40+
# Case files
41+
./mfc.sh validate case.py # validate without running
42+
./mfc.sh params <query> # search case parameters
43+
./mfc.sh new <name> # new case from template (clean: ./mfc.sh clean)
7244
```
7345

74-
Supported systems and their slugs (full list in `toolchain/modules`):
46+
Module loading (`source ./mfc.sh load -c <slug> -m <mode>`) is covered under System Identification below.
7547

76-
| Slug | System | GPU Backend | Example |
77-
|------|--------|-------------|---------|
78-
| `p` | GT Phoenix | OpenACC (nvfortran) | `source ./mfc.sh load -c p -m g` |
79-
| `f` | OLCF Frontier | OpenACC/OpenMP (Cray ftn) | `source ./mfc.sh load -c f -m g` |
80-
| `tuo` | LLNL Tuolumne | OpenMP (Cray ftn) | `source ./mfc.sh load -c tuo -m g` |
81-
| `d` | NCSA Delta | OpenACC (nvfortran) | `source ./mfc.sh load -c d -m g` |
82-
| `b` | PSC Bridges2 | OpenACC (nvfortran) | `source ./mfc.sh load -c b -m g` |
83-
| `cc` | DoD Carpenter (Cray) | CPU only | `source ./mfc.sh load -c cc -m c` |
84-
| `c` | DoD Carpenter (GNU) | CPU only | `source ./mfc.sh load -c c -m c` |
85-
| `o` | Brown Oscar | OpenACC (nvfortran) | `source ./mfc.sh load -c o -m g` |
86-
| `h` | UF HiPerGator | OpenACC (nvfortran) | `source ./mfc.sh load -c h -m g` |
48+
## System Identification and Module Loading
8749

88-
The `-m` flag selects mode: `g`/`gpu` for GPU builds, `c`/`cpu` for CPU-only.
89-
Batch job templates for `./mfc.sh run -e batch -c <system>` are in `toolchain/templates/`.
50+
On an HPC cluster, load modules before building: `source ./mfc.sh load -c <slug> -m <mode>`
51+
(`-m g`/`gpu` or `c`/`cpu`). The `source` is required — plain `./mfc.sh load` errors, since
52+
the command sets environment variables in the current shell.
9053

91-
IMPORTANT: `source` (or `.`) is required for `load` — it sets environment variables
92-
in the current shell. Using `./mfc.sh load` without `source` will error.
54+
Slugs live in `toolchain/modules` (e.g. `p` Phoenix, `f` Frontier, `tuo` Tuolumne, `d` Delta,
55+
`b` Bridges2, `c`/`cc` Carpenter GNU/Cray, `o` Oscar, `h` HiPerGator; GPU backend per system
56+
is defined there). To identify the current system, check `$LMOD_SYSHOST` (most reliable),
57+
then a non-empty `$CRAY_LD_LIBRARY_PATH` (→ Cray: Frontier / Carpenter-Cray), then `hostname`
58+
— login and compute nodes may differ. Batch templates for `./mfc.sh run -e batch -c <system>`
59+
are in `toolchain/templates/`.
9360

9461
## Development Workflow Contract
9562

@@ -99,7 +66,7 @@ IMPORTANT: Follow this loop for ALL code changes. Do not skip steps.
9966
2. **Plan** — For multi-file changes, outline your approach before implementing.
10067
3. **Implement** — Make small, focused changes. One logical change per commit.
10168
4. **Format** — Run `./mfc.sh format -j 8` to auto-format.
102-
5. **Verify** — Run `./mfc.sh precheck -j 8` (same 6 checks as CI lint gate).
69+
5. **Verify** — Run `./mfc.sh precheck -j 8` (same checks as the CI lint gate).
10370
6. **Build** — Run `./mfc.sh build -j 8` to verify compilation.
10471
7. **Test** — Run relevant tests: `./mfc.sh test --only <feature> -j 8`.
10572
For changes to `src/common/`, test ALL three targets: `./mfc.sh test -j 8`.
@@ -119,11 +86,11 @@ src/
11986
simulation/ # CFD solver (GPU-accelerated via OpenACC / OpenMP target offload)
12087
post_process/ # Data output and visualization
12188
toolchain/ # Python CLI, build system, testing, parameter management
122-
mfc/params/definitions.py # ~3,400 parameter definitions (source of truth)
89+
mfc/params/definitions.py # parameter definitions (source of truth)
12390
mfc/case_validator.py # Physics constraint validation
12491
mfc/test/ # Test runner and case generation
12592
examples/ # Example simulation cases (case.py files)
126-
tests/ # 560+ regression test golden files
93+
tests/ # regression test golden files
12794
```
12895

12996
Source files are `.fpp` (Fortran + Fypp macros), preprocessed to `.f90` by CMake.
@@ -137,6 +104,7 @@ NEVER use double-precision intrinsics: `dsqrt`, `dexp`, `dlog`, `dble`, `dabs`,
137104
NEVER use `d` exponent literals (`1.0d0`). Use `1.0_wp` instead.
138105
NEVER use `stop` or `error stop`. Use `call s_mpi_abort()` or `@:PROHIBIT()`/`@:ASSERT()`.
139106
NEVER use `goto`, `COMMON` blocks, or global `save` variables.
107+
(Headline subset; full lint-enforced list — incl. Python/shell rules — in `.claude/rules/fortran-conventions.md`.)
140108

141109
Every `@:ALLOCATE(...)` MUST have a matching `@:DEALLOCATE(...)`.
142110
Every new parameter MUST be added in at least 2 places (3 if it has constraints):
@@ -153,13 +121,14 @@ Changes to `src/common/` affect ALL three executables. Test comprehensively.
153121
- Modules: `m_<feature>` (e.g., `m_bubbles`)
154122
- Public subroutines: `s_<verb>_<noun>` (e.g., `s_compute_pressure`)
155123
- Public functions: `f_<verb>_<noun>`
124+
- Private/local variables: no prefix required. Constants: descriptive names, not ALL_CAPS.
156125
- 2-space indentation, lowercase keywords, explicit `intent` on all arguments
157126

158127
## Precision System
159128

160129
- `wp` = working precision (computation). `stp` = storage precision (field data arrays and I/O).
161-
- Default: both double. Single mode: both single. Mixed: wp=double, stp=half.
162-
- MPI types must match: `mpi_p``wp`, `mpi_io_p``stp`.
130+
- Both double by default. See `.claude/rules/fortran-conventions.md` for single/mixed
131+
modes, casting rules, and MPI type matching (`mpi_p``wp`, `mpi_io_p``stp`).
163132

164133
## Code Review Priorities
165134

0 commit comments

Comments
 (0)