Étape 0b : moteur en WebAssembly, page de test et de mesure #9

Merged
pierre merged 6 commits from wasm into main 2026-11-02 18:24:15 +00:00
Owner

Pourquoi

Étape 0b, la mesure décisive du prototype (docs/etape-0.md). Le moteur peut-il tourner assez vite et assez léger dans le navigateur du Fairphone 4 pour que l'application soit une PWA, plutôt qu'une application Android native ? Pour le savoir, il faut le même moteur compilé en WebAssembly, la preuve qu'il donne les mêmes résultats que le moteur natif, et une page de mesure que Pierre ouvrira sur le téléphone.

Quoi

  • make engine-wasm compile le moteur avec Emscripten (image emscripten/emsdk:3.1.64, validée dans l'ADR 0004) :
    • mêmes sources qu'en natif, dont la liste est désormais partagée dans engine/sources.mk ;
    • C générique, sans threads ;
    • données (réseaux, bases de fin de partie, table d'équité) regroupées dans build/wasm/engine.data et chargées une fois ;
    • une recompilation ne refait rien si rien n'a changé.
  • Interface JavaScript web/engine-wasm.mjs (bestMove, cubeDecision, evaluate, reference). Elle appelle le main d'engine-cli compilé en WebAssembly : la sortie est exactement le JSON d'engine-cli, sans code de mise en forme réécrit.
  • Même suite de contrat (ADR 0007) : tests/test_wasm_reference.sh, lancé par make test, rejoue les 32 positions de référence en WebAssembly sous Node, avec le même comparateur et la même tolérance qu'en natif. compare.py --cli choisit le programme interrogé.
  • Page de test web/index.html : le moteur tourne dans un Web Worker. On choisit une position, des dés et un niveau, et la page affiche le meilleur coup et son temps de calcul.
  • Page de mesure web/bench.html :
    • temps du meilleur coup à 0 et 2 plis et de la décision de videau à 2 plis (médiane et maximum) ;
    • chargement du moteur, taille téléchargée (brute et gzip) et mémoire ;
    • comparaison aux seuils de l'étape 0 ;
    • bouton « Copier les résultats ».
  • make deploy-web sert la page sur le réseau local, avec le serveur HTTP de Python de l'image build-c (aucune nouvelle image), et affiche l'adresse à ouvrir depuis le téléphone. make deploy y renvoie pour l'instant.
  • make bench fait la même mesure sous Node, sur le PC.
  • docs/guide-test-etape-0.md : le guide pas à pas pour la séance de mesure avec Pierre. Document temporaire de l'étape 0.
  • La feuille de route et le journal sont à jour, et le journal note la clôture de l'incident des hooks Gitea.

Comment

Travail délégué à un sous-agent selon un plan écrit avant la délégation, supprimé à la clôture ; son résultat est repris ici.

Résultats, vérifiés par la session principale après fusion de main dans la branche :

  • make engine-wasm : 20 s, rien n'est recompilé au second appel ;
  • make lint et make test : 8/8. La suite de contrat en WebAssembly donne le même écart maximal qu'en natif (9,53e-4 sur opening-64-match à 2 plis, tolérance 2e-3). Comparé directement au natif, l'écart maximal est de 2,3e-6, avec les mêmes classements et les mêmes décisions ;
  • taille téléchargée : 9,0 Mo brute, 7,3 Mo gzip (seuil : 40 Mo), dont 8,7 Mo de données, 180 Ko de .wasm et 73 Ko de JavaScript.

Mesures sur le PC (i5-2450M de 2011), au maximum sur les positions de référence :

Mesure Node (make bench) Chromium 130 Firefox 131 Seuil (téléphone)
Meilleur coup, 0 pli 2 ms 5 ms 14 ms 0,3 s
Meilleur coup, 2 plis (médiane / max) 107 / 454 ms 87 / 316 ms 693 / 2 341 ms 3 s
Videau, 2 plis (médiane / max) 27 / 109 ms 21 / 103 ms 158 / 902 ms 3 s
Chargement du moteur 82 ms 178 ms 204 ms –

Mémoire WebAssembly : 52 Mo.

Le sous-agent a vérifié les pages dans Chromium et Firefox sans interface (image Playwright utilisée ponctuellement, hors du dépôt), sur l'adresse réseau du PC et en HTTP non sécurisé comme sur le téléphone. Il a vérifié le meilleur coup, la mesure complète et la copie du rapport, ainsi que les types MIME (application/wasm).

Choix et compromis

  • Le main d'engine-cli réutilisé en WebAssembly, plutôt qu'une nouvelle mise en JSON : une seule implémentation, donc les mêmes sorties garanties.
  • Fichiers JavaScript en .mjs, sans framework ni étape de build : les mêmes modules servent au navigateur et à Node.
  • Données embarquées telles quelles (8,7 Mo) : simple, et largement sous le seuil. La base de fin de partie à deux côtés pèse 6,8 Mo ; elle pourrait devenir facultative si la taille devenait un problème.
  • Seuils jugés sur le temps maximal, la médiane étant donnée en plus.
  • Textes des pages écrits dans le HTML et non dans des fichiers de textes séparés (ADR 0007) : ce sont des pages de prototype, pas l'application.

Risques et déploiement

  • Firefox est environ 7 fois plus lent que Chromium sur ce PC. Le guide demande de mesurer dans les deux navigateurs du téléphone. Le chiffre qui décide est celui du Fairphone, pas celui du PC.
  • make deploy-web copie les fichiers dans le conteneur au démarrage : il faut relancer le serveur après une modification.
  • Le serveur écoute sur le réseau local (port 8080) pendant le test seulement. Si un pare-feu bloque le téléphone, le guide explique comment ouvrir et refermer le port.

Retour arrière : annuler le commit de fusion.

Comment vérifier

git switch main && git pull
make setup && make engine && make engine-wasm
make lint && make test
make bench
make deploy-web      # ouvrir l'adresse affichée, puis /bench.html ; Ctrl+C pour arrêter

Hors périmètre

  • Les mesures sur le Fairphone 4 : séance avec Pierre, guidée par docs/guide-test-etape-0.md.
  • La décision du socle (PWA ou Android natif) : un ADR, après les mesures et avec la validation de Pierre.
  • Le plateau jouable : étape 0d.

Generated with Claude Code https://claude.com/claude-code

## Pourquoi Étape 0b, la mesure décisive du prototype (`docs/etape-0.md`). Le moteur peut-il tourner assez vite et assez léger dans le navigateur du Fairphone 4 pour que l'application soit une PWA, plutôt qu'une application Android native ? Pour le savoir, il faut le même moteur compilé en WebAssembly, la preuve qu'il donne les mêmes résultats que le moteur natif, et une page de mesure que Pierre ouvrira sur le téléphone. ## Quoi - **`make engine-wasm`** compile le moteur avec Emscripten (image `emscripten/emsdk:3.1.64`, validée dans l'ADR 0004) : - mêmes sources qu'en natif, dont la liste est désormais partagée dans `engine/sources.mk` ; - C générique, sans threads ; - données (réseaux, bases de fin de partie, table d'équité) regroupées dans `build/wasm/engine.data` et chargées une fois ; - une recompilation ne refait rien si rien n'a changé. - **Interface JavaScript** `web/engine-wasm.mjs` (`bestMove`, `cubeDecision`, `evaluate`, `reference`). Elle appelle le `main` d'`engine-cli` compilé en WebAssembly : la sortie est exactement le JSON d'`engine-cli`, sans code de mise en forme réécrit. - **Même suite de contrat** (ADR 0007) : `tests/test_wasm_reference.sh`, lancé par `make test`, rejoue les 32 positions de référence en WebAssembly sous Node, avec le même comparateur et la même tolérance qu'en natif. `compare.py --cli` choisit le programme interrogé. - **Page de test `web/index.html`** : le moteur tourne dans un Web Worker. On choisit une position, des dés et un niveau, et la page affiche le meilleur coup et son temps de calcul. - **Page de mesure `web/bench.html`** : - temps du meilleur coup à 0 et 2 plis et de la décision de videau à 2 plis (médiane et maximum) ; - chargement du moteur, taille téléchargée (brute et gzip) et mémoire ; - comparaison aux seuils de l'étape 0 ; - bouton « Copier les résultats ». - **`make deploy-web`** sert la page sur le réseau local, avec le serveur HTTP de Python de l'image `build-c` (aucune nouvelle image), et affiche l'adresse à ouvrir depuis le téléphone. `make deploy` y renvoie pour l'instant. - **`make bench`** fait la même mesure sous Node, sur le PC. - **`docs/guide-test-etape-0.md`** : le guide pas à pas pour la séance de mesure avec Pierre. Document temporaire de l'étape 0. - La feuille de route et le journal sont à jour, et le journal note la clôture de l'incident des hooks Gitea. ## Comment Travail délégué à un sous-agent selon un plan écrit avant la délégation, supprimé à la clôture ; son résultat est repris ici. Résultats, vérifiés par la session principale après fusion de `main` dans la branche : - `make engine-wasm` : 20 s, rien n'est recompilé au second appel ; - `make lint` et `make test` : 8/8. La suite de contrat en WebAssembly donne **le même écart maximal qu'en natif** (9,53e-4 sur `opening-64-match` à 2 plis, tolérance 2e-3). Comparé directement au natif, l'écart maximal est de 2,3e-6, avec les mêmes classements et les mêmes décisions ; - **taille téléchargée : 9,0 Mo brute, 7,3 Mo gzip** (seuil : 40 Mo), dont 8,7 Mo de données, 180 Ko de `.wasm` et 73 Ko de JavaScript. Mesures sur le PC (i5-2450M de 2011), au maximum sur les positions de référence : | Mesure | Node (`make bench`) | Chromium 130 | Firefox 131 | Seuil (téléphone) | | --- | --- | --- | --- | --- | | Meilleur coup, 0 pli | 2 ms | 5 ms | 14 ms | 0,3 s | | Meilleur coup, 2 plis (médiane / max) | 107 / 454 ms | 87 / 316 ms | 693 / 2 341 ms | 3 s | | Videau, 2 plis (médiane / max) | 27 / 109 ms | 21 / 103 ms | 158 / 902 ms | 3 s | | Chargement du moteur | 82 ms | 178 ms | 204 ms | – | Mémoire WebAssembly : 52 Mo. Le sous-agent a vérifié les pages dans Chromium et Firefox sans interface (image Playwright utilisée ponctuellement, hors du dépôt), sur l'adresse réseau du PC et en HTTP non sécurisé comme sur le téléphone. Il a vérifié le meilleur coup, la mesure complète et la copie du rapport, ainsi que les types MIME (`application/wasm`). ## Choix et compromis - **Le `main` d'`engine-cli` réutilisé en WebAssembly**, plutôt qu'une nouvelle mise en JSON : une seule implémentation, donc les mêmes sorties garanties. - **Fichiers JavaScript en `.mjs`, sans framework ni étape de build** : les mêmes modules servent au navigateur et à Node. - **Données embarquées telles quelles** (8,7 Mo) : simple, et largement sous le seuil. La base de fin de partie à deux côtés pèse 6,8 Mo ; elle pourrait devenir facultative si la taille devenait un problème. - **Seuils jugés sur le temps maximal**, la médiane étant donnée en plus. - **Textes des pages écrits dans le HTML** et non dans des fichiers de textes séparés (ADR 0007) : ce sont des pages de prototype, pas l'application. ## Risques et déploiement - **Firefox est environ 7 fois plus lent que Chromium** sur ce PC. Le guide demande de mesurer dans les deux navigateurs du téléphone. Le chiffre qui décide est celui du Fairphone, pas celui du PC. - `make deploy-web` copie les fichiers dans le conteneur au démarrage : il faut relancer le serveur après une modification. - Le serveur écoute sur le réseau local (port 8080) pendant le test seulement. Si un pare-feu bloque le téléphone, le guide explique comment ouvrir et refermer le port. Retour arrière : annuler le commit de fusion. ## Comment vérifier ``` git switch main && git pull make setup && make engine && make engine-wasm make lint && make test make bench make deploy-web # ouvrir l'adresse affichée, puis /bench.html ; Ctrl+C pour arrêter ``` ## Hors périmètre - Les mesures sur le Fairphone 4 : séance avec Pierre, guidée par `docs/guide-test-etape-0.md`. - La décision du socle (PWA ou Android natif) : un ADR, après les mesures et avec la validation de Pierre. - Le plateau jouable : étape 0d. Generated with Claude Code https://claude.com/claude-code
pierre added 6 commits 2026-11-02 18:24:14 +00:00
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Le moteur et engine-cli sont compilés avec Emscripten (image figée
emscripten/emsdk:3.1.64), en C générique, sans threads ; les données
de build/data/ sont incluses dans engine.data. Le JavaScript appelle
engine_init une fois puis main pour chaque commande : la sortie est le
JSON d'engine-cli, sans code de mise en forme dupliqué.

tests/test_wasm_reference.sh rejoue les 32 positions de référence sous
Node avec le même comparateur (option --cli) et la même tolérance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
web/ : le moteur tourne dans un Web Worker (module ES) ; la page de
test donne le meilleur coup d'une position et son temps de calcul ;
la page de mesure chronomètre les positions de référence, mesure la
taille téléchargée et la mémoire, compare aux seuils de l'étape 0b et
produit un rapport à copier. make bench fait la même mesure sous Node,
make deploy-web sert les pages sur le réseau local. Guide de test pour
le Fairphone 4 dans docs/guide-test-etape-0.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pierre merged commit 14d1186e84 into main 2026-11-02 18:24:15 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: pierre/Ustagammon#9