Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3b5d83c
add: benches for bivariate ops and matmul
dvdplm May 6, 2026
c3e724d
add: benches for bivariate ops and matmul
dvdplm May 6, 2026
9e79916
wip: optimizations sweep 1
dvdplm May 6, 2026
dbc2767
wip: aggressive unrolling and removal of ndarray (almost) completely.
dvdplm May 6, 2026
cb554ce
chore: remove aggressive unrolling and reformulate loops for speed.
dvdplm May 7, 2026
2382591
chore: better docs,
dvdplm May 7, 2026
11871c9
chore: update bivariate benches to new api
dvdplm May 7, 2026
3853a18
perf: avoid a few allocations
dvdplm May 7, 2026
d424382
chore: update to new api
dvdplm May 7, 2026
5af9318
chore: dial down the benchmarks to more relevant sizes and cases.
dvdplm May 7, 2026
686044d
Merge branch 'main' into dvdplm/perf/bivariate-optimizations
dvdplm May 7, 2026
0c7b8b4
chore: remove trait, mak`from_secret` the only constructor, remove `D…
dvdplm May 8, 2026
8c6444d
chore: tighter comments&docs
dvdplm May 8, 2026
6f63479
chore: shorter names
dvdplm May 8, 2026
c3e620e
Merge branch 'main' into dvdplm/perf/bivariate-optimizations
dvdplm May 10, 2026
2f889a3
chore: tweak docs a wee bit
dvdplm May 10, 2026
3d87b22
fix: did ToB rename the example we use?
dvdplm May 10, 2026
9839cf0
chore: fix dylint
dvdplm May 10, 2026
a8376f1
Merge branch 'main' into dvdplm/perf/bivariate-optimizations
dvdplm May 11, 2026
e0e8805
Potential fix for pull request finding
dvdplm May 12, 2026
3388bee
Merge branch 'main' into dvdplm/perf/bivariate-optimizations
dvdplm May 12, 2026
4c1acb4
Merge branch 'main' into dvdplm/perf/bivariate-optimizations
dvdplm May 18, 2026
cc9f4e8
Merge branch 'main' into dvdplm/perf/bivariate-optimizations
dvdplm May 20, 2026
448fa4f
Merge branch 'main' into dvdplm/perf/bivariate-optimizations
dvdplm May 21, 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
1 change: 1 addition & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions core/threshold-algebra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ tfhe-versionable.workspace = true
[dev-dependencies]
aes-prng.workspace = true
bc2wrap.workspace = true
criterion.workspace = true
num-traits.workspace = true
paste.workspace = true
proptest.workspace = true
rstest.workspace = true

[[bench]]
name = "bivariate"
harness = false

[features]
default = ["extension_degree_4"]
extension_degree_3 =[]
Expand Down
78 changes: 78 additions & 0 deletions core/threshold-algebra/benches/bivariate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use aes_prng::AesRng;
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use rand::SeedableRng;
use std::hint::black_box;
use threshold_algebra::{
bivariate::BivariatePoly, galois_rings::degree_4::ResiduePolyF4Z128, structure_traits::Sample,
};

const DEGREES: [usize; 3] = [1, 4, 13];

fn bivariate_setup(degree: usize) -> (BivariatePoly<ResiduePolyF4Z128>, ResiduePolyF4Z128) {
let mut rng = AesRng::seed_from_u64(degree as u64);
let secret = ResiduePolyF4Z128::sample(&mut rng);
let point = ResiduePolyF4Z128::sample(&mut rng);
let poly = BivariatePoly::from_secret(&mut rng, secret, degree);
(poly, point)
}

fn bench_bivariate_sampling(c: &mut Criterion) {
let mut group = c.benchmark_group("bivariate/from_secret");

for degree in DEGREES {
group.bench_function(BenchmarkId::from_parameter(degree), |b| {
let mut rng = AesRng::seed_from_u64(degree as u64);
let secret = ResiduePolyF4Z128::sample(&mut rng);
b.iter(|| {
black_box(BivariatePoly::from_secret(
&mut rng,
black_box(secret),
black_box(degree),
))
});
});
}

group.finish();
}

fn bench_bivariate_evaluation(c: &mut Criterion) {
let mut group = c.benchmark_group("bivariate/evaluation");

for degree in DEGREES {
let (poly, point) = bivariate_setup(degree);

group.bench_function(BenchmarkId::new("partial_x", degree), |b| {
b.iter(|| black_box(poly.partial_x_eval(black_box(point))));
});
group.bench_function(BenchmarkId::new("partial_y", degree), |b| {
b.iter(|| black_box(poly.partial_y_eval(black_box(point))));
});
// Baseline: two separate partial evals, mirroring the code before PR 576.
group.bench_function(BenchmarkId::new("partial_x_then_y", degree), |b| {
b.iter(|| {
let p = black_box(point);
(
black_box(poly.partial_x_eval(p)),
black_box(poly.partial_y_eval(p)),
)
});
});
// Fused: the path `DoublePoly::from_bivariate` actually uses.
group.bench_function(BenchmarkId::new("partial_evaluations", degree), |b| {
b.iter(|| black_box(poly.partial_evals(black_box(point))));
});
group.bench_function(BenchmarkId::new("full", degree), |b| {
b.iter(|| black_box(poly.full_eval(black_box(point), black_box(point))));
});
}

group.finish();
}

criterion_group!(
bivariate,
bench_bivariate_sampling,
bench_bivariate_evaluation,
);
criterion_main!(bivariate);
Loading
Loading