This repository has been archived by the owner on Feb 19, 2024. It is now read-only.
forked from supranational/pasta-msm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Hanting Zhang
committed
Dec 2, 2023
1 parent
8a10540
commit e803295
Showing
9 changed files
with
497 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"files.associations": { | ||
"__locale": "cpp", | ||
"ios": "cpp" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright Supranational LLC | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#![allow(dead_code)] | ||
#![allow(unused_imports)] | ||
#![allow(unused_mut)] | ||
#![allow(non_snake_case)] | ||
|
||
use criterion::{criterion_group, criterion_main, Criterion}; | ||
|
||
use pasta_curves::{group::ff::{PrimeField, Field}, pallas}; | ||
use pasta_msm::{self, utils::SparseMatrix, spmvm::{CudaSparseMatrix, sparse_matrix_witness_pallas, CudaWitness}}; | ||
use rand::Rng; | ||
|
||
#[cfg(feature = "cuda")] | ||
extern "C" { | ||
fn cuda_available() -> bool; | ||
} | ||
|
||
pub fn generate_csr<F: PrimeField>( | ||
n: usize, | ||
m: usize, | ||
) -> SparseMatrix<F> { | ||
let mut rng = rand::thread_rng(); | ||
|
||
let mut data = Vec::new(); | ||
let mut col_idx = Vec::new(); | ||
let mut row_ptr = Vec::new(); | ||
row_ptr.push(0); | ||
|
||
for _ in 0..n { | ||
let num_elements = rng.gen_range(5..=10); // Random number of elements between 5 to 10 | ||
for _ in 0..num_elements { | ||
data.push(F::random(&mut rng)); // Random data value | ||
col_idx.push(rng.gen_range(0..m)); // Random column index | ||
} | ||
row_ptr.push(data.len()); // Add the index of the next row start | ||
} | ||
|
||
data.shrink_to_fit(); | ||
col_idx.shrink_to_fit(); | ||
row_ptr.shrink_to_fit(); | ||
|
||
let csr = SparseMatrix { | ||
data, | ||
indices: col_idx, | ||
indptr: row_ptr, | ||
cols: m, | ||
}; | ||
|
||
csr | ||
} | ||
|
||
include!("../src/tests.rs"); | ||
|
||
fn criterion_benchmark(c: &mut Criterion) { | ||
let bench_npow: usize = std::env::var("BENCH_NPOW") | ||
.unwrap_or("17".to_string()) | ||
.parse() | ||
.unwrap(); | ||
let n: usize = 1 << bench_npow; | ||
|
||
println!("generating random matrix and scalars, just hang on..."); | ||
let csr = generate_csr(n, n); | ||
let cuda_csr = | ||
CudaSparseMatrix::new(&csr.data, &csr.indices, &csr.indptr, n, n); | ||
let W = crate::tests::gen_scalars(n - 10); | ||
let U = crate::tests::gen_scalars(9); | ||
let witness = CudaWitness::new(&W, &pallas::Scalar::ONE, &U); | ||
let scalars = [W.clone(), vec![pallas::Scalar::ONE], U.clone()].concat(); | ||
|
||
#[cfg(feature = "cuda")] | ||
{ | ||
unsafe { pasta_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 _ = csr.multiply_vec(&scalars); | ||
}) | ||
}); | ||
|
||
group.finish(); | ||
|
||
#[cfg(feature = "cuda")] | ||
if unsafe { cuda_available() } { | ||
unsafe { pasta_msm::CUDA_OFF = false }; | ||
|
||
let mut group = c.benchmark_group("GPU"); | ||
group.sample_size(20); | ||
|
||
let mut cuda_res = vec![pallas::Scalar::ONE; cuda_csr.num_rows]; | ||
for nthreads in [128, 256, 512, 1024] { | ||
group.bench_function(format!("2**{} points, nthreads={}", bench_npow, nthreads), |b| { | ||
b.iter(|| { | ||
let _ = sparse_matrix_witness_pallas(&cuda_csr, &witness, &mut cuda_res, nthreads); | ||
}) | ||
}); | ||
} | ||
|
||
group.finish(); | ||
} | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,84 @@ | ||
// Copyright Supranational LLC | ||
// Licensed under the Apache License, Version 2.0, see LICENSE for details. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
#![allow(non_snake_case)] | ||
|
||
use std::time::Instant; | ||
|
||
use pasta_curves::group::ff::PrimeField; | ||
use pasta_msm::spmvm::double_pallas; | ||
use pasta_curves::{group::ff::{PrimeField, Field}, pallas}; | ||
use pasta_msm::{ | ||
spmvm::{sparse_matrix_mul_pallas, CudaSparseMatrix, CudaWitness, sparse_matrix_witness_pallas}, | ||
utils::SparseMatrix, | ||
}; | ||
use rand::Rng; | ||
|
||
pub fn generate_scalars<F: PrimeField>( | ||
len: usize, | ||
) -> Vec<F> { | ||
pub fn generate_csr<F: PrimeField>(n: usize, m: usize) -> SparseMatrix<F> { | ||
let mut rng = rand::thread_rng(); | ||
let scalars = (0..len) | ||
.map(|_| F::random(&mut rng)) | ||
.collect::<Vec<_>>(); | ||
|
||
let mut data = Vec::new(); | ||
let mut col_idx = Vec::new(); | ||
let mut row_ptr = Vec::new(); | ||
row_ptr.push(0); | ||
|
||
for _ in 0..n { | ||
let num_elements = rng.gen_range(5..=10); // Random number of elements between 5 to 10 | ||
for _ in 0..num_elements { | ||
data.push(F::random(&mut rng)); // Random data value | ||
col_idx.push(rng.gen_range(0..m)); // Random column index | ||
} | ||
row_ptr.push(data.len()); // Add the index of the next row start | ||
} | ||
|
||
data.shrink_to_fit(); | ||
col_idx.shrink_to_fit(); | ||
row_ptr.shrink_to_fit(); | ||
|
||
let csr = SparseMatrix { | ||
data, | ||
indices: col_idx, | ||
indptr: row_ptr, | ||
cols: m, | ||
}; | ||
|
||
csr | ||
} | ||
|
||
pub fn generate_scalars<F: PrimeField>(len: usize) -> Vec<F> { | ||
let mut rng = rand::thread_rng(); | ||
let scalars = (0..len).map(|_| F::random(&mut rng)).collect::<Vec<_>>(); | ||
|
||
scalars | ||
} | ||
|
||
/// cargo run --release --example spmvm | ||
fn main() { | ||
let npow: usize = std::env::var("NPOW") | ||
.unwrap_or("23".to_string()) | ||
.unwrap_or("17".to_string()) | ||
.parse() | ||
.unwrap(); | ||
let n = 1usize << npow; | ||
let nthreads: usize = std::env::var("NTHREADS") | ||
.unwrap_or("128".to_string()) | ||
.parse() | ||
.unwrap(); | ||
|
||
let mut scalars = generate_scalars(n); | ||
let csr = generate_csr(n, n); | ||
let cuda_csr = | ||
CudaSparseMatrix::new(&csr.data, &csr.indices, &csr.indptr, n, n); | ||
let W = generate_scalars(n - 10); | ||
let U = generate_scalars(9); | ||
let scalars = [W.clone(), vec![pallas::Scalar::ONE], U.clone()].concat(); | ||
|
||
let start = Instant::now(); | ||
let double_scalars = scalars.iter().map(|x| x + x).collect::<Vec<_>>(); | ||
let res = csr.multiply_vec(&scalars); | ||
println!("cpu took: {:?}", start.elapsed()); | ||
|
||
let witness = CudaWitness::new(&W, &pallas::Scalar::ONE, &U); | ||
let mut cuda_res = vec![pallas::Scalar::ONE; cuda_csr.num_rows]; | ||
let start = Instant::now(); | ||
double_pallas(&mut scalars); | ||
sparse_matrix_witness_pallas(&cuda_csr, &witness, &mut cuda_res, nthreads); | ||
println!("gpu took: {:?}", start.elapsed()); | ||
|
||
assert_eq!(double_scalars, scalars); | ||
assert_eq!(res, cuda_res); | ||
println!("success!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
pub mod spmvm; | ||
pub mod utils; | ||
|
||
extern crate semolina; | ||
|
||
|
Oops, something went wrong.