ci: re-enable CGAL tests with LOW_MEMORY_BUILD for Raspberry Pi runner
Finding-I from doc/reviewer/external-audit-2026-05-30.md.
Root cause: CGAL+Eigen at -O3 drives cc1plus peak RAM to ~700 MB per
Unity compilation unit (batch size 4) on ARM64. With the 1600 MB
container limit the 2nd or 3rd TU reliably triggered OOM-kill, so
test-cgal was gated off via `if: false` since 2026-05-26.
Fix: new CMake option CONFORMALLAB_LOW_MEMORY_BUILD=ON applies four
orthogonal memory-saving measures to conformallab_cgal_tests:
1. -O0 (no debug info): optimizer passes entirely skipped → cc1plus
peak drops from ~700 MB to ~150-200 MB per TU on ARM64.
Omitting -g avoids the additional object-file / linker RAM cost.
2. CONFORMALLAB_USE_PCH=OFF: saves the one-time ~200 MB PCH
compilation cost; each TU re-parses CGAL headers (fast at -O0).
3. UNITY_BUILD_BATCH_SIZE=1: one source file per cc1plus invocation,
removing the "4-file template-explosion" per-unit multiplier.
4. -Wl,--no-keep-memory (GNU ld): linker releases symbol tables after
each input file → ~15-25 % less linker RSS.
Verified locally with cmake -DCONFORMALLAB_LOW_MEMORY_BUILD=ON:
277/277 CGAL tests pass, 31 s runtime (vs 2 s at -O3 — expected;
tests run 15× slower without optimizer but all correct).
CI workflow changes (cpp-tests.yml):
- test-cgal re-enabled: `if: github.event_name == 'pull_request'`
- Configure step adds -DCONFORMALLAB_LOW_MEMORY_BUILD=ON
- Container memory: 1600m → 2000m (--memory-swap=3000m for 1 GB swap
headroom), using ~half of the Pi's 3-4 GB while leaving OS margin.
CLAUDE.md updated: new flag added to compile-time options table; CI
status row corrected from DISABLED to active.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -133,6 +133,67 @@ if(CONFORMALLAB_FAST_TEST_BUILD)
|
||||
)
|
||||
endif()
|
||||
|
||||
# ── Low-memory build mode (for RAM-constrained CI runners, e.g. Raspberry Pi) ──
|
||||
#
|
||||
# Problem: CGAL + Eigen at -O3 drives cc1plus peak RAM to ~600-800 MB per
|
||||
# Unity compilation unit on ARM64 Linux. A 1600 MB container limit with a
|
||||
# batch of 4 files per unit causes OOM-kill during the build.
|
||||
#
|
||||
# This flag enables three orthogonal memory-saving measures:
|
||||
#
|
||||
# 1. -O0 (no debug info): drops cc1plus backend RAM by ~60-70 %.
|
||||
# Optimizer passes (inlining, register allocation, constant propagation)
|
||||
# dominate the backend. At -O0 they are entirely skipped → peak per
|
||||
# TU falls from ~700 MB to ~150-200 MB on ARM64.
|
||||
# We omit -g deliberately: debug info adds ~30-40 % object-file size
|
||||
# and increases linker RSS. CI needs "does it compile + do tests pass",
|
||||
# not debuggability.
|
||||
#
|
||||
# 2. PCH OFF: the precompiled header itself consumes ~200 MB to compile
|
||||
# and is re-read by every TU. Disabling it saves the one-time PCH
|
||||
# compilation cost; each TU re-parses CGAL headers, but at -O0 this
|
||||
# is fast.
|
||||
#
|
||||
# 3. UNITY_BUILD_BATCH_SIZE=1: one source file per unity unit. Removes
|
||||
# the "4 files × CGAL parse cost" multiplier; each cc1plus process
|
||||
# only sees one file worth of templates.
|
||||
#
|
||||
# 4. Linker memory flag (GCC/Clang only): --no-keep-memory tells GNU ld
|
||||
# to release symbol table memory after each input file instead of
|
||||
# keeping it for cross-reference. Reduces linker RSS by 15-25 % at
|
||||
# the cost of slightly longer link time.
|
||||
#
|
||||
# Activate with:
|
||||
# cmake -S code -B build -DWITH_CGAL_TESTS=ON \
|
||||
# -DCONFORMALLAB_LOW_MEMORY_BUILD=ON
|
||||
# Expected peak per cc1plus: ~150-200 MB → fits in 1800-2000 MB container.
|
||||
# Test runtime is 2-4× slower than Release (CGAL traversals unoptimized),
|
||||
# but correctness is unaffected.
|
||||
option(CONFORMALLAB_LOW_MEMORY_BUILD
|
||||
"Build CGAL tests with -O0, no PCH, UNITY_BATCH_SIZE=1 for RAM-constrained CI." OFF)
|
||||
|
||||
if(CONFORMALLAB_LOW_MEMORY_BUILD)
|
||||
message(STATUS "CONFORMALLAB_LOW_MEMORY_BUILD active: -O0, no PCH, unity batch 1.")
|
||||
|
||||
# 1. -O0, no debug info
|
||||
target_compile_options(conformallab_cgal_tests PRIVATE
|
||||
$<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-O0 -UNDEBUG>
|
||||
)
|
||||
|
||||
# 2. PCH off — force-override the option so the block below is skipped
|
||||
set(CONFORMALLAB_USE_PCH OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# 3. Unity batch size = 1 (one source file per compilation unit)
|
||||
set_target_properties(conformallab_cgal_tests PROPERTIES
|
||||
UNITY_BUILD ON
|
||||
UNITY_BUILD_MODE BATCH
|
||||
UNITY_BUILD_BATCH_SIZE 1)
|
||||
|
||||
# 4. Linker memory hint (GNU ld / lld)
|
||||
target_link_options(conformallab_cgal_tests PRIVATE
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Wl,--no-keep-memory>)
|
||||
endif()
|
||||
|
||||
target_link_libraries(conformallab_cgal_tests PRIVATE GTest::gtest_main)
|
||||
|
||||
# ── Compile-time speed-up: precompiled headers ───────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user