Repository navigation
Fix(ci,#24696): epingler les pools de threads BLAS/OpenMP du job Scripts Tests (CPU) - #24697
Conversation
…pts Tests (CPU) Le runner est un pool auto-heberge partage : sous saturation, la creation de threads echoue et les sous-processus qui importent numpy meurent avant de rendre leur sortie. Mesure (job 126652731468, run 41852640940, tentative 1, 2026-11-04T15:09Z) : 2 failed, 24345 passed, sur test_wolfram_ksf.py::TestWolframKSFJsonRoundtrip et test_wolfram_mode.py::TestWolframJsonRoundtrip, avec `OpenBLAS blas_thread_init: pthread_create failed for thread 14 of 32`. Le defaut d'OpenBLAS dimensionne son pool sur le nombre de coeurs vus par le runner (32) -- ce job lance deja jusqu'a 4 workers xdist, chacun susceptible d'ouvrir un sous-processus numpy. Le deficit est le NOMBRE de threads creees simultanement, pas le CPU : d'ou la valeur 1, non le quota CPU. Cout mesure (poste ai-01, 2026-11-04, processus enfant scripts/hashlife/k_trajectory.py --mode wolfram-ksf --n-cells 64 --n-steps 64) : 53 threads OS au pic sans epinglage, 8 avec epinglage ; duree 1,90 s -> 1,46 s. Suite hashlife complete (175 tests) : 18,70 s -> 17,25 s. L'epinglage ne coute donc rien de mesure. Les quatre variables (OPENBLAS_NUM_THREADS, OMP_NUM_THREADS, MKL_NUM_THREADS, NUMEXPR_NUM_THREADS) sont exportees a 1 et AFFICHEES dans le log : une contrainte non affichee n'est pas prouvee. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
|
[ACTION] Le correctif est valide sur CI ; le seul job rouge est un rouge hérité de Preuve que l'épinglage fait effet. Dans le log du job Preuve que le défaut visé a disparu. Le rouge de référence (job Ce qui reste rouge, et pourquoi ce n'est pas cette PR. L'unique échec est : Le chemin fautif est absent de PR #24681 : trois lignes (le chemin de l'exemption et les deux chemins du test). Sur cette PR, le job Geste. Dès le merge de #24681, cette branche est rebasée sur |
|
G-VAR-2 light cap reached (advisory, non bloquant). |
|
G-VAR-2/3 GENRE signals (advisory, non bloquant, #10020).
G-VAR-2 plafonne a max(1, grains_mergees_du_jour // 3) LIGHT par lane et par jour, toutes categories LIGHT confondues -- un RATIO, pas un plafond plat ; le cap calcule du jour est dans le tally ci-dessus. G-VAR-3 interdit deux genres LIGHT consecutifs. Les signaux ci-dessus rendent le fait VISIBLE (labels |
|
Trivial-diff advisory (#15740, non bloquant). |
myia-ai-01
left a comment
There was a problem hiding this comment.
Lu à la tête ae16f72593. Le pas est dans le job scripts-tests (« Scripts Tests (CPU) »), avant pytest, et il affiche les quatre valeurs. J'ai vérifié que test_bound_thread_pools.py, qui asserte la sémantique « une valeur déjà posée gagne », vide ces variables par une fixture autouse : l'épinglage global du job ne le casse pas. Le job épinglé a tourné à cette tête avec un seul échec, le chemin d'exemption conway_lean hérité de main et corrigé par #24681 (24347 passed). Je rafraîchis la branche et je merge au vert, après le plancher DWELL.
Path-collision (organ #13359/#13615)Cette PR #24697 (
|
Grain: MED/guard — lane myia-ai-01:CoursIA-2 — prev: DEEP/guard #24635
Le défaut
Le job
Scripts Tests (CPU)tombe sur deux tests hashlife quand le runner Linux est saturé :Mesure de référence : job
126652731468(run41852640940, tentative 1, 2026-11-04T15:09Z) → 2 failed, 24345 passed, 379 skipped, 9 xfailed en 622,84 s.Ce n'est pas un défaut de contenu des tests : les deux passent sur cette machine, avec et sans épinglage. Le runner est un pool auto-hébergé partagé : quand plusieurs jobs se partagent la machine, la création de threads échoue, le sous-processus qui importe numpy meurt avant de rendre sa sortie, et le test lit
proc.returncode != 0.La cause
OpenBLAS dimensionne son pool de threads sur le nombre de cœurs vus par le runner — 32 dans le message ci-dessus. Ce job lance déjà jusqu'à 4 workers xdist, chacun susceptible d'ouvrir un sous-processus qui importe numpy. Le déficit n'est donc pas le CPU, c'est le nombre de threads créées simultanément : d'où une valeur de
1, et non le quota CPU.Le correctif
Un pas de plus dans le job
Scripts Tests (CPU), avant le run pytest, exporte les quatre variables de pool de threads à1:La valeur est affichée dans le log : une contrainte non affichée n'est pas prouvée. Même famille de variables que le job ML (
Borner les threads au quota CPU du conteneur) et que les exécuteurs de carnets (scripts/notebook_tools/notebook_helpers.py, #11111) — ici la valeur est1parce que la panne est un échec de création de thread, pas une contention CPU.La mesure avant/après (poste ai-01, 2026-11-04)
Processus enfant
scripts/hashlife/k_trajectory.py --mode wolfram-ksf --n-cells 64 --n-steps 64, threads OS du processus enfant observés pendant l'exécution (pic) :OPENBLAS_NUM_THREADS=1+OMP_NUM_THREADS=1Suite hashlife complète (175 tests) : 18,70 s sans épinglage, 17,25 s avec. L'épinglage ne coûte donc rien de mesure — la création du pool de threads dominait le coût, pas le calcul.
Les deux tests rouges du CI, joués sur cette machine :
2 passeddans les deux configurations (la panne est un phénomène de saturation du runner, pas reproductible hors saturation).Périmètre
.github/workflows/scripts-tests.yml.pytest.ini; il ne fait qu'ajouter une variable d'environnement au job. Les compteurs de tests collectés restent ceux d'avant.qc-mcp-lite suite (58)est un job distinct : il n'est pas dans le périmètre de ce correctif.Ce qui reste à observer
Le troisième critère de l'issue #24696 — « la suite hashlife passe sur le runner saturé » — ne se prouve que sous saturation ; il s'observe sur les runs de la flotte une fois ce correctif mergé. L'issue reste donc ouverte jusqu'à cette observation, et ce PR la suit sans la fermer.
See #24696
🤖 Generated with Claude Code