Commit 9a1d03c7c for llama.cpp
commit 9a1d03c7ca2ca279feca8afd29d40c8e0fff9b6d
Author: Georgi Gerganov <ggerganov@gmail.com>
Date: Fri Nov 6 14:52:26 2026 +0200
tests : override hardware_concurrency in CI (#31797)
The self-hosted CPU runners are containers with 8 CPUs, but
std::thread::hardware_concurrency reports the cores of the host. The
table mode of test-llama-context sizes its pool from that count, so it
runs 4 models x 8 threads on an 8-CPU job and hangs.
Add TEST_ARG_HARDWARE_CONCURRENCY and TEST_ARG_PARALLEL_WORKERS as the
defaults for the auto-selected counts of test-llama-context and of
test-backend-ops, and set them to 8 and 4 for cpu-x64-high-perf.
Assisted-by: dsh:llama.cpp/ggml-org/Qwen3.8-Flash-Next-GGUF (RTX 5090 32GB, DDR5 128GB)
diff --git a/.github/workflows/ci-self-hosted-cpu.yml b/.github/workflows/ci-self-hosted-cpu.yml
index 4cb9be587..c03acdaa0 100644
--- a/.github/workflows/ci-self-hosted-cpu.yml
+++ b/.github/workflows/ci-self-hosted-cpu.yml
@@ -48,6 +48,12 @@ jobs:
cpu-x64-high-perf:
runs-on: hf-jobs-cpu-upgrade:ubuntu26_04
+ # note: this runner has 8 CPUs, but std::thread::hardware_concurrency reports the cores of the
+ # host (https://github.com/ggml-org/llama.cpp/pull/31439#issuecomment-6683386059)
+ env:
+ TEST_ARG_HARDWARE_CONCURRENCY: 8
+ TEST_ARG_PARALLEL_WORKERS: 4
+
steps:
- name: Clone
id: checkout
diff --git a/tests/test-backend-ops.cpp b/tests/test-backend-ops.cpp
index e35806f31..96954a5d7 100644
--- a/tests/test-backend-ops.cpp
+++ b/tests/test-backend-ops.cpp
@@ -48,9 +48,33 @@
#ifdef __EMSCRIPTEN__
# define N_THREADS 1
#else
-# define N_THREADS std::thread::hardware_concurrency()
+static unsigned test_hardware_concurrency() {
+ const char * env = std::getenv("TEST_ARG_HARDWARE_CONCURRENCY");
+ if (env != nullptr) {
+ const long n = std::strtol(env, nullptr, 10);
+ if (n > 0) {
+ return (unsigned) n;
+ }
+ }
+
+ return std::thread::hardware_concurrency();
+}
+
+# define N_THREADS test_hardware_concurrency()
#endif
+static int test_parallel_workers(int default_workers) {
+ const char * env = std::getenv("TEST_ARG_PARALLEL_WORKERS");
+ if (env != nullptr) {
+ const long n = std::strtol(env, nullptr, 10);
+ if (n > 0) {
+ return (int) n;
+ }
+ }
+
+ return default_workers;
+}
+
static void init_tensor_uniform(ggml_tensor * tensor, float min = -1.0f, float max = 1.0f) {
if (ggml_is_empty(tensor)) {
return;
@@ -14048,7 +14072,7 @@ int main(int argc, char ** argv) {
const char * backend_filter = nullptr;
const char * params_filter = nullptr;
const char * test_file_path = nullptr;
- int parallel_workers = 1;
+ int parallel_workers = test_parallel_workers(1);
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "test") == 0) {
diff --git a/tests/test-llama-context.cpp b/tests/test-llama-context.cpp
index 0e905a7c7..62fedea50 100644
--- a/tests/test-llama-context.cpp
+++ b/tests/test-llama-context.cpp
@@ -16,6 +16,7 @@
#include <atomic>
#include <clocale>
#include <cstdio>
+#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <mutex>
@@ -202,6 +203,30 @@ static void print_cases() {
printf("\nthe [rs] cases are also run against a cache pre-filled with a known pattern\n\n");
}
+static unsigned test_hardware_concurrency() {
+ const char * env = std::getenv("TEST_ARG_HARDWARE_CONCURRENCY");
+ if (env != nullptr) {
+ const long n = std::strtol(env, nullptr, 10);
+ if (n > 0) {
+ return (unsigned) n;
+ }
+ }
+
+ return std::thread::hardware_concurrency();
+}
+
+static int test_parallel_workers(int default_workers) {
+ const char * env = std::getenv("TEST_ARG_PARALLEL_WORKERS");
+ if (env != nullptr) {
+ const long n = std::strtol(env, nullptr, 10);
+ if (n > 0) {
+ return (int) n;
+ }
+ }
+
+ return default_workers;
+}
+
int main(int argc, char ** argv) {
std::setlocale(LC_NUMERIC, "C");
@@ -220,7 +245,7 @@ int main(int argc, char ** argv) {
bool list_cases = false;
bool dump_logs_on_fail = true;
- int parallel_workers = 0; // 0 = auto, same flag as in test-backend-ops
+ int parallel_workers = test_parallel_workers(0);
auto parse_parallel_workers = [&](const char * flag, const char * value) {
try {
@@ -401,7 +426,7 @@ int main(int argc, char ** argv) {
return 1;
}
- const unsigned n_hw_2 = std::thread::hardware_concurrency() / 2;
+ const unsigned n_hw_2 = test_hardware_concurrency() / 2;
const size_t n_auto = std::max<size_t>(1, std::min<size_t>(n_hw_2, 4));
const size_t n_pool = parallel_workers > 0
? std::min<size_t>((size_t) parallel_workers, models.size())