From d90e762069b769cf662ca2883b41c32ecbead4c6 Mon Sep 17 00:00:00 2001 From: George Date: Tue, 11 Aug 2026 19:18:53 -0700 Subject: [PATCH 1/2] fix: remove integer(wp) and d-literal convention violations in src --- src/simulation/m_bubbles_EE.fpp | 2 +- src/simulation/m_bubbles_EL.fpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/simulation/m_bubbles_EE.fpp b/src/simulation/m_bubbles_EE.fpp index 9e3f2f29e..bb7eddc6c 100644 --- a/src/simulation/m_bubbles_EE.fpp +++ b/src/simulation/m_bubbles_EE.fpp @@ -70,7 +70,7 @@ contains type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf real(wp) :: nR3bar - integer(wp) :: i, j, k, l + integer :: i, j, k, l $:GPU_PARALLEL_LOOP(private='[i, j, k, l, nR3bar]', collapse=3) do l = 0, p diff --git a/src/simulation/m_bubbles_EL.fpp b/src/simulation/m_bubbles_EL.fpp index a7057867b..93f7a1a88 100644 --- a/src/simulation/m_bubbles_EL.fpp +++ b/src/simulation/m_bubbles_EL.fpp @@ -1796,7 +1796,7 @@ contains do i = 0, m lag_void_max = max(lag_void_max, 1._wp - q_beta(1)%sf(i, j, k)) call s_get_char_vol(i, j, k, volcell) - if ((1._wp - q_beta(1)%sf(i, j, k)) > 5.0d-11) then + if ((1._wp - q_beta(1)%sf(i, j, k)) > 5.0e-11_wp) then lag_void_avg = lag_void_avg + (1._wp - q_beta(1)%sf(i, j, k))*volcell lag_vol = lag_vol + volcell end if From 62a16ff2f3873947e5626a950b5eb5289eb33d6c Mon Sep 17 00:00:00 2001 From: George Date: Tue, 11 Aug 2026 19:19:39 -0700 Subject: [PATCH 2/2] toolchain: extend lint_source.py for integer(wp) and signed d-literals --- toolchain/mfc/lint_source.py | 33 +++++++++++++++++++- toolchain/mfc/test_lint_source.py | 51 ++++++++++++++++++++++++++++--- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/toolchain/mfc/lint_source.py b/toolchain/mfc/lint_source.py index 535119207..0f28f234a 100644 --- a/toolchain/mfc/lint_source.py +++ b/toolchain/mfc/lint_source.py @@ -187,8 +187,14 @@ def check_double_precision(repo_root: Path) -> list[str]: """ errors: list[str] = [] src_dir = repo_root / SRC_DIR + # The d-literal alternative catches double-precision literals with signed or + # multi-digit exponents (e.g. 5.0d-11, 2.5d+3, 1.0d12), not just '[0-9]d0'. + # The identifier boundaries keep it from matching inside names like cart2d12_coords. precision_re = re.compile( - r"\b(?:double_precision|double\s+precision|dsqrt|dexp|dlog|dble|dabs|" r"dprod|dmin|dmax|dfloat|dreal|dcos|dsin|dtan|dsign|dtanh|dsinh|dcosh)\b|" r"\breal\s*\(\s*[48]\s*\)|" r"[0-9]d0", + r"\b(?:double_precision|double\s+precision|dsqrt|dexp|dlog|dble|dabs|" + r"dprod|dmin|dmax|dfloat|dreal|dcos|dsin|dtan|dsign|dtanh|dsinh|dcosh)\b|" + r"\breal\s*\(\s*[48]\s*\)|" + r"(? list[str]: return errors +def check_integer_wp(repo_root: Path) -> list[str]: + """Flag ``integer(wp)`` declarations. + + ``wp`` is a floating-point kind parameter; using it as an integer kind is a + copy-paste error. Integers take the default kind: plain ``integer``. + """ + errors: list[str] = [] + src_dir = repo_root / SRC_DIR + integer_wp_re = re.compile(r"\binteger\s*\(\s*wp\s*\)", re.IGNORECASE) + + for src in _fortran_fpp_files(src_dir): + lines = src.read_text(encoding="utf-8").splitlines() + rel = src.relative_to(repo_root) + + for i, line in enumerate(lines): + stripped = line.strip() + if _is_comment_or_blank(stripped): + continue + if integer_wp_re.search(stripped.split("!")[0]): + errors.append(f" {rel}:{i + 1} 'integer(wp)' uses a floating-point kind. Fix: use plain 'integer'") + + return errors + + def check_junk_comments(repo_root: Path) -> list[str]: """Flag junk separator patterns (===, ----+) in Python and shell scripts. @@ -445,6 +475,7 @@ def main(): all_errors.extend(check_double_precision(repo_root)) all_errors.extend(check_junk_code(repo_root)) all_errors.extend(check_false_integers(repo_root)) + all_errors.extend(check_integer_wp(repo_root)) all_errors.extend(check_junk_comments(repo_root)) all_errors.extend(check_fypp_list_duplicates(repo_root)) all_errors.extend(check_duplicate_lines(repo_root)) diff --git a/toolchain/mfc/test_lint_source.py b/toolchain/mfc/test_lint_source.py index 6c788543f..6adb63e1d 100644 --- a/toolchain/mfc/test_lint_source.py +++ b/toolchain/mfc/test_lint_source.py @@ -1,6 +1,11 @@ """Tests for the manual registry-bound broadcast lint in lint_source.py.""" -from mfc.lint_source import _extract_bcast_roots, check_manual_registry_bcasts +from mfc.lint_source import ( + _extract_bcast_roots, + check_double_precision, + check_integer_wp, + check_manual_registry_bcasts, +) BCAST_TAIL = ", 1, mpi_p, 0, MPI_COMM_WORLD, ierr)" @@ -43,10 +48,48 @@ def test_struct_members_and_loop_indices_skipped(): assert _extract_bcast_roots(lines) == [] +def _write_src(tmp_path, rel: str, body: str): + """Write a source file under tmp_path/src/ for a lint check to scan.""" + path = tmp_path / "src" / rel + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(body, encoding="utf-8") + + def _write_proxy(tmp_path, target_dir: str, body: str): - proxy_dir = tmp_path / "src" / target_dir - proxy_dir.mkdir(parents=True) - (proxy_dir / "m_mpi_proxy.fpp").write_text(body, encoding="utf-8") + _write_src(tmp_path, f"{target_dir}/m_mpi_proxy.fpp", body) + + +def test_double_precision_flags_signed_d_exponent(tmp_path): + _write_src(tmp_path, "simulation/m_x.fpp", " if (x > 5.0d-11) then\n") + errors = check_double_precision(tmp_path) + assert len(errors) == 1 + assert "5.0d-11" in errors[0] + + +def test_double_precision_clean_cases(tmp_path): + body = "\n".join( + [ + " integer, dimension(2) :: cart2d12_coords, cart2d13_coords", # identifier, not a literal + " call MPI_CART_COORDS(comm, rank, 2, cart2d12_coords, ierr)", + " x = 5.0e-11_wp", # correct working-precision literal + "", + ] + ) + _write_src(tmp_path, "simulation/m_y.fpp", body) + assert check_double_precision(tmp_path) == [] + + +def test_integer_wp_flagged(tmp_path): + _write_src(tmp_path, "simulation/m_z.fpp", " integer(wp) :: i, j, k, l\n") + errors = check_integer_wp(tmp_path) + assert len(errors) == 1 + assert "integer(wp)" in errors[0] + + +def test_integer_wp_clean(tmp_path): + body = " integer :: i\n real(wp) :: x\n" + _write_src(tmp_path, "simulation/m_ok.fpp", body) + assert check_integer_wp(tmp_path) == [] def test_manual_broadcast_of_registry_scalar_is_flagged(tmp_path):