# Exécution, familles et shards

> Un seul hart, une horloge de 38 bits, chaque accès mémoire sous forme de requête horodatée, 23 familles de circuits, et le shard comme unité de preuve.

## La machine

L’émulateur exécute RV32IMAC sur un seul hart à partir d’une `ProgramImage`, sans interruptions ni niveaux de privilège. Une exécution est une fonction pure de l’image et de son entrée, sans horloge, sans aléa ni fils d’exécution : deux exécutions découpent donc des shards identiques. Il diffère d’un RV32IMAC hébergé en trois points : `sc.w` réussit toujours, un accès non aligné à un demi-mot ou à un mot est fatal au lieu d’être scindé, et le flux d’instructions est l’image décodée au chargement.

Toute autre façon dont une exécution peut s’arrêter avant `EXIT`, comme un accès hors des régions projetées, `ebreak` ou un saut vers un demi-mot sans instruction, est une erreur fatale qui ne produit aucune trace. Une telle exécution n’a pas de preuve. Un statut de sortie non nul n’est pas une erreur : c’est une exécution comme une autre, et elle est prouvable.

## L’horloge et la requête

Le cycle `c` occupe les quatre horodatages `4c + Δ`, un par **créneau** `Δ ∈ {0, 1, 2, 3}`. Chaque instruction est un cycle, et rien d’autre n’en est un : une invocation de délégation emprunte le cycle qui l’a demandée. Les cycles sont numérotés à partir de 1, parce que l’horodatage 0 est l’écriture initiale de chaque adresse. L’horloge fait 38 bits : une exécution compte donc au plus `2^36 − 1` cycles.

Chaque accès mémoire est une **requête** : la lecture d’une valeur écrite pour la dernière fois à un horodatage antérieur, et une écriture à l’horodatage courant. Une requête qui ne fait que lire réécrit ce qu’elle a lu. Le créneau 0 de chaque cycle est la requête du pc, qui lit `pc` et écrit `next_pc`. Viennent ensuite les requêtes de registres et de mémoire de l’instruction, à des créneaux fixes :

| Classe | Δ = 1 | Δ = 2 | Δ = 3 |
| --- | --- | --- | --- |
| registre-immédiat, `jalr` | `rs1` | | `rd` |
| branchements | `rs1` | `rs2` | |
| registre-registre, M | `rs1` | `rs2` | `rd` |
| chargements | `rs1` | le mot, lu | `rd` |
| rangements | `rs1` | `rs2` | le mot, avec les octets rangés fusionnés |
| atomiques | `rs1` | `rs2` | le mot, et `rd` |
| `ecall` | `a7` | `a0` | `a0`, et la requête miroir d’une délégation |

Les adresses résident dans des **espaces** : les 32 registres, la RAM par mots alignés sur 4 octets, le pc, un espace d’ancrage par type de délégation, et les cellules de corps du format de récursion. `x0` est un registre ordinaire dans la trace et une constante dans la machine : chaque requête qui le vise lit et écrit 0.

## Vingt-trois familles

Une **famille** est un circuit et les lignes qu’il prouve. Il en existe quatre catégories :

| Catégorie | Familles | Une ligne est |
| --- | --- | --- |
| Exécution | 0–6 : `ADD_SUB_LUI_AUIPC`, `JUMP_BRANCH_SLT`, `SHIFT_BITWISE`, `MUL_DIV`, `MEM_WORD`, `MEM_SUBWORD`, `ATOMICS` | une instruction exécutée |
| Fenêtre | 7 `INIT_TEARDOWN`, 8 `ZERO_WINDOWS`, 12 `PUBLIC_INPUT`, 13 `PUBLIC_OUTPUT`, 14 `ADVICE_WINDOWS` | un mot mémoire, initialisé puis finalisé |
| Délégation | 9 `KECCAK_F`, 10 `POSEIDON2`, 11 `FR_ARITH`, 15 `MOD_MUL`, 16 `SHA256_COMP`, 17 `EC_ADD` | une invocation sur un cadre de RAM |
| Récursion | 18 `FIELD_WINDOWS`, 19 `FR_OP`, 20 `P2_FIELD`, 21 `FIELD_IO`, 22 `FQ_OP` | une cellule de corps, ou une opération de coprocesseur |

Chaque cycle va à l’unique famille d’exécution dont la table décodée revendique son pc. Les familles s’entrelacent dans le temps : `ADD_SUB_LUI_AUIPC` peut posséder les cycles 1 et 3, et `JUMP_BRANCH_SLT` le cycle 2. Rien n’exige qu’elles soient contiguës, parce que l’argument de mémoire ordonne chaque ligne par son écriture du pc.

Les familles de fenêtres existent parce que l’argument de mémoire exige que chaque adresse que touche une exécution ait exactement une valeur initiale et une valeur finale. `INIT_TEARDOWN` couvre la fenêtre de RAM 0 et l’initialise avec l’image du programme; `ZERO_WINDOWS` couvre toutes les autres fenêtres de RAM ordinaire que l’exécution a touchées et les initialise à zéro; la paire publique couvre les fenêtres d’entrée et du journal; `ADVICE_WINDOWS` couvre la région des données auxiliaires (*advice*), qu’elle initialise avec les octets du prouveur.

## Shards

Les lignes d’une famille, dans leur ordre d’apparition, sont découpées en **shards** de la hauteur de la famille. Le dernier est complété par des lignes nulles, que les circuits sont construits pour accepter. Un shard coûte sa hauteur complète, quel que soit son taux d’occupation : les familles que touche un programme et les hauteurs qu’il choisit fixent donc le plancher de chaque preuve.

| Famille | Hauteur par défaut | Pourquoi |
| --- | --- | --- |
| Familles d’instructions | `2^22`, `2^20` pour `MUL_DIV` et `ATOMICS` | le plancher de leurs vérifications d’intervalle sur les horodatages est `2^20` |
| Fenêtres de RAM | `2^22` | une seule hauteur de fenêtre partagée, d’au moins `2^16` |
| Entrée publique, journal | `2^12` | fixée : la hauteur place les fenêtres |
| `KECCAK_F`, `SHA256_COMP` | `2^18` | quatre fois les appels de leur plancher `2^16`, pour 2 % de preuve en plus |
| `MOD_MUL`, `EC_ADD` | `2^16` | leur plancher |
| `POSEIDON2`, `FR_ARITH` | `2^8` | aucune table, donc aucun plancher |

Un shard est prouvé isolément, par le circuit de sa famille, sauf pour l’argument de mémoire : le circuit de chaque shard produit en sortie le produit de ses tuples de lecture et celui de ses tuples d’écriture, et le vérificateur rapproche ces produits une seule fois sur l’ensemble des shards de l’énoncé. C’est la seule chose qui relie les shards. Il n’y a ni chaînage du pc d’un shard à l’autre, ni frontière partagée entre voisins.

Aux hauteurs par défaut, la taille d’une preuve de shard va d’environ 12,5 KB pour une fenêtre publique à 665 KB pour un shard `POSEIDON2`; celle d’une famille d’instructions va de 64 à 77 KB. La page [Performances](https://apogee.gweb3networks.com/docs/architecture/performance) en donne le tableau.

La spécification : [Trace d’exécution](https://apogee.gweb3networks.com/docs/auditors/spec/execution-trace), [Circuits et registre](https://apogee.gweb3networks.com/docs/auditors/spec/circuits).
