Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f18b848
build: pin Jolt to a16z/jolt main e1d8e02b5
Acentelles Oct 29, 2026
fefb5d0
perf(challenges): use signed accumulation for sparse evaluation
Acentelles Oct 23, 2026
af458fb
feat(challenges): static operator-norm base tables behind ont-static-…
Acentelles Oct 26, 2026
bbedf38
perf(verifier): evaluate the compression relation weights by factor
Acentelles Oct 23, 2026
0dabcd6
test(verifier): cross-check factored compression weights against per-…
Acentelles Oct 23, 2026
dd987aa
test(verifier): name the cross-check event-sum type
Acentelles Oct 23, 2026
7693561
Batch reduced setup rows sharing one functional
Acentelles Oct 23, 2026
3fe67f7
test(setup-contribution): import Ring for from_u64 in the reduced sha…
Acentelles Oct 24, 2026
3647784
Add optional no-carry tensor contractions
Acentelles Oct 26, 2026
7721c4c
Add optional tensor equality run accumulation
Acentelles Oct 27, 2026
1ad19b9
Use power-of-two run shifts and test Fp128 boundaries
Acentelles Oct 27, 2026
a2b83d9
Add optional line-preserving sums of products at the structured setup…
Acentelles Oct 27, 2026
eb2ab64
test(pcs): pass the witness chunking to the cross-check roundtrips
Acentelles Oct 28, 2026
4f781ad
build: regenerate the lockfiles for the Jolt pin
Acentelles Oct 29, 2026
6c25733
build: pin Jolt to a16z/jolt main 4e55c9a5
Acentelles Oct 30, 2026
11ad417
Merge main into perf/verifier-recursion-levers
Acentelles Oct 30, 2026
abd7131
Pin Jolt to main
Acentelles Oct 30, 2026
a3aceff
build: resolve lockfiles after merging main
Acentelles Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions book/src/usage/feature-flags.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,19 @@ paths; every other target keeps the portable path.
| --- | --- |
| `logging-transcript` | Records transcript schedule events and checks that wire values are absorbed before challenges |
| `response-model-diagnostics` | Measures complete source and response energies for planner model calibration |
| `compression-weights-crosscheck` | Checks every factored compression relation weight evaluation against the per-event evaluation and counts its evaluation tiers |

`response-model-diagnostics` scans witness data that normal proving does not
scan. Use it for model calibration runs, not for ordinary performance numbers.

`compression-weights-crosscheck` (on `akita-types`, forwarded by `akita-pcs`)
evaluates every compression relation weight table both by factor and event by
event, at the verifier's point and at seeded random points, and compares each
grouped builder family with the per-event builder. A difference fails
verification. Each evaluation emits one `tracing` event at `INFO` with its
evaluation tiers and builder outcomes. It is for native diagnostic runs; it
changes no proof, transcript or default build.

The `transcript_schedule` example uses `logging-transcript`:

```bash
Expand Down
9 changes: 5 additions & 4 deletions crates/akita-algebra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ repository = "https://github.com/LayerZero-Labs/akita"
readme = "../../README.md"

[dependencies]
jolt-inlines-ntt = { version = "=0.1.0", git = "https://github.com/a16z/jolt", rev = "83fcab4937c492615b068dc852ad848c3b20cde0", default-features = false, optional = true }
jolt-inlines-ntt = { version = "=0.1.0", git = "https://github.com/a16z/jolt", rev = "718921695296180005c2bf028451f730886561bb", default-features = false, optional = true }
akita-error = { version = "0.1.0", path = "../akita-error" }
jolt-field = { version = "=0.1.0", git = "https://github.com/a16z/jolt", rev = "83fcab4937c492615b068dc852ad848c3b20cde0", default-features = false, features = [
jolt-field = { version = "=0.1.0", git = "https://github.com/a16z/jolt", rev = "718921695296180005c2bf028451f730886561bb", default-features = false, features = [
"asm",
"solinas",
] }
jolt-poly = { version = "=0.1.0", git = "https://github.com/a16z/jolt", rev = "83fcab4937c492615b068dc852ad848c3b20cde0", default-features = false }
jolt-poly = { version = "=0.1.0", git = "https://github.com/a16z/jolt", rev = "718921695296180005c2bf028451f730886561bb", default-features = false }
akita-serialization = { version = "0.1.0", path = "../akita-serialization" }
rand_core = { version = "0.6", features = ["getrandom"] }
rayon = { version = "1.10", optional = true }
Expand All @@ -37,6 +37,7 @@ harness = false
ntt-inline = ["dep:jolt-inlines-ntt"]
default = []
parallel = ["dep:rayon", "jolt-field/parallel"]

tensor-no-carry = []
tensor-eq-runs = []
[lints]
workspace = true
35 changes: 35 additions & 0 deletions crates/akita-algebra/src/offset_eq/tensor_pair/materialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ pub(in crate::offset_eq) struct DenseLeftTensorView<'a, F: Field> {
pub(in crate::offset_eq) residual: ResidualTerms<F>,
}

#[cfg(feature = "tensor-no-carry")]
mod separate;

impl<F: Field> DenseLeftTensorView<'_, F> {
/// Number of nonzero-weight residual terms. Each axis count is at most
/// its validated `len`, so this never exceeds the checked coordinate
Expand Down Expand Up @@ -443,8 +446,18 @@ impl<'a, F: Field> DenseLeftOverlap<'a, F> {
equality: &OffsetEqWindow<F>,
output_len: usize,
) -> Result<Vec<F>, AkitaError> {
#[cfg(feature = "tensor-no-carry")]
let separated = self
.views
.iter()
.map(|view| separate::SeparatedResidual::prepare(view, equality))
.collect::<Result<Vec<_>, AkitaError>>()?;
let evaluate_coordinate = |(coordinate, destination): (usize, &mut F)| {
#[cfg(feature = "tensor-no-carry")]
let mut separated_views = separated.iter();
for view in &self.views {
#[cfg(feature = "tensor-no-carry")]
let prepared = separated_views.next().and_then(Option::as_ref);
if view.family.scalar.is_zero() {
continue;
}
Expand All @@ -457,6 +470,17 @@ impl<'a, F: Field> DenseLeftOverlap<'a, F> {
coordinate,
"right",
)?;
#[cfg(feature = "tensor-no-carry")]
if let Some(prepared) = prepared {
let value = prepared.evaluate(equality, right_offset)?;
let scalar = view.family.scalar;
*destination += if scalar == F::one() {
value
} else {
scalar * value
};
continue;
}
*destination += view.evaluate_residual(equality, right_offset)?;
}
Ok::<_, AkitaError>(())
Expand All @@ -465,6 +489,14 @@ impl<'a, F: Field> DenseLeftOverlap<'a, F> {
let destination = output.get_mut(self.destination.clone()).ok_or_else(|| {
AkitaError::Internal("validated tensor destination span exceeds the output".into())
})?;
#[cfg(all(feature = "tensor-eq-runs", feature = "tensor-no-carry"))]
let runs_declined = separated.iter().any(Option::is_some);
#[cfg(all(feature = "tensor-eq-runs", not(feature = "tensor-no-carry")))]
let runs_declined = false;
#[cfg(feature = "tensor-eq-runs")]
if runs::try_accumulate(equality, &self.views, runs_declined, destination)? {
return Ok(output);
}
// Tuned with `benches/offset_eq_window.rs::bench_materialize_disjoint_intervals`
// on an Apple M4 Max (16 cores, 64 GiB).
const PARALLEL_THRESHOLD: usize = 1 << 14;
Expand Down Expand Up @@ -542,3 +574,6 @@ fn visit_tensor_coordinates<F: Field>(
}
Ok(())
}

#[cfg(feature = "tensor-eq-runs")]
mod runs;
130 changes: 130 additions & 0 deletions crates/akita-algebra/src/offset_eq/tensor_pair/materialize/runs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
use super::{DenseLeftTensorView, ResidualTerms};
use crate::offset_eq::OffsetEqWindow;
use crate::Field;
use akita_error::AkitaError;

/// Reorder the residual-by-coordinate sum into runs within one low table.
/// The high factor and residual coefficient are constant within each run.
/// Carries end a run; no inversion or nonzero challenge assumption is used.
pub(super) fn try_accumulate<F: Field>(
equality: &OffsetEqWindow<F>,
views: &[DenseLeftTensorView<'_, F>],
separated: bool,
destination: &mut [F],
) -> Result<bool, AkitaError> {
let Some(high_values) = &equality.eq_high else {
return Ok(false);
};
if destination.len() < 16 {
return Ok(false);
}
// Finish admission before writing anything, so declining is transactional.
// A view that takes the no-carry separated path keeps that dispatch.
if separated {
return Ok(false);
}
for view in views {
// Runs need the tabulated residual; a streamed residual declines.
let ResidualTerms::Table(residual) = &view.residual else {
return Ok(false);
};
let axis =
view.family.axes.get(view.destination_axis).ok_or_else(|| {
AkitaError::Internal("tensor run destination axis is absent".into())
})?;
if !axis.right_stride.is_power_of_two()
|| axis.right_stride > equality.eq_low.len() / 8
|| axis.len != destination.len()
{
return Ok(false);
}
let span = axis
.right_stride
.checked_mul(axis.len - 1)
.ok_or_else(|| AkitaError::InvalidInput("tensor run right span overflow".into()))?;
let last =
view.family.right_offset.checked_add(span).ok_or_else(|| {
AkitaError::InvalidInput("tensor run right offset overflow".into())
})?;
if !view.family.scalar.is_zero() {
for &(offset, _) in residual {
last.checked_add(offset).ok_or_else(|| {
AkitaError::InvalidInput("tensor run residual offset overflow".into())
})?;
}
}
}
for view in views {
if view.family.scalar.is_zero() {
continue;
}
let axis = view.family.axes.get(view.destination_axis).ok_or_else(|| {
AkitaError::Internal("validated tensor run destination axis is absent".into())
})?;
let stride_bits = axis.right_stride.trailing_zeros();
let ResidualTerms::Table(residual) = &view.residual else {
return Err(AkitaError::Internal(
"validated tensor run residual is not tabulated".into(),
));
};
for &(offset, weight) in residual {
let coefficient = if view.family.scalar == F::one() {
weight
} else {
view.family.scalar * weight
};
let mut index = view
.family
.right_offset
.checked_add(offset)
.ok_or_else(|| {
AkitaError::Internal("validated tensor run offset overflow".into())
})?;
let mut remaining = &mut destination[..];
while !remaining.is_empty() {
let low = index & equality.low_mask;
let high = index >> equality.low_bits;
let Some(&high_value) = high_values.get(high) else {
// Monotone physical addresses cannot reenter the domain.
break;
};
let available = ((equality.low_mask - low) >> stride_bits) + 1;
let take = available.min(remaining.len());
let (run, tail) = remaining.split_at_mut_checked(take).ok_or_else(|| {
AkitaError::Internal("validated tensor run split exceeds output".into())
})?;
let scale = if coefficient == F::one() {
high_value
} else {
coefficient * high_value
};
if !scale.is_zero() {
let low_values = equality.eq_low.get(low..).ok_or_else(|| {
AkitaError::Internal("tensor run low index exceeds table".into())
})?;
for (value, &low_value) in run
.iter_mut()
.zip(low_values.iter().step_by(axis.right_stride))
{
*value += low_value * scale;
}
}
if tail.is_empty() {
break;
}
index = axis
.right_stride
.checked_mul(take)
.and_then(|span| index.checked_add(span))
.ok_or_else(|| {
AkitaError::Internal("validated tensor run advance overflow".into())
})?;
remaining = tail;
}
}
}
Ok(true)
}

#[cfg(test)]
mod tests;
Loading
Loading