Skip to content

Commit 1c0ee04

Browse files
edsavagecursoragent
andcommitted
[ML] Fix test parallelism for low-core CI machines and add diagnostics
The ceil(nproc/3) formula was too conservative on 4-core machines (macOS CI Orka VMs), yielding -j 2 which serialised test suites into 5 waves. On <=4 cores, CTest internal parallelism is modest enough that using all cores avoids unnecessary serialisation. Also adds diagnostic logging of CPU count and parallelism settings to build.gradle, docker_entrypoint.sh, and run-tests-individually.cmake to make CI performance easier to analyse. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 079e7e9 commit 1c0ee04

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

build.gradle

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ project.ext.numCpus = Runtime.runtime.availableProcessors()
116116
// Each suite spawns ctest --parallel <all_cpus> internally, so running too
117117
// many suites simultaneously causes resource contention. These values were
118118
// determined empirically (see PR #2900).
119-
project.ext.testParallel = isWindows ? 2 : Math.max(1, (int) Math.ceil(numCpus / 3.0))
119+
// On low-core machines (<=4, e.g. macOS CI Orka VMs), use all cores since
120+
// CTest internal parallelism is modest enough that contention is minimal.
121+
project.ext.testParallel = isWindows ? 2 : (numCpus <= 4 ? numCpus : Math.max(2, (int) Math.ceil(numCpus / 3.0)))
120122
project.ext.makeEnvironment = [ 'CPP_CROSS_COMPILE': cppCrossCompile,
121123
'VERSION_QUALIFIER': versionQualifier,
122124
'SNAPSHOT': (isSnapshot ? 'yes' : 'no'),
@@ -232,6 +234,9 @@ task test(type: Exec) {
232234
workingDir "${projectDir}"
233235
dependsOn 'strip'
234236
description = 'Run C++ tests'
237+
doFirst {
238+
logger.lifecycle("Test parallelism: numCpus=${numCpus}, testParallel=${testParallel} (cmake --build -j ${testParallel})")
239+
}
235240
}
236241

237242
check {

cmake/run-tests-individually.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ if(NOT "${_current_batch}" STREQUAL "")
188188
endif()
189189

190190
list(LENGTH _batches _num_batches)
191-
message(STATUS "Running ${_num_tests} test(s) in ${_num_batches} batch(es), "
192-
"max ${MAX_PROCS} parallel process(es)")
191+
message(STATUS "${TEST_SUITE}: ${_num_tests} test(s) in ${_num_batches} batch(es), "
192+
"MAX_ARGS=${MAX_ARGS}, MAX_PROCS=${MAX_PROCS} (${_num_cpus} logical CPUs)")
193193

194194
# ---------------------------------------------------------------------------
195195
# Generate a per-batch runner script invoked by each CTest test entry

dev-tools/docker/docker_entrypoint.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ if [ "x$1" = "x--test" ] ; then
6868
echo passed > build/test_status.txt
6969
# Each test suite spawns ctest --parallel <nproc> internally, so limit
7070
# the number of suites running concurrently to avoid resource contention.
71-
TEST_PARALLEL=$(( ($(nproc) + 2) / 3 ))
71+
# On low-core machines (<=4), use all cores since CTest internal
72+
# parallelism is modest enough that contention is minimal.
73+
NCPUS=$(nproc)
74+
if [ "$NCPUS" -le 4 ]; then
75+
TEST_PARALLEL=$NCPUS
76+
else
77+
TEST_PARALLEL=$(( (NCPUS + 2) / 3 ))
78+
fi
79+
echo "Test parallelism: nproc=${NCPUS}, TEST_PARALLEL=${TEST_PARALLEL} (cmake --build -j ${TEST_PARALLEL})"
7280
cmake --build cmake-build-docker ${CMAKE_VERBOSE} -j ${TEST_PARALLEL} -t test_individually || echo failed > build/test_status.txt
7381
fi
7482

0 commit comments

Comments
 (0)