|
| 1 | +###################################################################### |
| 2 | +# .cursorrules – project-level instructions for Cursor AI # |
| 3 | +# Target repo: github.com/mflowcode/mfc # |
| 4 | +# Format: plain-text "rules for the Agent". One idea per line. # |
| 5 | +###################################################################### |
| 6 | + |
| 7 | +### ─────────────────────────────────────────────────────────────────── |
| 8 | +### 1. Global project context (ALWAYS applied) |
| 9 | +### ─────────────────────────────────────────────────────────────────── |
| 10 | + |
| 11 | +- You are interacting with **MFC** – an exascale, many-physics, multi-component |
| 12 | + flow solver written in modern Fortran and generated with the Fypp |
| 13 | + pre-processor. Most source files use the `.fpp` extension (Fypp templates) |
| 14 | + and are transpiled to `.f90` during the CMake build. A minority of modules |
| 15 | + remain as plain `.f90`. The code lives in `src/`, tests in `tests/`, |
| 16 | + and example input cases in `examples/`. |
| 17 | + |
| 18 | +- Fypp helper macros live in files under any `include/` directory within |
| 19 | + `src/` (e.g., `src/<module>/include/`). **Scan these macro files first** so |
| 20 | + that template expansions resolve correctly. |
| 21 | + |
| 22 | +- Always assume free-form Fortran 2008+ (`.fpp` and `.f90`) with `implicit none`, |
| 23 | + explicit `intent(in|out|inout)`, and modern constructs (`allocate`, |
| 24 | + `move_alloc`, `iso_fortran_env`, etc.). |
| 25 | + |
| 26 | +- Prefer `module` + `contains` → `subroutine foo()` patterns; avoid COMMON |
| 27 | + blocks and `include` files. |
| 28 | + |
| 29 | +- **Simulation kernels are accelerated exclusively with OpenACC.** Always |
| 30 | + include the appropriate `!$acc` pragmas when generating or modifying |
| 31 | + performance-critical loops. |
| 32 | + |
| 33 | +- **The codebase is written in Fortran 2008+ with the Fypp pre-processor.** |
| 34 | + Always use the appropriate Fypp macros when generating or modifying |
| 35 | + performance-critical loops. |
| 36 | + |
| 37 | +- **Before suggesting or applying any source-code changes, first read/parse the |
| 38 | + full codebase *and* the documentation sources listed below, then produce a |
| 39 | + concise description of how the codebase is structured and functions.** |
| 40 | + |
| 41 | +- Documentation sources: |
| 42 | + - Primary online docs: <https://mflowcode.github.io/documentation/md_readme.html> |
| 43 | + - Root-level `README.md` in the repository. |
| 44 | + |
| 45 | +### ─────────────────────────────────────────────────────────────────── |
| 46 | +### 2. Style & naming conventions (AUTO-ATTACH for *.fpp and *.f90 files) |
| 47 | +### ─────────────────────────────────────────────────────────────────── |
| 48 | + |
| 49 | +- Indent 2 spaces; continuation lines line up under “&”. |
| 50 | +- No maximum line length is enforced. |
| 51 | +- Prefer shorter, streamlined code—avoid needless verbosity while keeping clarity. |
| 52 | +- Lower-case keywords (`do`, `end subroutine`, etc.). |
| 53 | +- Module names: `m_<feature>` (e.g., `m_transport`). |
| 54 | +- Public procedures: `<verb>_<noun>` (e.g., `compute_flux`) with prefixe `s_` or `f_` for subroutines and functions, respectively. |
| 55 | +- Avoid private helper functions within a subroutine or function, and instead make them private to the module (if appropriate) |
| 56 | +- Helper functions or subroutines start with with f_[name here] or s_[name here], respectively |
| 57 | +- Avoid passing arguments to subroutines and functions that need to be reshaped in the subroutine or function, such that the compiler can optimize the code. |
| 58 | +- Avoid common Fortran code smells, such as: |
| 59 | + - Use of `goto` statements (except in legacy interop situations). |
| 60 | + - Omission of `intent(...)` declarations. |
| 61 | + - Use of global state via `COMMON` blocks or `save` variables. |
| 62 | + - Shadowing of variable names (especially loop indices). |
| 63 | + - Non-descriptive or single-letter variable names outside small scopes. |
| 64 | + - Excessively long helper procedures (>200 lines); prefer decomposition. |
| 65 | + - Excessively long subroutines (>500 lines); prefer decomposition. |
| 66 | + - Excessively long functions (>100 lines); prefer decomposition. |
| 67 | + - Excessively long modules (>1000 lines); prefer decomposition. |
| 68 | + - Excessively long files (>1000 lines); prefer decomposition. |
| 69 | + - Subroutines and functions that are too long to be understood at a glance. |
| 70 | + - Use of `!$acc routine seq` to mark subroutines and functions that are called from OpenACC parallel loops. |
| 71 | + - Mixing I/O logic with computation (separate concerns). |
| 72 | + - Missing implicit none statements. |
| 73 | + - Missing `intent(in|out|inout)` declarations. |
| 74 | + - Missing `dimension` or `allocatable`/`pointer` attributes. |
| 75 | + - Missing `private` declarations. |
| 76 | + - Missing `public` declarations. |
| 77 | + - Missing `module procedure` declarations. |
| 78 | + - Missing `use` statements. |
| 79 | + - Declaring arrays without `dimension` or `allocatable`/`pointer` attributes. |
| 80 | + - Use of `stop` for error handling (prefer use of the subroutine `s_mpi_abort` with an appropriate string message argument). |
| 81 | + |
| 82 | +### ─────────────────────────────────────────────────────────────────── |
| 83 | +### 3. Test workflow (AUTOMATICALLY applied when the code is significantly changed and should be tested) |
| 84 | +### ─────────────────────────────────────────────────────────────────── |
| 85 | + |
| 86 | +- Run the test suite after any meaningful code change to verify correctness. |
| 87 | +- Ask the user to alter the test suite command so that only the relevant tests are run. |
| 88 | +- When you think you are done with the code changes, run ./mfc.sh test -j $(nproc) -f EA8FA07E -t 9E2CA336 |
| 89 | +- Otherwise, only run specific tests that are relevant to the code changes. |
| 90 | +- Do not run ./mfc.sh test -j $(nproc) without any other arguments (it takes too long to run all tests). |
| 91 | + |
| 92 | +### ─────────────────────────────────────────────────────────────────── |
| 93 | +### 4. OpenACC programming guidelines (AUTOMATICALLY applied to *.fpp/*.f90) |
| 94 | +### ─────────────────────────────────────────────────────────────────── |
| 95 | + |
| 96 | +- **Prefer:** |
| 97 | + |
| 98 | + !$acc parallel loop gang vector default(present) |
| 99 | + |
| 100 | + around tight loops over cells or particles; fall back to `!$acc kernels` |
| 101 | + only when loop dependencies prevent direct parallelization. Always add |
| 102 | + `reduction` clauses where needed. |
| 103 | + |
| 104 | +- Use `collapse(n)` in `!$acc parallel loop` pragmas to combine nested loops |
| 105 | + when it improves parallelism and the iterations are independent. |
| 106 | + |
| 107 | +- Use `private(var1, var2, ...)` clauses for all variables that are local |
| 108 | + to a parallel region or loop, especially scalar temporaries and loop counters. |
| 109 | + |
| 110 | +- Use `!$acc routine seq` to mark subroutines and functions that are called from OpenACC parallel loops. |
| 111 | + |
| 112 | +- When adding `!$acc routine seq` put it on the first line after the declaration of the subroutine or function. |
| 113 | + |
| 114 | +- Allocate large arrays with the `managed` attribute or move them to the device |
| 115 | + at program start using a persistent `!$acc enter data` region. |
| 116 | + |
| 117 | +- Do **not** place `stop` or `error stop` statements inside OpenACC parallel regions or loops, as they are unsupported in device code and will cause runtime failures. |
| 118 | + |
| 119 | +- Ensure the code compiles with Cray Fortran (`ftn`) and NVIDIA HPC SDK |
| 120 | + (`nvfortran`) for OpenACC GPU offloading, and with GNU (`gfortran`) and Intel |
| 121 | + (`ifx`/`ifort`) for CPU-only builds where OpenACC directives are ignored. |
| 122 | + |
| 123 | +###################################################################### |
| 124 | +# End of file |
| 125 | +###################################################################### |
0 commit comments