Étape 0a.4 close : plan supprimé, feuille de route à jour
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
15939802ce
commit
4dba402b74
@@ -1,120 +0,0 @@
|
||||
# Comparer le moteur embarqué aux références de gnubg de bureau
|
||||
|
||||
- **Date** : 2026-11-02
|
||||
- **Étape** : 0a.4
|
||||
- **Statut** : terminé
|
||||
- **Exécutant** : sous-agent general-purpose, dans un worktree isolé
|
||||
|
||||
## Objectif
|
||||
|
||||
`make test` vérifie automatiquement que le moteur embarqué (`build/engine-cli`)
|
||||
retrouve les résultats de gnubg de bureau sur les 32 positions de
|
||||
`tests/reference/`, aux niveaux 0 et 2 plis, avec une tolérance mesurée et
|
||||
justifiée.
|
||||
|
||||
## Consignes
|
||||
|
||||
1. **Sortie d'`engine-cli` alignée sur le contrat** de
|
||||
`tests/reference/README.md` : une sous-commande (par exemple
|
||||
`engine-cli reference <position_id> <match_id> [dés]`, ou une option) produit,
|
||||
pour une position et un niveau, un objet de même structure que la partie
|
||||
`plies["<n>"]` d'un fichier de résultat (`evaluation`, `moves` ou `cube`).
|
||||
Le classement des coups suit exactement la méthode de la commande `hint` de
|
||||
gnubg (documentée dans le README du format) : nombre de coups, notation,
|
||||
pli réel de chaque coup. Garder `engine-cli` simple : réutiliser les
|
||||
fonctions d'`engine.h`, compléter `engine.h` si nécessaire.
|
||||
2. **Comparateur** : un script lisible (Python 3 ou shell avec `jq`) qui, pour
|
||||
chaque position et chaque niveau, appelle `engine-cli`, compare au résultat
|
||||
de référence et affiche un rapport clair (position, niveau, champ, valeur
|
||||
attendue, valeur obtenue, écart). Il tourne **dans Docker** (ajouter ce qu'il
|
||||
faut à `docker/build-c/Dockerfile` et changer l'étiquette de l'image dans le
|
||||
`Makefile`), jamais avec les outils du PC (ADR 0004).
|
||||
3. **Critères de concordance** :
|
||||
- même nombre de coups légaux ;
|
||||
- même meilleur coup, sauf si gnubg lui-même sépare les deux premiers coups
|
||||
de moins que la tolérance (cas d'égalité : le dire dans le rapport) ;
|
||||
- même pli réel du meilleur coup ;
|
||||
- équités et probabilités à la tolérance près, pour les coups communs ;
|
||||
- même décision de videau, et équités du videau à la tolérance près.
|
||||
4. **Tolérance mesurée, pas devinée** : mesurer l'écart maximal observé sur
|
||||
les 32 positions, l'expliquer (gnubg de bureau en SSE2 avec `-ffast-math`,
|
||||
moteur embarqué en C générique), et mesurer aussi l'écart d'un build du
|
||||
moteur sans `-ffast-math`. Fixer la tolérance avec une marge raisonnable et
|
||||
la justifier dans `tests/reference/README.md`.
|
||||
5. **`tests/test_engine_reference.sh`**, lancé par `make test` : lance
|
||||
`make engine` si nécessaire puis le comparateur ; échoue avec le rapport si
|
||||
un critère n'est pas tenu.
|
||||
6. **`tests/test_reference.sh`** n'utilise plus `jq` sur le PC : passer par
|
||||
l'image Docker de la chaîne C (ADR 0004), et mettre `CREDITS.md` à jour.
|
||||
|
||||
Contraintes :
|
||||
- respecter `CLAUDE.md` et les ADR 0004, 0005 et 0007 : simplicité, identifiants
|
||||
en anglais, commentaires en français, aucune installation hors Docker,
|
||||
`-j2` ;
|
||||
- ne pas modifier les références (`tests/reference/results/`) ni les fichiers
|
||||
de `engine/gnubg/` ; si une divergence vient d'un vrai défaut du moteur
|
||||
embarqué, corriger dans `engine/compat/` ou `engine/src`, et le dire ;
|
||||
- ne rien masquer : si une position ne concorde pas, le rapport doit le
|
||||
montrer, avec la cause trouvée ou les hypothèses ;
|
||||
- `make lint` et `make test` doivent passer ; commits petits, en français, avec
|
||||
la ligne `Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>` ;
|
||||
- ne pas pousser ni créer de merge request.
|
||||
|
||||
Rapport attendu : ce qui a été fait, la tolérance retenue et sa justification
|
||||
(écarts mesurés avec et sans `-ffast-math`), les éventuelles divergences et
|
||||
leur cause, les commandes de vérification.
|
||||
|
||||
## Critères de réussite
|
||||
|
||||
- `make test` compare les 32 positions aux deux niveaux et passe.
|
||||
- La tolérance est documentée et justifiée par des mesures.
|
||||
- Une divergence volontairement introduite (par exemple une référence
|
||||
modifiée dans une copie) fait échouer le test avec un rapport lisible.
|
||||
|
||||
## Résultat
|
||||
|
||||
Terminé le 2026-11-02, branche `comparaison-travail`. `make lint` et
|
||||
`make test` passent (7/7) ; les 32 positions concordent aux deux niveaux
|
||||
avec la tolérance retenue, sans aucune égalité de meilleur coup à signaler.
|
||||
|
||||
**Fait.**
|
||||
|
||||
- `engine-cli --ply N reference POSITION_ID MATCH_ID [DÉS]` produit un niveau
|
||||
au format de `tests/reference/` (`evaluation`, puis `moves` ou `cube`).
|
||||
Nombres écrits avec 9 chiffres significatifs (float32 exact).
|
||||
- `tests/reference/compare.py` (Python 3) et `tests/test_engine_reference.sh`
|
||||
(lancé par `make test`) : comparaison dans l'image `ustagammon/build-c:2`,
|
||||
qui reçoit Python 3 et jq. `tests/test_reference.sh` se relance dans cette
|
||||
image : plus de jq sur le PC. `CREDITS.md` à jour.
|
||||
- Critères, tolérance et mesures documentés dans `tests/reference/README.md`.
|
||||
|
||||
**Défauts du moteur embarqué trouvés et corrigés** (`engine/engine.c`) :
|
||||
|
||||
- en match, l'équité des coups classés était convertie deux fois par
|
||||
`mwc2eq` (`ScoreMove` la convertit déjà) ;
|
||||
- `engine_best_moves` n'appliquait pas tout `hint` : `fAnalyse` était faux
|
||||
et `RefreshMoveList` absent (classement par niveau d'évaluation, puis
|
||||
départage des égalités).
|
||||
|
||||
Changements d'interface : `engine_cube` gagne `optimal` et `decision_text` ;
|
||||
`decision` prend le nom de l'énumération de gnubg (`DOUBLE_TAKE`…), comme
|
||||
les références (`tests/test_engine.sh` adapté).
|
||||
|
||||
**Tolérance : 0,002**, sur probabilités et équités. Mesures sur 2 598
|
||||
nombres : écart maximal 9,5e-4 et 99 % des écarts sous 1,6e-4, que le moteur
|
||||
soit compilé avec ou sans `-ffast-math` (les deux builds diffèrent entre eux
|
||||
de 1,1e-6 au plus). La cause est la sigmoïde de gnubg de bureau en SSE2 avec
|
||||
`-ffast-math`, qui calcule `1/x` par `_mm_rcp_ps` (environ 12 bits) ; preuve :
|
||||
le moteur compilé en SSE2 pour l'essai redonne les références au bit près.
|
||||
L'écart maximal vient d'un seul coup (`opening-64-match`, 2 plis, `8/2 6/2`),
|
||||
où l'écart de 1e-4 fait basculer un choix discret de la recherche.
|
||||
|
||||
**Critère de divergence vérifié** : sur une copie de `results/` avec une
|
||||
équité décalée de 0,01, un nombre de coups légaux, une décision de videau et
|
||||
un meilleur coup modifiés, `compare.py --results <copie>` échoue avec un
|
||||
tableau de 10 écarts lisibles.
|
||||
|
||||
**Suites possibles** : mesurer de même sur téléphone (NEON, autre
|
||||
approximation de la division) ; envisager un build SSE2 d'`engine-cli` sur PC
|
||||
si l'on veut une concordance au bit près (non retenu : le moteur de
|
||||
l'application tournera en C générique ou en NEON).
|
||||
Reference in New Issue
Block a user