#pragma once #include #include // ── ISimilarityEngine ───────────────────────────────────────────────────────── // Backend-agnostic gallery similarity engine for the identity matcher. // // The full reference gallery (n_gallery × 512 L2-normalised embeddings) is // uploaded to the GPU once at construction and stays resident. Per frame, the // small query matrix (n_faces × 512) is uploaded and a single SGEMM produces the // similarity matrix S (n_gallery × n_faces, column-major) — i.e. S[g + f*n_gal] // is cosine_similarity(gallery[g], query[f]). // // The GPU math backend (cuBLAS/CUDA or rocBLAS/HIP) is selected at compile time // by CMake (SAE_GEMM_BACKEND); backends/gemm_backend.cpp provides // make_similarity_engine(). The core matcher node sees only this interface and // holds no CUDA/HIP/BLAS headers. struct ISimilarityEngine { virtual ~ISimilarityEngine() = default; // Largest n_faces accepted by compute() per call (bounds GPU buffer sizes). virtual int max_faces() const = 0; // Compute similarities for n_faces query embeddings. // query_row_major: n_faces × 512, row fi at query + fi*512. // Returns a pointer to host memory holding S column-major: the gallery // similarities for face fi start at result + fi*n_gallery. The pointer is // owned by the engine and valid until the next compute() call. virtual const float* compute(const float* query_row_major, int n_faces) = 0; }; // gallery_row_major: n_gallery × 512, embedding i at gallery + i*512. std::unique_ptr make_similarity_engine( const float* gallery_row_major, int n_gallery, int max_faces);