8.6 KiB
Geometric Verification
Scope
Geometric Verification Model est le contrat persistant placé après le Matcher.
Sa représentation stocke les identités scientifiques Geometric Verifier v1/v2
historiques et v3 courantes, sans changement de schéma : verifier_version et
parameter_fingerprint appartiennent déjà à l'identité exacte. Il stocke un
résultat terminé, compact et immutable. Il n'est ni un moteur de calcul ni une
tâche.
Aucun RANSAC, USAC, MAGSAC, calcul d'inliers ou backend géométrique n'appartient à ce ticket.
Position in reconstruction pipeline
La chaîne d'ownership est :
Feature Set → Candidate Pair → Match Result → Geometric Verification Result
Le masque indexe exclusivement l'ordre des entrées du Match File canonique du Match Result. Il n'indexe directement ni les features, ni la Candidate Pair, ni un ordre temporaire de backend.
Scientific ownership
Le parent scientifique est match_result_id. L'API accepte uniquement un Match Result existant,
MATCHED, avec match_count strictement positif. NO_MATCH et les erreurs runtime ne peuvent pas
produire de résultat géométrique.
Parent Match Result
Le Match Store reste propriétaire de la validation du Match File. La création consulte le parent
et son match_count en DB ; elle ne relit pas l'asset. Un load valide aussi l'existence et l'état du
parent afin qu'une ligne corrompue ne soit jamais rendue comme résultat valide.
Persistent identity
L'identité demandée et unique est :
(match_result_id, verifier_kind, verifier_version, parameter_fingerprint)
Le fingerprint est le SHA-256 opaque de 32 octets déjà standard dans le projet. Il représentera un encodage de paramètres versionné, stable, à ordre de champs explicite et, pour les nombres binaires, little-endian. Aucun timestamp, résultat, PID, durée ou identifiant matériel n'y entre.
Verifier kind
Le modèle supporte uniquement FUNDAMENTAL, valeur persistante stable 1. Aucun comportement fictif
ESSENTIAL ou HOMOGRAPHY n'est réservé dans l'API publique.
Persistent states
GEOMETRIC_REJECTED=1: calcul scientifique terminé, critère non satisfait ;GEOMETRIC_VERIFIED=2: calcul scientifique terminé, critère satisfait.
FAILED, RUNNING, PAUSED et CANCELLED appartiennent au Task Runtime. REJECTED peut conserver
un nombre d'inliers non nul.
Model representation
FUNDAMENTAL utilise neuf colonnes SQLite REAL, en ordre ligne-major m00 à m22. SQLite
convertit les valeurs numériques en binary64 sans exposer une ABI C. VERIFIED exige les neuf
valeurs présentes et finies. REJECTED exige les neuf valeurs NULL. Le modèle n'impose ni rang 2,
ni déterminant, ni normalisation ou échelle canonique ; ces règles relèvent du futur verifier.
Inlier representation
Le masque est un BLOB SQLite obligatoire de taille exacte ceil(match_count / 8). Pour l'entrée
i, byte_index=i/8, bit_index=i%8 et le masque vaut 1u << bit_index. Le bit 0 est donc le bit
de poids faible de l'octet 0. Cette convention est indépendante de l'endianness CPU et de l'ABI.
Les bits de padding du dernier octet valent zéro et le popcount est exactement inlier_count.
Le masque existe pour REJECTED comme pour VERIFIED. Avec 8192 matches, il mesure au maximum
1024 octets. Un BLOB SQLite évite les milliers de lignes secondaires et la publication, le hash,
le nettoyage et la récupération d'un asset externe d'environ 1 Kio. Une liste uint32_t serait
jusqu'à 32 fois plus grande au cas dense et aurait un encodage supplémentaire à versionner.
Invariants
0 <= inlier_count <= parent.match_count <= 8192;- longueur, padding et popcount du masque sont canoniques ;
- REJECTED possède un masque cohérent et aucun modèle ;
- VERIFIED possède un masque cohérent et exactement neuf valeurs finies ;
- kind, version et fingerprint ont une sérialisation stable ;
- une ligne publiée est complète et immutable.
Exemple : pour 100 matches, une identité FUNDAMENTAL v1, v2 ou v3/fingerprint X peut publier REJECTED avec 23 inliers, un masque de 13 octets et aucun modèle. Une autre identité peut publier VERIFIED avec 67 inliers, le même format de masque et une matrice 3×3 finie.
Persistence semantics
Une création valide puis insère identité, état, masque et modèle dans une transaction courte. Le calcul futur se fera entièrement avant cette transaction. SQLite fournit l'atomicité ; aucun asset ou journal secondaire n'est créé.
Reuse
Le reuse cherche uniquement l'identité exacte, jamais le résultat le plus récent. Une identité
existante retourne une erreur de contrainte à create; le runtime fera find, validera puis
réutilisera. INSERT OR REPLACE est interdit, même si le nouveau contenu semble identique.
Invalidations
Un nouveau Match Result possède un nouvel ID et ne réutilise donc aucun ancien résultat
géométrique. La FK emploie ON DELETE CASCADE : supprimer explicitement le parent supprime ses
enfants et ne crée pas d'orphelin. Aucun moteur d'invalidation parallèle n'est nécessaire.
Project DB schema
Project DB v12 ajoute geometric_verification_results, une contrainte UNIQUE sur l'identité et un
index de pagination (match_result_id, geometric_verification_result_id). Les CHECK SQL portent
les bornes scalaires, tailles locales et nullabilité modèle/état. La cohérence avec le parent, le
padding, le popcount et la finitude restent validés en C.
API
L'API publique implémente :
lardon3d_project_db_create_geometric_verification_result();lardon3d_project_db_load_geometric_verification_result();lardon3d_project_db_find_geometric_verification_result();lardon3d_project_db_list_geometric_verification_results().
La liste est bornée à 256 entrées, filtrée par parent puis ordonnée par ID croissant avec curseur.
Le résultat en mémoire contient son created_at et son masque dans une capacité fixe de 1024
octets : aucun ownership dynamique ni fonction de destruction. Les fonctions copient fingerprint,
masque et neuf coefficients ; l'appelant conserve ses entrées.
Parent absent retourne NOT_FOUND; parent NO_MATCH ou parent incohérent retourne CONSTRAINT à
la création. Masque, modèle ou arguments locaux invalides retournent INVALID_ARGUMENT; duplicate
identity retourne CONSTRAINT. Un loader qui rencontre une ligne ou un parent incohérent retourne
CORRUPT, sans résultat partiel.
Resource bounds
Un résultat contient au plus 1024 octets de masque et 72 octets de valeurs numériques, plus de petites métadonnées. Une page est bornée. Le loader vérifie les entiers et tailles SQLite avant tout cast ou copie. Il n'existe ni cache global, ni lecture non bornée, ni Content Store associé. Le Match File parent mesure au plus 98 336 octets ; le futur job peut donc rester une petite unité.
Error ownership
Seuls les résultats scientifiques terminés sont persistés. OOM, exception, annulation, timeout, device lost, I/O transitoire ou panne de thread appartiennent à l'exécution de tâche. État du modèle et état d'exécution sont deux contrats distincts.
Recovery semantics
Après commit, le résultat est complet et réutilisable après réouverture. Avant commit, le rollback ne laisse aucune ligne partielle. Un loader rejette toute ligne incohérente comme corruption au lieu de réparer ou d'interpréter au mieux.
Verifier execution contract
L'exécution prend un Match Result et son Match File borné. L'accès nécessaire existe via
lardon3d_feature_reader_keypoints(), borné à 256 keypoints par appel ; l'intégration devra relier
les deux Feature Sets et les indices du Match File sans modifier le Feature Store. Le verifier
estimera hors transaction, dérivera état/masque/modèle, publiera en une courte transaction,
checkpoint puis libérera les buffers. Une paire est l'unité atomique. Task Runtime et Resource
Governor décideront admission, threads et lots ; zram/swap ne sont jamais un budget.
Un backend reste hors identité seulement s'il est scientifiquement transparent. Sinon son algorithme ou contrat doit apparaître dans kind/version/fingerprint avant publication. Toute seed influençant le résultat doit avoir une politique déterministe versionnée ou être couverte par le fingerprint. Aucun nombre de threads ou hardware ID n'est un paramètre scientifique par défaut.
Explicitly out of scope
GPU, Vulkan, OpenCL, shader et nouvelle orchestration restent hors périmètre de ce contrat de persistance.
Versioning
Project DB schema version 12 décrit le stockage. verifier_version décrit indépendamment le
contrat scientifique. Changer un algorithme n'impose une migration DB que si la représentation
persistante change.