Skip to content

Lint rules for empirically-confirmed invariants: GPU declare scoping, fypp determinism, allocate pairing #1576

Description

@sbryngelson

Motivation

Three invariants were each violated on master and found the hard way during the 2026-06 series; all three are statically checkable in toolchain/mfc/lint_source.py (already CI-gated via precheck):

  1. GPU_DECLARE must live in the module that declares its variables. Violations compile fine on NVHPC and fail only on Cray ftn (ftn-1448) — i.e. the feedback loop runs through Frontier CI, weeks after the commit. This bit the executable-dedup work (fixed in Share the global-parameters core across executables; generate MPI broadcasts; build hygiene #1552) and the rule currently exists only as documentation.
  2. No fypp set-literal loops (#:for x in {...}). Python set iteration order is hash-randomized per process, so emitted code differs between builds — harmless for the constant-assignment sites converted in Phase-2 completion: post-process context types, m_riemann_solvers split, cleanup #1556, but it silently defeats build reproducibility and makes emitted-code diffing (a verification technique the series relied on heavily) noisy. The existing sites are fixed; nothing stops new ones.
  3. @:ALLOCATE / @:DEALLOCATE pairing per module. The project rule exists in CLAUDE.md/contributing; Gs_rs and Res_gs are @:ALLOCATE'd but never deallocated in the Riemann finalizer #1568 (Gs_rs/Res_gs, leaked since 2022) and Single-precision output arrays (q_sf_s family) are never deallocated in post_process #1569 (the single-precision q_sf_s triple, since 2023) show it is not enforced. A per-module name-set comparison (allocated minus deallocated, with an allowlist for intentional cases) would have flagged both years ago.

Proposal & execution sketch

Three independent rules in lint_source.py, each with the same shape: parse, check, report file:line with a named rule.

Effort: small (an afternoon each). Risk: minimal — lint-only. Impact: four recurring bug classes become unrecurrable at commit time instead of at Frontier-CI time or never.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions