pub struct MmapProverIndex<const FULL_ROUNDS: usize, G: KimchiCurve<FULL_ROUNDS>, Srs> {
index: ManuallyDrop<ProverIndex<FULL_ROUNDS, G, Srs>>,
_mmap: Arc<ReadOnlyMmap>,
}Expand description
A ProverIndex whose large Vec<F> fields are backed by memory in a
live mmap(2) region instead of owned heap allocations.
The wrapper [Deref]s to ProverIndex, so anywhere the existing prover
takes &ProverIndex (e.g. ProverProof::create) it transparently
accepts an MmapProverIndex as well. The file pages can be evicted by
the kernel under memory pressure and re-faulted on demand.
§Lifetime and drop
The inner ProverIndex is stored in a [ManuallyDrop] because its
Vec<F> fields (sid; every Evaluations.evals; lookup data when
present) are constructed via Vec::from_raw_parts(mmap_ptr, len, len)
and point into the mapping. Running Vec::drop on them would call
dealloc on mmap memory, which is undefined behaviour.
Consequently, when MmapProverIndex is dropped, the inner
ProverIndex’s owned sub-allocations (the owned gates vector,
linearization, powers_of_alpha, and any LazyCache/Arc machinery)
leak. This notably includes the Arc<Srs> strong count: it is never
decremented, so the SRS is never freed for the life of the process even
if the caller drops its own clone. The lazily-recomputed
precomputations (the d4/d8 DomainConstantEvaluations, tens of MB) are
likewise owned heap allocations that leak and are not reclaimed by
munmap. This is acceptable for Mina’s usage pattern — proving keys are
loaded once at daemon startup and held for the life of the process, so
cumulative leakage is bounded and the OS reclaims everything on exit. The
Arc<ReadOnlyMmap> held alongside is dropped normally, which calls
munmap and releases the mmap-backed field arrays (the bulk of the
on-disk key), but not the recomputed/owned allocations above.
A future refinement could replace the bulk leak with a manual per-
field tear-down: pattern-destructure the ProverIndex, drop the
owned fields explicitly, and mem::forget only the mmap-backed
Vecs. That’s about 50 lines of unsafe and can be added without
affecting the on-disk format or the public API.
Fields§
§index: ManuallyDrop<ProverIndex<FULL_ROUNDS, G, Srs>>§_mmap: Arc<ReadOnlyMmap>Implementations§
Source§impl<const FULL_ROUNDS: usize, G, Srs> MmapProverIndex<FULL_ROUNDS, G, Srs>where
G: KimchiCurve<FULL_ROUNDS>,
impl<const FULL_ROUNDS: usize, G, Srs> MmapProverIndex<FULL_ROUNDS, G, Srs>where
G: KimchiCurve<FULL_ROUNDS>,
Sourcepub fn madvise_dontneed(&self)
pub fn madvise_dontneed(&self)
Advise the kernel that the mapped cache file’s pages are no longer
needed (MADV_DONTNEED). Reads into the mapping after this call
will trigger fresh page faults that re-populate from disk.
This simulates the real-world behaviour the zero-copy cache was
designed for — pages evicted under memory pressure are silently
re-faulted as the prover walks back through them. Used in tests
(see cached_index_prove_after_madv_dontneed) to confirm that the
construction doesn’t somehow keep the data pinned in RAM via a
stray owned copy.
No-op on a zero-length mapping.
Methods from Deref<Target = ProverIndex<FULL_ROUNDS, G, Srs>>§
Sourcepub fn verify(
&self,
witness: &[Vec<F>; 15],
public: &[F],
) -> Result<(), GateError>
pub fn verify( &self, witness: &[Vec<F>; 15], public: &[F], ) -> Result<(), GateError>
This function verifies the consistency of the wire assignments (witness) against the constraints
Sourcepub fn perm_quot(
&self,
lagrange: &WitnessOverDomains<F>,
beta: F,
gamma: F,
z: &DensePolynomial<F>,
alphas: impl Iterator<Item = F>,
) -> Result<(Evaluations<F, D<F>>, DensePolynomial<F>), ProverError>
pub fn perm_quot( &self, lagrange: &WitnessOverDomains<F>, beta: F, gamma: F, z: &DensePolynomial<F>, alphas: impl Iterator<Item = F>, ) -> Result<(Evaluations<F, D<F>>, DensePolynomial<F>), ProverError>
Sourcepub fn perm_lnrz(
&self,
e: &ProofEvaluations<PointEvaluations<F>>,
zeta: F,
beta: F,
gamma: F,
alphas: impl Iterator<Item = F>,
) -> Evaluations<F, D<F>>
pub fn perm_lnrz( &self, e: &ProofEvaluations<PointEvaluations<F>>, zeta: F, beta: F, gamma: F, alphas: impl Iterator<Item = F>, ) -> Evaluations<F, D<F>>
permutation linearization poly contribution computation
Sourcepub fn perm_aggreg(
&self,
witness: &[Vec<F>; 15],
beta: &F,
gamma: &F,
rng: &mut (impl RngCore + CryptoRng),
) -> Result<DensePolynomial<F>, ProverError>
pub fn perm_aggreg( &self, witness: &[Vec<F>; 15], beta: &F, gamma: &F, rng: &mut (impl RngCore + CryptoRng), ) -> Result<DensePolynomial<F>, ProverError>
Sourcepub fn verifier_index_digest<EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField, FULL_ROUNDS>>(
&self,
) -> G::BaseFieldwhere
VerifierIndex<FULL_ROUNDS, G, Srs>: Clone,
pub fn verifier_index_digest<EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField, FULL_ROUNDS>>(
&self,
) -> G::BaseFieldwhere
VerifierIndex<FULL_ROUNDS, G, Srs>: Clone,
Retrieve or compute the digest for the corresponding verifier index.
Sourcepub fn verifier_index(&self) -> VerifierIndex<FULL_ROUNDS, G, Srs>where
VerifierIndex<FULL_ROUNDS, G, Srs>: Clone,
pub fn verifier_index(&self) -> VerifierIndex<FULL_ROUNDS, G, Srs>where
VerifierIndex<FULL_ROUNDS, G, Srs>: Clone,
Produces the VerifierIndex from the prover’s ProverIndex.
§Panics
Will panic if srs cannot be in cell.