Skip to content

Commit e4d00c0

Browse files
authored
update cursor rules. (#955)
1 parent 3b6fe6e commit e4d00c0

File tree

1 file changed

+122
-28
lines changed

1 file changed

+122
-28
lines changed

.cursor/rules/mfc-agent-rules.mdc

Lines changed: 122 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,30 @@
1-
---
2-
description: Full MFC project rules – consolidated for Agent Mode
3-
alwaysApply: true
4-
---
1+
----
2+
-description: Full MFC project rules – consolidated for Agent Mode
3+
-alwaysApply: true
4+
----
55

66
# 0 Purpose & Scope
7-
Consolidated guidance for the MFC exascale, many-physics solver.
8-
Written primarily for Fortran/Fypp; the OpenACC and style sections matter only when
9-
`.fpp` / `.f90` files are in view.
7+
Consolidated guidance for the MFC exascale, many-physics solver.
8+
Written primarily for Fortran/Fypp; the GPU and style sections matter only when `.fpp` / `.f90` files are in view.
109

1110
---
1211

1312
# 1 Global Project Context (always)
14-
- **Project**: *MFC* is modern Fortran 2008+ generated with **Fypp**.
15-
- Sources `src/`, tests `tests/`, examples `examples/`.
16-
- Most sources are `.fpp`; CMake transpiles them to `.f90`.
17-
- **Fypp macros** live in `src/<subprogram>/include/` you should scan these first.
18-
`<subprogram>` ∈ {`simulation`,`common`,`pre_process`,`post_process`}.
19-
- Only `simulation` (+ its `common` calls) is GPU-accelerated via **OpenACC** or **OpenMP**.
20-
- Assume free-form Fortran 2008+, `implicit none`, explicit `intent`, and modern
21-
intrinsics.
22-
- Prefer `module … contains … subroutine foo()`; avoid `COMMON` blocks and
23-
file-level `include` files.
24-
- **Read the full codebase and docs *before* changing code.**
25-
Docs: <https://mflowcode.github.io/documentation/md_readme.html> and the respository root `README.md`.
13+
- **Project**: *MFC* is modern Fortran 2008+ generated with **Fypp**.
14+
- Sources `src/`, tests `tests/`, examples `examples/`.
15+
- Most sources are `.fpp`; CMake transpiles them to `.f90`.
16+
- **Fypp macros** live in `src/<subprogram>/include/` you should scan these first.
17+
`<subprogram>` ∈ {`simulation`,`common`,`pre_process`,`post_process`}.
18+
- Only `simulation` (+ its `common` calls) is GPU-accelerated via **OpenACC** or **OpenMP**.
19+
- Assume free-form Fortran 2008+, `implicit none`, explicit `intent`, and modern intrinsics.
20+
- Prefer `module … contains … subroutine foo()`; avoid `COMMON` blocks and file-level `include` files.
21+
- **Read the full codebase and docs *before* changing code.**
22+
- Docs: <https://mflowcode.github.io/documentation/md_readme.html> and the respository root `README.md`.
2623

2724
### Incremental-change workflow
28-
1. Draft a step-by-step plan.
29-
2. After each step, build:
25+
26+
1. Draft a step-by-step plan.
27+
2. After each step, build:
3028
```bash
3129
./mfc.sh build -t pre_process simulation -j $(nproc)
3230
```
@@ -49,12 +47,10 @@ Written primarily for Fortran/Fypp; the OpenACC and style sections matter only w
4947
* Subroutine → `s_<verb>_<noun>` (e.g. `s_compute_flux`)
5048
* Function → `f_<verb>_<noun>`
5149
* Private helpers stay in the module; avoid nested procedures.
52-
* **Size limits**: subroutine ≤ 500 lines, helper ≤ 150, function ≤ 100,
53-
module/file ≤ 1000.
54-
* ≤ 6 arguments per routine; otherwise pass a derived-type “params” struct.
50+
* **Size limits**: subroutine ≤ 500 lines, helper ≤ 150, function ≤ 100, module/file ≤ 1000.
51+
* ≤ 6 arguments per routine; otherwise pass a derived-type "params" struct.
5552
* No `goto` (except unavoidable legacy); no global state (`COMMON`, `save`).
56-
* Every variable: `intent(in|out|inout)` + appropriate `dimension` / `allocatable`
57-
/ `pointer`.
53+
* Every variable: `intent(in|out|inout)` + appropriate `dimension` / `allocatable` / `pointer`.
5854
* Use `s_mpi_abort(<msg>)` for errors, not `stop`.
5955
* Mark GPU-callable helpers that are called from GPU parallel loops immediately after declaration:
6056
```fortran
@@ -66,9 +62,10 @@ Written primarily for Fortran/Fypp; the OpenACC and style sections matter only w
6662

6763
---
6864

69-
# 3 FYPP Macros for GPU acceleration Pogramming Guidelines (for kernels)
65+
# 3 FYPP Macros for GPU acceleration Pogramming Guidelines (for GPU kernels)
7066

71-
Do not directly use OpenACC or OpenMP directives directly. Instead, use the FYPP macros contained in src/common/include/parallel_macros.fpp
67+
Do not directly use OpenACC or OpenMP directives directly.
68+
Instead, use the FYPP macros contained in src/common/include/parallel_macros.fpp
7269

7370
Wrap tight loops with
7471

@@ -82,3 +79,100 @@ $:GPU_PARALLEL_FOR(private='[...]', copy='[...]')
8279
* **Do not** place `stop` / `error stop` inside device code.
8380
* Must compile with Cray `ftn` and NVIDIA `nvfortran` for GPU offloading; also build CPU-only with
8481
GNU `gfortran` and Intel `ifx`/`ifort`.
82+
83+
---
84+
85+
# 4 File & Module Structure
86+
87+
- **File Naming**:
88+
- `.fpp` files: Fypp preprocessed files that get translated to `.f90`
89+
- Modules are named with `m_` prefix followed by feature name: `m_helper_basic`, `m_viscous`
90+
- Primary program file is named `p_main.fpp`
91+
92+
- **Module Layout**:
93+
- Start with Fypp include for macros: `#:include 'macros.fpp'`
94+
- Header comments using `!>` style documentation
95+
- `module` declaration with name matching filename
96+
- `use` statements for dependencies
97+
- `implicit none` statement
98+
- `private` declaration followed by explicit `public` exports
99+
- `contains` section
100+
- Implementation of subroutines and functions
101+
102+
# 5 Fypp Macros and GPU Acceleration
103+
104+
## Use of Fypp
105+
- **Fypp Directives**:
106+
- Start with `#:` (e.g., `#:include`, `#:def`, `#:enddef`)
107+
- Macros defined in `include/*.fpp` files
108+
- Used for code generation, conditional compilation, and GPU offloading
109+
110+
## Some examples
111+
112+
Documentation on how to use the Fypp macros for GPU offloading is available at https://mflowcode.github.io/documentation/md_gpuParallelization.html
113+
114+
Some examples include:
115+
- `$:GPU_ROUTINE(parallelism='[seq]')` - Marks GPU-callable routines
116+
- `$:GPU_PARALLEL_LOOP(collapse=N)` - Parallelizes loops
117+
- `$:GPU_LOOP(parallelism='[seq]')` - Marks sequential loops
118+
- `$:GPU_UPDATE(device='[var1,var2]')` - Updates device data
119+
- `$:GPU_ENTER_DATA(copyin='[var]')` - Copies data to device
120+
- `$:GPU_EXIT_DATA(delete='[var]')` - Removes data from device
121+
122+
# 6 Documentation Style
123+
124+
- **Subroutine/Function Documentation**:
125+
```fortran
126+
!> This procedure <description>
127+
!! @param param_name Description of the parameter
128+
!! @return Description of the return value (for functions)
129+
```
130+
which conforms to the Doxygen Fortran format.
131+
132+
# 7 Error Handling
133+
134+
- **Assertions**:
135+
- Use the fypp `ASSERT` macro for validating conditions
136+
- Example: `@:ASSERT(predicate, message)`
137+
138+
- **Error Reporting**:
139+
- Use `s_mpi_abort(<msg>)` for error termination, not `stop`
140+
- No `stop` / `error stop` inside device code
141+
142+
# 8 Memory Management
143+
144+
- **Allocation/Deallocation**:
145+
- Use fypp macro `@:ALLOCATE(var1, var2)` macro for device-aware allocation
146+
- Use fypp macro `@:DEALLOCATE(var1, var2)` macro for device-aware deallocation
147+
148+
# 9. Additional Observed Patterns
149+
150+
- **Derived Types**:
151+
- Extensive use of derived types for encapsulation
152+
- Use pointers within derived types (e.g., `pointer, dimension(:,:,:) => null()`)
153+
- Clear documentation of derived type components
154+
155+
- **Pure & Elemental Functions**:
156+
- Use `pure` and `elemental` attributes for side-effect-free functions
157+
- Combine them for operations on arrays (`pure elemental function`)
158+
159+
- **Precision Handling**:
160+
- Use `wp` (working precision) parameter from `m_precision_select`
161+
- Never hardcode precision with `real*8` or similar
162+
163+
- **Loop Optimization**:
164+
- Favor array operations over explicit loops when possible
165+
- Use `collapse=N` directive to optimize nested loops
166+
167+
# 10. Fortran Practices to Avoid
168+
169+
- **Fixed Format**: Only free-form Fortran is used
170+
- No column-position dependent code
171+
172+
- **Older Intrinsics**: Avoid outdated Fortran features like:
173+
- `equivalence` statements
174+
- `data` statements (use initialization expressions)
175+
- Character*N (use `character(len=N)` instead)
176+
177+
- **Using same variable for multiple purposes**: Maintain single responsibility
178+
- Each variable should have one clear purpose

0 commit comments

Comments
 (0)