Skip to content

Speed up gfortran debug CI builds#1339

Merged
sbryngelson merged 9 commits intoMFlowCode:masterfrom
sbryngelson:fast-debug
Mar 31, 2026
Merged

Speed up gfortran debug CI builds#1339
sbryngelson merged 9 commits intoMFlowCode:masterfrom
sbryngelson:fast-debug

Conversation

@sbryngelson
Copy link
Copy Markdown
Member

@sbryngelson sbryngelson commented Mar 31, 2026

Summary

  • Add RelDebug build type — a lightweight debug mode for CI that sits between full Debug and Release
  • --debug remains unchanged (full runtime checks for local development)
  • --reldebug is the new CI flag: -Og/-O1, bounds-only checking, debug symbols
  • Remove -fcheck=bounds from the unconditional GCC>=10 block so Release builds no longer pay for runtime bounds checking

RelDebug flags per compiler

Compiler Full Debug (--debug) RelDebug (--reldebug)
gfortran -O0 -fcheck=all,no-array-temps -fbacktrace -fsignaling-nans ... -Og -fcheck=bounds -fbacktrace -fsignaling-nans
Intel ifx -Og -traceback -debug -check all -Og -traceback -check bounds
NVHPC -O0 -C -Mbounds -traceback -Minform=inform -O1 -Mbounds -traceback
Cray ftn -O0 -K trap=fp -O1

Baseline (gfortran on ubuntu-latest)

  • Debug (20% of tests): 137 min → ~5.2x slower per test than Release
  • Release (100% of tests): 131 min (had -fcheck=bounds always on!)

Test plan

  • Compare CI wall-clock times for Github (ubuntu, mpi, reldebug, false) against prior debug baseline
  • Compare Github (ubuntu, mpi, no-debug, false) against prior baseline (should also be faster with -fcheck=bounds removed from Release)
  • Verify no test regressions across all matrix combinations

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 31, 2026

Claude Code Review

Incremental review from: c0249a2
Head SHA: e65d1b5

New findings since last Claude review:

  • toolchain/main.py lines 214–222 — logic gap when both flags are already persisted: The disambiguation heuristic only checks state.gCFG.reldebug but never checks state.gCFG.debug. When both reldebug and debug were already persisted in a prior run's config (i.e., state.gCFG.reldebug == True and state.gCFG.debug == True), the condition if not state.gCFG.reldebug: is False so the else branch fires and clears reldebug — even though the user passed neither flag explicitly on this invocation. The fix is to also guard the else with elif not state.gCFG.debug: and add a final else that handles the ambiguous case (both previously persisted) rather than silently picking one.

@sbryngelson sbryngelson marked this pull request as ready for review March 31, 2026 18:18
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

📝 Walkthrough

Walkthrough

This pull request introduces a new RelDebug build type alongside the existing Debug and Release modes. The change adds CMake configuration for the new build type with specific compiler flags for various compilers, updates the GitHub Actions test workflow to use reldebug instead of debug, and modifies the build system toolchain to support the new mode. Documentation is updated to describe the --reldebug / --no-reldebug CLI flags. Additionally, the CLI argument parser and state management are updated to convert snake_case configuration names to hyphenated format (e.g., foo_bar becomes --foo-bar).

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main purpose of the PR: introducing a new lightweight debug build mode (RelDebug) to speed up gfortran debug CI builds, which is the primary objective.
Description check ✅ Passed The PR description is comprehensive and includes a clear summary, compiler-specific flag table, baseline performance data, and test plan checklist, covering all essential information for understanding the changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 784aad79-9f80-497e-b647-c853c0a0666f

📥 Commits

Reviewing files that changed from the base of the PR and between afc724e and 36249ac.

📒 Files selected for processing (8)
  • .github/workflows/test.yml
  • CMakeLists.txt
  • docs/documentation/getting-started.md
  • docs/documentation/troubleshooting.md
  • toolchain/mfc/build.py
  • toolchain/mfc/cli/argparse_gen.py
  • toolchain/mfc/cli/docs_gen.py
  • toolchain/mfc/state.py

Comment on lines +41 to +45
# RelDebug: a lighter debug mode for CI. Compiler-specific blocks below add the
# actual flags; these defaults just tell CMake it is a recognised build type.
set(CMAKE_C_FLAGS_RELDEBUG "-g" CACHE STRING "")
set(CMAKE_CXX_FLAGS_RELDEBUG "-g" CACHE STRING "")
set(CMAKE_Fortran_FLAGS_RELDEBUG "-g" CACHE STRING "")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'RelDebug config plumbing:\n'
rg -n 'RelDebug|RELDEBUG|CMAKE_CONFIGURATION_TYPES|CMAKE_MAP_IMPORTED_CONFIG_RELDEBUG|CMAKE_BUILD_TYPE' CMakeLists.txt toolchain/mfc/build.py

printf '\nWindows / multi-config hints:\n'
rg -n '\.sln|Visual Studio|--config|mfc\.bat' docs .github toolchain

Repository: MFlowCode/MFC

Length of output: 3934


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Checking for CMAKE_CONFIGURATION_TYPES usage ==="
rg -n 'CMAKE_CONFIGURATION_TYPES' CMakeLists.txt toolchain/

echo -e "\n=== Checking for Intel compiler ID variations ==="
rg -n 'IntelLLVM|CMAKE_.*_COMPILER_ID.*Intel|CMAKE_Fortran_COMPILER_ID' CMakeLists.txt

echo -e "\n=== Checking CMake generator selection in build.py ==="
rg -n 'CMAKE_GENERATOR|Visual Studio|Xcode|Ninja|Unix Makefiles' toolchain/mfc/build.py

echo -e "\n=== Full Intel block context (lines ~240-270) ==="
sed -n '230,280p' CMakeLists.txt

Repository: MFlowCode/MFC

Length of output: 109


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Checking for CMAKE_CONFIGURATION_TYPES usage ==="
rg -n 'CMAKE_CONFIGURATION_TYPES' CMakeLists.txt toolchain/ || echo "(not found)"

echo -e "\n=== Checking for Intel compiler ID variations ==="
rg -n 'IntelLLVM|CMAKE_Fortran_COMPILER_ID.*Intel' CMakeLists.txt || echo "(not found)"

echo -e "\n=== Checking CMake generator selection in build.py ==="
rg -n 'CMAKE_GENERATOR|Visual Studio|Xcode|Ninja' toolchain/mfc/build.py || echo "(not found)"

echo -e "\n=== Intel-specific block context (lines 230-280) ==="
sed -n '230,280p' CMakeLists.txt

Repository: MFlowCode/MFC

Length of output: 2591


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Workflow configuration (check for generator hints) ==="
rg -n 'CMAKE_GENERATOR|Visual Studio|Xcode|generator' .github/workflows/

echo -e "\n=== mfc.bat content (Windows build entry point) ==="
head -50 mfc.bat

echo -e "\n=== build.py generator handling ==="
sed -n '350,420p' toolchain/mfc/build.py

Repository: MFlowCode/MFC

Length of output: 115


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Workflow configuration (check for generator hints) ==="
rg -n 'CMAKE_GENERATOR|Visual Studio|Xcode|generator' .github/workflows/ || echo "(not found)"

echo -e "\n=== mfc.bat content (Windows build entry point) ==="
head -60 mfc.bat || echo "(mfc.bat not found or empty)"

echo -e "\n=== build.py CMake invocation (lines 350-420) ==="
sed -n '350,420p' toolchain/mfc/build.py

Repository: MFlowCode/MFC

Length of output: 4991


Verify RelDebug support on multi-config generators and add Intel oneAPI compiler ID.

Multi-config generators (Visual Studio, Xcode) will fail to use the custom RelDebug flags:

  • CMAKE_BUILD_TYPE is empty on multi-config generators, so the if(CMAKE_BUILD_TYPE STREQUAL "RelDebug") conditionals throughout the file will not fire (lines 240, 248, 259, 268, 333, 647)
  • CMAKE_CONFIGURATION_TYPES is never set, so RelDebug is not registered as a valid configuration
  • cmake --build --config RelDebug will use default flags instead of the custom ones, or fail

The code sets CMAKE_BUILD_TYPE (single-config only) but later passes --config (multi-config syntax) to the build command, suggesting both patterns were intended but not properly reconciled.

Additionally, the Intel Fortran block (line 243) only checks for CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" but does not handle IntelLLVM, which is what Intel oneAPI (ifx) reports. If oneAPI is installed, the compiler ID will not match and flags will not be applied.

Suggested fixes:

  1. Add CMAKE_CONFIGURATION_TYPES registration for multi-config generators and use generator expressions instead of CMAKE_BUILD_TYPE conditionals, or
  2. Detect the generator type and apply platform-appropriate logic
  3. Extend the Intel block to also check for IntelLLVM:
elseif ((CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") OR (CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM"))

Comment on lines 236 to +239
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_options(-g -Og -traceback -debug)
add_compile_options(-g -Og -traceback -debug -check all)
elseif (CMAKE_BUILD_TYPE STREQUAL "RelDebug")
add_compile_options(-g -Og -traceback -check bounds)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

For Intel oneAPI ifx, what value does CMake set in CMAKE_Fortran_COMPILER_ID: IntelorIntelLLVM?

💡 Result:

For Intel oneAPI ifx (LLVM-based Fortran compiler), CMake sets:

  • CMAKE_Fortran_COMPILER_ID = IntelLLVM (not Intel). [1], [2]

Sources: CMake Discourse example output showing “Fortran Compiler ID: IntelLLVM” when using ifx [1], and Intel’s oneAPI Fortran 2021 release notes stating ifx is supported with compiler id IntelLLVM (with CMake 3.20 + oneAPI HPC Toolkit 2021.2 on Linux). [2]


🏁 Script executed:

# Find and read the CMakeLists.txt file around lines 236-239 with full context
fd CMakeLists.txt | head -1 | xargs -I {} sh -c 'wc -l {} && echo "---" && head -n 260 {} | tail -n 50'

Repository: MFlowCode/MFC

Length of output: 2069


🏁 Script executed:

fd CMakeLists.txt | head -1 | xargs -I {} sh -c 'grep -n "CMAKE_Fortran_COMPILER_ID\|IntelLLVM\|Intel" {} | head -20'

Repository: MFlowCode/MFC

Length of output: 1532


🏁 Script executed:

fd CMakeLists.txt | head -1 | xargs -I {} sh -c 'sed -n "130,320p" {} | cat -n'

Repository: MFlowCode/MFC

Length of output: 9152


🏁 Script executed:

cd . && git log --oneline -1 2>/dev/null || echo "Not a git repo or git not available"
git diff HEAD -- CMakeLists.txt 2>/dev/null | grep -A 5 -B 5 "CMAKE_BUILD_TYPE.*RelDebug" | head -30 || echo "No git diff available"

Repository: MFlowCode/MFC

Length of output: 157


🏁 Script executed:

cd . && git show HEAD --stat | head -20

Repository: MFlowCode/MFC

Length of output: 1160


🏁 Script executed:

fd . -name "*.md" | xargs grep -l "ifx\|IntelLLVM\|oneAPI" 2>/dev/null | head -5

Repository: MFlowCode/MFC

Length of output: 287


🏁 Script executed:

fd ".*\.md$" | xargs grep -l "ifx\|IntelLLVM\|oneAPI" 2>/dev/null

Repository: MFlowCode/MFC

Length of output: 187


🏁 Script executed:

git show HEAD:CMakeLists.txt | grep -A 10 'CMAKE_Fortran_COMPILER_ID STREQUAL "Intel"'

Repository: MFlowCode/MFC

Length of output: 1349


The Intel conditional block needs to handle IntelLLVM compiler ID for ifx support.

CMake identifies Intel oneAPI's ifx compiler as CMAKE_Fortran_COMPILER_ID = "IntelLLVM", not "Intel". The current check at line 114 (elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")) will not match ifx, causing the entire Intel-specific block—including the new RelDebug flags (-Og -traceback -check bounds)—to be skipped. Update the condition to also check for IntelLLVM:

elseif ((CMAKE_Fortran_COMPILER_ID STREQUAL "Intel") OR (CMAKE_Fortran_COMPILER_ID STREQUAL "IntelLLVM"))

mpi: bool = True
gpu: str = gpuConfigOptions.NONE.value
debug: bool = False
reldebug: bool = False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Normalize debug/reldebug before persisting config.

Because config is remembered across commands, debug and reldebug can both end up True (for example, after --debug and later --reldebug). toolchain/mfc/build.py then still selects Debug, while make_options() / make_slug() serialize a distinct configuration. That makes --reldebug silently ineffective and creates duplicate build/cache keys.

Also applies to: 47-63

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 31, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.67%. Comparing base (afc724e) to head (e65d1b5).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #1339       +/-   ##
===========================================
+ Coverage   47.42%   64.67%   +17.25%     
===========================================
  Files          70       70               
  Lines       19202    18249      -953     
  Branches     1635     1504      -131     
===========================================
+ Hits         9106    11803     +2697     
+ Misses       9229     5491     -3738     
- Partials      867      955       +88     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sbryngelson sbryngelson merged commit 336487c into MFlowCode:master Mar 31, 2026
54 checks passed
@sbryngelson sbryngelson deleted the fast-debug branch March 31, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant