Make FFT and division by d parallel.

This commit is contained in:
Sean Bowe 2016-08-06 11:32:31 -06:00
parent ac39f38e90
commit 4ad19126df
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
5 changed files with 47 additions and 9 deletions

7
Cargo.lock generated
View File

@ -2,9 +2,15 @@
name = "mpc" name = "mpc"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"snark 0.0.1", "snark 0.0.1",
] ]
[[package]]
name = "crossbeam"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "gcc" name = "gcc"
version = "0.3.32" version = "0.3.32"
@ -30,6 +36,7 @@ dependencies = [
] ]
[metadata] [metadata]
"checksum crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "fb974f835e90390c5f9dfac00f05b06dc117299f5ea4e85fbc7bb443af4911cc"
"checksum gcc 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "dcb000abd6df9df4c637f75190297ebe56c1d7e66b56bbf3b4aa7aece15f61a2" "checksum gcc 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "dcb000abd6df9df4c637f75190297ebe56c1d7e66b56bbf3b4aa7aece15f61a2"
"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417" "checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417"
"checksum libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "39dfaaa0f4da0f1a06876c5d94329d739ad0150868069cc235f1ddf80a0480e7" "checksum libc 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "39dfaaa0f4da0f1a06876c5d94329d739ad0150868069cc235f1ddf80a0480e7"

View File

@ -11,3 +11,4 @@ readme = "README.md"
[dependencies] [dependencies]
snark = { path = "./snark/" } snark = { path = "./snark/" }
crossbeam = "0.2.9"

View File

@ -156,7 +156,7 @@ pub fn pairing<Ga: Group, Gb: Group>(p: &Ga, q: &Gb) -> Gt where Ga: Pairing<Gb>
unsafe { libsnarkwrap_pairing(p.g1(q), p.g2(q)) } unsafe { libsnarkwrap_pairing(p.g1(q), p.g2(q)) }
} }
pub trait Group: Sized + pub trait Group: Sized + Send +
Copy + Copy +
Clone + Clone +
Mul<Fr, Output=Self> + Mul<Fr, Output=Self> +

View File

@ -1,16 +1,28 @@
use snark::{Group, Fr}; use snark::{Group, Fr};
use crossbeam;
pub fn lagrange_coeffs<G: Group>(v: &[G], omega: Fr, d: usize) -> Vec<G> pub fn lagrange_coeffs<G: Group>(v: &[G], omega: Fr, d: usize) -> Vec<G>
{ {
const THREADS: usize = 8;
let overd = Fr::from_str(&format!("{}", d)).inverse(); let overd = Fr::from_str(&format!("{}", d)).inverse();
fft(v, omega) let mut tmp = fft(v, omega, THREADS);
.into_iter() tmp.reverse(); // coefficients are in reverse
.rev() // coefficients are in reverse
.map(|e| e * overd) // divide by d crossbeam::scope(|scope| {
.collect::<Vec<_>>() for i in tmp.chunks_mut(d / THREADS) {
scope.spawn(move || {
for i in i {
*i = *i * overd;
}
});
}
});
tmp
} }
fn fft<G: Group>(v: &[G], omega: Fr) -> Vec<G> fn fft<G: Group>(v: &[G], omega: Fr, threads: usize) -> Vec<G>
{ {
if v.len() == 2 { if v.len() == 2 {
vec![ vec![
@ -31,8 +43,25 @@ fn fft<G: Group>(v: &[G], omega: Fr) -> Vec<G>
} }
let o2 = omega * omega; let o2 = omega * omega;
let evens = fft(&evens, o2); let (evens, odds) = if threads < 2 {
let odds = fft(&odds, o2); (fft(&evens, o2, 1), fft(&odds, o2, 1))
} else {
use std::sync::mpsc::channel;
use std::thread;
let (tx_evens, rx_evens) = channel();
let (tx_odds, rx_odds) = channel();
thread::spawn(move || {
tx_evens.send(fft(&evens, o2, threads/2)).unwrap();
});
thread::spawn(move || {
tx_odds.send(fft(&odds, o2, threads/2)).unwrap();
});
(rx_evens.recv().unwrap(), rx_odds.recv().unwrap())
};
let mut acc = omega; let mut acc = omega;
let mut res = Vec::with_capacity(v.len()); let mut res = Vec::with_capacity(v.len());

View File

@ -1,4 +1,5 @@
extern crate snark; extern crate snark;
extern crate crossbeam;
mod util; mod util;
mod lagrange; mod lagrange;