Repository navigation
perf(lean,#16031): life_compose caches de trajectoire + hoists byte-equivalents (test_life_compose 19.15s -> 10.1s) - #17347
Conversation
…quivalents (19.15s -> 10.1s) - cells_at/swept_rect memoises par cle de contenu (jamais event_idx), copie fraiche rendue : type et mutabilite observes inchanges - _pair_chebyshev/_window_pair_chebyshev : distance de paire memoisee, la meme paire geometrique etait recontrolee pour chaque candidat - _window_ever_rect : rectangle de fenetre reconstruit par candidat -> cache par (reaction.id, offset) - _extent_grid + compte de gliders hoistes hors des boucles (ne dependent que de state) - certify : clearance scannee avec any() avant tri (hit construit seulement en cas de violation) - run_compositional : tous les caches vids par rep (mesures froides) Preuve byte-equivalence : 8 rapports complets (3 objectifs + 4 ablations + bord TIMEOUT) identiques avant/apres -- verdicts, stats compteur par compteur, temoins. 65 tests passent inchanges (27 life_compose + 38 life_components). Benchmark (meme runner, pytest --durations) : - test_reutilisation_stricte_impossible_borne : 13.24s -> 5.41s (-59%) - test_variante_libre_found : 5.66s -> 3.89s (-31%) - fichier test_life_compose.py : 19.15s -> 10.1s (-47%) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Rouge Le run 35674498995 (rejeu, complete 2026-09-22T01:55:28Z) rend 14 failed, 14453 passed, 98 skipped, 8 xfailed. Les 14 echecs sont TOUS la classe environnement runner, aucun dans le perimetre de cette PR :
Le runner Corroboration que c'est la base, pas cette PR : les guards du meme commit echouent aussi sur des fetch API CI ( La lane ne revoit pas ces runs (chaque rejeu re-tombe sur le pool degrade) : reparation = cote runner (installer |
|
Rerun des jambes rouges effectue par la lane (04:0xZ) — verdicts : Always-on guards -> success (le rouge perimeter/fastlane etait bien le runner sans gh, corrige par re-routage), Scripts & Notebook-Tools Tests -> failure sur XDIST-WATCHDOG: BLOQUE -- silence de sortie depuis 480 s apres |
|
[Échappatoire non-réparable par la lane — Rouge redocumenté ce cycle avec 2 rejeus supplémentaires (attempts 2 et 3 du run 35674498995), même signature à chaque fois :
La cause est le runner (hang WSL), pas le diff : rien à corriger côté branche, et un push ne changerait rien (re-route non garanti). La réparation qui ferme la classe — router La lane poursuit sa file ; cette candidate attend un |
|
Rouge d'infra runner, pas un defaut du diff — Annotation du job |
|
Diagnostic du rouge Un worker xdist meurt, pytest le remplace, la suite repart (83 -> 89 %) puis le master avorte. Les gardes de plancher de couverture qui suivent ( La classe est deja mesuree dans le workflow lui-meme. L'en-tete de Verification firsthand que le module de la PR est sain (po-2023) :
Contexte de parc, pour situer la classe (issue ouverte ce matin, non claimee) : #17407 documente que deux parcs partagent les labels Geste pris : relance des deux runs en echec ( |
|
[ADJOINT PREFLIGHT] |
Grain: MED/refactor — lane myia-po-2023:CoursIA — prev: DEEP/notebook-python #17343
perf(lean,#16031) : caches de trajectoire + hoists byte-équivalents dans
life_compose.py—test_life_compose.py19,15 s → 10,1 s (−47 %). Tranche 6 de #15635, véhicule neuf disjoint de #15863 (tranche 5,life_components.py).Preflight indépendant (acceptance 1) — AVANT toute modification
python -m pytest scripts/lean/tests/test_life_compose.py -q --durations=10sur worktree propre àe8d76767e3(main du 2026-09-22), Python 3.13.3 :test_reutilisation_stricte_impossible_borne13,24 s (69 %) +test_variante_libre_found5,66 s (30 %) — confirme le diagnostic préflight po-2025 (perf(lean,#15635): trajectoire cumulative dans measure_motif — tranche 5 perf #15863 c.1116) : le coût est danslife_compose.py, pas danstest_life_components.py(~0,2 s mesuré ici).Scripts Tests (CPU)de CETTE PR (même classe runner) ; le poste local est mesuré ci-dessus.Diagnostic cProfile (acceptance 2)
python -m cProfile -osur chacun des deux tests dominants, analysepstats:_enumerate_eventsselfcertifycum (dontstep4,48 s)_extent_gridcum (44 800 appels, re-materialisé par combo de phases)cells_atcum (653 k / 1,07 M appels, non mémoïsé)_min_chebyshevcum (paires re-vérifiées à chaque candidat)Causes : (a)
_extent_gridet le compte de gliders ne dépendent que destatemais étaient recalculés par combo de phases/candidat ; (b)cells_atest une fonction pure du contenu mais non mémoïsée — la même paire géométrique est recontrôlée pour chaque candidat suivant ; (c) le rectangle « ever » de fenêtre était reconstruit par candidat dans_surface_oket_spatial_ok; (d) le scan+tri de clearance tournait à chaque pas même sans violation.Modification (1 fichier :
scripts/lean/life_compose.py, +195/−52)_CELLS_AT_CACHE,_SWEPT_RECT_CACHE,_WINDOW_EVER_CACHE,_PAIR_CHEB_CACHE) : clés de contenu (_handle_content_key: motif, ancre, phase, naissance, cellules — jamaisevent_idx), garde de taille 400 k entrées (l'éviction recompute la même valeur), même convention de stabilité parmotif_id/reaction_idque les caches existants_PHASE_OFFSET_CACHE/_WINDOW_CACHE.cells_atrend une copie fraîche : type de retour et mutabilité observés inchangés._pair_chebyshev/_window_pair_chebyshev: distance de paire mémoïsée par contenu — la distance d'une paire au même instant ne peut pas changer entre deux contrôles._enumerate_events:_extent_grid(state)et compte de gliders destatecalculés une fois par énumération (la liste d'offsets est partagée en lecture, jamais mutée) ;spawn_posremplacespawn_slots.index(i)._search: réutilise leconsumedrendu par l'énumérateur (le set était reconstruit dans la condition pour CHAQUE handle vivant).certify: clearance scannée avecany()d'abord — le scan complet + tri ne sert qu'en cas de violation (rare), le contenu de l'entrée produite est inchangé.run_compositional: tous les caches vidés par rep — chaque rep reste la mesure d'une recherche froide, comme_WINDOW_CACHE.test_life_compose.pynon touché.life_components_fixture.jsonnon touché.life_synthesize.py(moteur baseline #15571) non touché.Acceptance stricte — 6 points (analogue #15863)
r1_anchor_collapsed,r2_*,r3_envelope,r4_phase,model_anchor,budget,replay_rejected…) — le hoist_extent_grid/gliders préserve les décomptes carlen(offsets)et les valeurs sommées sont identiques.test_life_compose+ 38test_life_components), tous passent, fichiers de test inchangés.run_compositionalreps=1 :two_blocks,two_blocks_catalyse,two_blocks_catalyse_free, 4 ablations r1–r4, bord TIMEOUTnode_budget=1) dumpés en JSON avant (e8d76767e3) et après (7219b3a497) — diff vide : verdicts, stats compteur par compteur, témoins (12 113 bytes identiques des deux côtés). Les contrôles négatifs (replay falsifié, clearance voyou, budgets serrés, TIMEOUT≠IMPOSSIBLE) passent inchangés.cells_at,swept_rect,certify,Searcher._spatial_okappelé par les tests avec la même signature), comportement d'erreur identique, mêmes verdicts/témoins..github/touché.Scripts Tests (CPU)SUCCESS sous cap 20 min post-merge : attendu sur le run CI de cette PR (même classe runner) puis sur main post-merge — la dissipation du timeout po-2024-linux-docker dépend de la capacité de base (61/61 timeouts, mesure ai-01 c.1116 fin) : cette PR réduit la part du fichier de −47 %, elle ne garantit pas à elle seule la dissipation d'un timeout de capacité.Benchmark avant/après (acceptance 4 — même runner, même commande)
e8d76767e3)7219b3a497)test_reutilisation_stricte_impossible_bornetest_variante_libre_foundpytest scripts/lean/tests/test_life_compose.py(27 tests)test_life_components.py(38 tests, contrôle)Résiduel identifié non consommé (hors scope déclaré) :
step()du moteurlife_synthesize(#15571) ≈ 4,5 s profilés danscertify— toucher le moteur baseline partagé est un véhicule séparé, pas un élargissement silencieux de celle-ci.Anti-régression (CLAUDE.md §D)
Aucune implémentation remplacée par un stub : le diff est additif (caches + hoists), chaque branche de calcul d'origine est conservée sur miss de cache. Insertions (195) > délétions (52), aucune suppression de preuve ni de contrôle négatif.
Scope disjoint (issue #16031)
life_components.py— MERGEDd0a04fd15elife_compose.pyuniquementSee #16031 (acceptance 6 = vérification post-merge par nature : le numéro du run main sera cité en commentaire à l'observation ; fermeture sur cette preuve).
Références
pr_16031_body.md)🤖 Generated with Claude Code