Skip to content

Commit

Permalink
add tests and benches
Browse files Browse the repository at this point in the history
  • Loading branch information
Hanting Zhang committed Jan 6, 2024
1 parent 9e7a36d commit 9cfc26b
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 145 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ jobs:
with:
command: test

- name: Run msm example
run: cargo run --release --example msm
- name: Run grumpkin_msm example
run: cargo run --release --example grumpkin_msm

- name: Run pasta_msm example
run: cargo run --release --example pasta_msm

- name: Check benches build
run: cargo check --benches
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,9 @@ which = "^4.0"
criterion = { version = "0.3", features = [ "html_reports" ] }

[[bench]]
name = "msm"
name = "grumpkin_msm"
harness = false

[[bench]]
name = "pasta_msm"
harness = false
1 change: 1 addition & 0 deletions benches/msm.rs → benches/grumpkin_msm.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright Supranational LLC
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#![allow(unused_mut)]

use criterion::{criterion_group, criterion_main, Criterion};
use grumpkin_msm::utils::{gen_points, gen_scalars};
Expand Down
66 changes: 66 additions & 0 deletions benches/pasta_msm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright Supranational LLC
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#![allow(unused_mut)]

use criterion::{criterion_group, criterion_main, Criterion};
use grumpkin_msm::pasta::utils::{gen_points, gen_scalars};

#[cfg(feature = "cuda")]
use grumpkin_msm::cuda_available;

fn criterion_benchmark(c: &mut Criterion) {
let bench_npow: usize = std::env::var("BENCH_NPOW")
.unwrap_or("17".to_string())
.parse()
.unwrap();
let npoints: usize = 1 << bench_npow;

// println!("generating {} random points, just hang on...", npoints);
let mut points = gen_points(npoints);
let mut scalars = gen_scalars(npoints);

#[cfg(feature = "cuda")]
{
unsafe { grumpkin_msm::CUDA_OFF = true };
}

let mut group = c.benchmark_group("CPU");
group.sample_size(10);

group.bench_function(format!("2**{} points", bench_npow), |b| {
b.iter(|| {
let _ = grumpkin_msm::pasta::pallas(&points, &scalars);
})
});

group.finish();

#[cfg(feature = "cuda")]
if unsafe { cuda_available() } {
unsafe { grumpkin_msm::CUDA_OFF = false };

const EXTRA: usize = 5;
let bench_npow = bench_npow + EXTRA;
let npoints: usize = 1 << bench_npow;

while points.len() < npoints {
points.append(&mut points.clone());
}
scalars.append(&mut gen_scalars(npoints - scalars.len()));

let mut group = c.benchmark_group("GPU");
group.sample_size(20);

group.bench_function(format!("2**{} points", bench_npow), |b| {
b.iter(|| {
let _ = grumpkin_msm::pasta::pallas(&points, &scalars);
})
});

group.finish();
}
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
128 changes: 3 additions & 125 deletions examples/pasta_msm.rs
Original file line number Diff line number Diff line change
@@ -1,132 +1,10 @@
use std::{
cell::UnsafeCell,
mem::transmute,
sync::atomic::{AtomicUsize, Ordering},
};

#[cfg(feature = "cuda")]
use grumpkin_msm::cuda_available;

use pasta_curves::{
arithmetic::CurveExt,
group::{ff::Field, Curve},
pallas,
use grumpkin_msm::pasta::utils::{
gen_points, gen_scalars, naive_multiscalar_mul,
};
use rand::{RngCore, SeedableRng};
use rand_chacha::ChaCha20Rng;

pub fn gen_points(npoints: usize) -> Vec<pallas::Affine> {
let mut ret: Vec<pallas::Affine> = Vec::with_capacity(npoints);
unsafe { ret.set_len(npoints) };

let mut rnd: Vec<u8> = Vec::with_capacity(32 * npoints);
unsafe { rnd.set_len(32 * npoints) };
ChaCha20Rng::from_entropy().fill_bytes(&mut rnd);

let n_workers = rayon::current_num_threads();
let work = AtomicUsize::new(0);
rayon::scope(|s| {
for _ in 0..n_workers {
s.spawn(|_| {
let hash = pallas::Point::hash_to_curve("foobar");

let mut stride = 1024;
let mut tmp: Vec<pallas::Point> = Vec::with_capacity(stride);
unsafe { tmp.set_len(stride) };

loop {
let work = work.fetch_add(stride, Ordering::Relaxed);
if work >= npoints {
break;
}
if work + stride > npoints {
stride = npoints - work;
unsafe { tmp.set_len(stride) };
}
for i in 0..stride {
let off = (work + i) * 32;
tmp[i] = hash(&rnd[off..off + 32]);
}
#[allow(mutable_transmutes)]
pallas::Point::batch_normalize(&tmp, unsafe {
transmute::<&[pallas::Affine], &mut [pallas::Affine]>(
&ret[work..work + stride],
)
});
}
})
}
});

ret
}

fn as_mut<T>(x: &T) -> &mut T {
unsafe { (*(x as *const _ as *mut UnsafeCell<T>)).get_mut() }
}

pub fn gen_scalars(npoints: usize) -> Vec<pallas::Scalar> {
let mut ret: Vec<pallas::Scalar> = Vec::with_capacity(npoints);
unsafe { ret.set_len(npoints) };

let n_workers = rayon::current_num_threads();
let work = AtomicUsize::new(0);

rayon::scope(|s| {
for _ in 0..n_workers {
s.spawn(|_| {
let mut rng = ChaCha20Rng::from_entropy();
loop {
let work = work.fetch_add(1, Ordering::Relaxed);
if work >= npoints {
break;
}
*as_mut(&ret[work]) = pallas::Scalar::random(&mut rng);
}
})
}
});

ret
}

pub fn naive_multiscalar_mul(
points: &[pallas::Affine],
scalars: &[pallas::Scalar],
) -> pallas::Affine {
let n_workers = rayon::current_num_threads();

let mut rets: Vec<pallas::Point> = Vec::with_capacity(n_workers);
unsafe { rets.set_len(n_workers) };

let npoints = points.len();
let work = AtomicUsize::new(0);
let tid = AtomicUsize::new(0);
rayon::scope(|s| {
for _ in 0..n_workers {
s.spawn(|_| {
let mut ret = pallas::Point::default();

loop {
let work = work.fetch_add(1, Ordering::Relaxed);
if work >= npoints {
break;
}
ret += points[work] * scalars[work];
}

*as_mut(&rets[tid.fetch_add(1, Ordering::Relaxed)]) = ret;
})
}
});

let mut ret = pallas::Point::default();
for i in 0..n_workers {
ret += rets[i];
}

ret.to_affine()
}
use pasta_curves::group::Curve;

fn main() {
let bench_npow: usize = std::env::var("BENCH_NPOW")
Expand Down
Loading

0 comments on commit 9cfc26b

Please sign in to comment.