---
description: CUDA/C++ naming — macros, kernels, device helpers, module growth
globs: src/**/*.cu,src/**/*.cuh,src/**/*.h
---

# CUDA and GPU-side naming (CelerisLab)

## File banner and guards

- First line of each hand-written `.cu` / `.cuh`: `// CelerisLab – <path_under_lbm/kernels/>` (en-dash `–`), matching siblings (e.g. `operators/collision_srt.cuh`, `step/one_step_double.cu`).
- Include guards: `CELERIS_<PATH_UPPER>_<STEM>_CUH` (match existing pattern, e.g. `CELERIS_OPERATORS_COLLISION_SRT_CUH`).
- Auto-generated headers under `lbm/kernels/config/` must start with:
  `// AUTO-GENERATED by CelerisLab compiler – DO NOT EDIT MANUALLY`

## Module domains (plan for growth)

Keep names readable across domains. Today most GPU code lives under `lbm/kernels/`; future areas may add parallel trees (e.g. particles, deformable solids). Use consistent **semantic** prefixes in identifiers when ambiguity is likely:

| Domain | Scope (conceptual) | Identifier hint |
|--------|-------------------|-----------------|
| Orchestration | Host-side launch, thin wrappers | Already mostly Python; CUDA entry files stay thin |
| Common | Shared numerics / helpers used by multiple domains | Prefer neutral names (`clamp01`, `dot3`) or `cel_*` only if truly project-global |
| LBM | Lattice, collision, streaming, macroscopic | `collide_*`, `stream_*`, `macro_*`, step drivers `one_step_*` — keep physics meaning in the name |
| Body / IBM | Immersed boundaries, rigid surfaces | `ibm_*`, `curved_*`, `cut_link_*` style names where they describe physics |
| Future: flexible solids | Not present yet | Reserve `flex_*` or a dedicated subdirectory prefix when added |
| Future: particles | Not present yet | Reserve `part_*` or `particle_*` under a dedicated subtree when added |

Do not rename working kernels for style alone in a mixed PR with behavior changes; batch renames in a dedicated change after audit.

## Config macros (`config_*.h`)

- Macros are compile-time switches and constants. Prefer **layer + clear token**:

  - **Grid**: `NX`, `NY`, `NZ`, `DIM`, `NQ`, … (existing tier “Global/Grid”).
  - **Physics**: `VIS`, `RHO`, `U0`, … (existing).
  - **Method**: group by sub-area where possible — collision (`COLLISION_MODEL`, …), streaming (`STREAMING_MODEL`, …), LES (`USE_LES` / future `LES_*`), inlet/outlet (`INLET_*`, `OUTLET_*`), stability guards (`OMEGA_COLLISION_*`, `TRT_MAGIC_PARAM`, …).
  - **Objects / case**: `N_OBJS`, …

- When **adding** macros, pick names that won’t collide across layers and that encode the tier (document in `configs/CONFIG.md` and in compiler mapping).
- Full normalization of legacy macro names is a **separate refactor** (compiler + all `#ifdef` / macro uses).

## Device functions and kernels

- Device helpers: `__device__ __forceinline__`; prefer small verbs (`compute_feq`, `apply_bc_wall`).
- Pointer parameters that are not aliased: use `__restrict__` where appropriate.
- Kernel entry points (`__global__`): name should state **what step** and **which path** (e.g. `step_lbm_double_buffer`), not only `kernel_launch`.

## Flags and constants

- Cell flags live in `core/flags.cuh`: keep `FLAG_*`, `MASK_*`, and helpers (`is_fluid`, …). Do not change bit layout without a versioned migration plan.
- Python flag constants in `lbm/descriptors.py` must stay consistent with GPU flags; any change updates both sides and user docs.

## Section comments

- File-level title: `// ==== Title ====` or equivalent single banner.
- Subsections: `// --- Section ---` or aligned `// -----` blocks — pick one style **within a file** and match neighbors.
