Place bellman multicore operations behind a (default) feature flag
Co-authored-by: Jack Grigg <jack@z.cash>
This commit is contained in:
parent
955e6795d5
commit
3dd849053a
|
@ -13,16 +13,17 @@ rand = "0.4"
|
|||
bit-vec = "0.4.4"
|
||||
ff = { path = "../ff" }
|
||||
futures = "0.1"
|
||||
futures-cpupool = "0.1"
|
||||
futures-cpupool = { version = "0.1", optional = true }
|
||||
group = { path = "../group" }
|
||||
num_cpus = "1"
|
||||
crossbeam = "0.3"
|
||||
num_cpus = { version = "1", optional = true }
|
||||
crossbeam = { version = "0.3", optional = true }
|
||||
pairing = { path = "../pairing", optional = true }
|
||||
byteorder = "1"
|
||||
|
||||
[features]
|
||||
groth16 = ["pairing"]
|
||||
default = ["groth16"]
|
||||
multicore = ["futures-cpupool", "crossbeam", "num_cpus"]
|
||||
default = ["groth16", "multicore"]
|
||||
|
||||
[[test]]
|
||||
name = "mimc"
|
||||
|
|
11
src/lib.rs
11
src/lib.rs
|
@ -3,13 +3,18 @@ extern crate group;
|
|||
#[cfg(feature = "pairing")]
|
||||
extern crate pairing;
|
||||
extern crate rand;
|
||||
extern crate num_cpus;
|
||||
|
||||
extern crate futures;
|
||||
extern crate futures_cpupool;
|
||||
extern crate bit_vec;
|
||||
extern crate crossbeam;
|
||||
extern crate byteorder;
|
||||
|
||||
#[cfg(feature = "multicore")]
|
||||
extern crate crossbeam;
|
||||
#[cfg(feature = "multicore")]
|
||||
extern crate futures_cpupool;
|
||||
#[cfg(feature = "multicore")]
|
||||
extern crate num_cpus;
|
||||
|
||||
pub mod multicore;
|
||||
mod multiexp;
|
||||
pub mod domain;
|
||||
|
|
|
@ -4,18 +4,20 @@
|
|||
//! crossbeam but may be extended in the future to
|
||||
//! allow for various parallelism strategies.
|
||||
|
||||
use num_cpus;
|
||||
use futures::{Future, IntoFuture, Poll};
|
||||
use futures_cpupool::{CpuPool, CpuFuture};
|
||||
use crossbeam::{self, Scope};
|
||||
#[cfg(feature = "multicore")]
|
||||
mod implementation {
|
||||
use num_cpus;
|
||||
use futures::{Future, IntoFuture, Poll};
|
||||
use futures_cpupool::{CpuPool, CpuFuture};
|
||||
use crossbeam::{self, Scope};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Worker {
|
||||
#[derive(Clone)]
|
||||
pub struct Worker {
|
||||
cpus: usize,
|
||||
pool: CpuPool
|
||||
}
|
||||
}
|
||||
|
||||
impl Worker {
|
||||
impl Worker {
|
||||
// We don't expose this outside the library so that
|
||||
// all `Worker` instances have the same number of
|
||||
// CPUs configured.
|
||||
|
@ -65,13 +67,13 @@ impl Worker {
|
|||
f(scope, chunk_size)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WorkerFuture<T, E> {
|
||||
pub struct WorkerFuture<T, E> {
|
||||
future: CpuFuture<T, E>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Send + 'static, E: Send + 'static> Future for WorkerFuture<T, E> {
|
||||
impl<T: Send + 'static, E: Send + 'static> Future for WorkerFuture<T, E> {
|
||||
type Item = T;
|
||||
type Error = E;
|
||||
|
||||
|
@ -79,9 +81,9 @@ impl<T: Send + 'static, E: Send + 'static> Future for WorkerFuture<T, E> {
|
|||
{
|
||||
self.future.poll()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn log2_floor(num: usize) -> u32 {
|
||||
fn log2_floor(num: usize) -> u32 {
|
||||
assert!(num > 0);
|
||||
|
||||
let mut pow = 0;
|
||||
|
@ -91,10 +93,10 @@ fn log2_floor(num: usize) -> u32 {
|
|||
}
|
||||
|
||||
pow
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_log2_floor() {
|
||||
#[test]
|
||||
fn test_log2_floor() {
|
||||
assert_eq!(log2_floor(1), 0);
|
||||
assert_eq!(log2_floor(2), 1);
|
||||
assert_eq!(log2_floor(3), 1);
|
||||
|
@ -103,4 +105,64 @@ fn test_log2_floor() {
|
|||
assert_eq!(log2_floor(6), 2);
|
||||
assert_eq!(log2_floor(7), 2);
|
||||
assert_eq!(log2_floor(8), 3);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "multicore"))]
|
||||
mod implementation {
|
||||
use futures::{future, Future, IntoFuture, Poll};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Worker;
|
||||
|
||||
impl Worker {
|
||||
pub fn new() -> Worker {
|
||||
Worker
|
||||
}
|
||||
|
||||
pub fn log_num_cpus(&self) -> u32 {
|
||||
0
|
||||
}
|
||||
|
||||
pub fn compute<F, R>(&self, f: F) -> R::Future
|
||||
where
|
||||
F: FnOnce() -> R + Send + 'static,
|
||||
R: IntoFuture + 'static,
|
||||
R::Future: Send + 'static,
|
||||
R::Item: Send + 'static,
|
||||
R::Error: Send + 'static,
|
||||
{
|
||||
f().into_future()
|
||||
}
|
||||
|
||||
pub fn scope<F, R>(&self, elements: usize, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&DummyScope, usize) -> R,
|
||||
{
|
||||
f(&DummyScope, elements)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WorkerFuture<T, E> {
|
||||
future: future::FutureResult<T, E>,
|
||||
}
|
||||
|
||||
impl<T: Send + 'static, E: Send + 'static> Future for WorkerFuture<T, E> {
|
||||
type Item = T;
|
||||
type Error = E;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
self.future.poll()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyScope;
|
||||
|
||||
impl DummyScope {
|
||||
pub fn spawn<F: FnOnce()>(&self, f: F) {
|
||||
f();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use self::implementation::*;
|
||||
|
|
Loading…
Reference in New Issue