forked from filecoin-project/bellperson
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gpu_provers.rs
116 lines (94 loc) · 3.37 KB
/
gpu_provers.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use bellperson::{Circuit, ConstraintSystem, SynthesisError};
use ff::PrimeField;
#[derive(Clone)]
pub struct DummyDemo {
pub interations: u64,
}
impl<Scalar: PrimeField> Circuit<Scalar> for DummyDemo {
fn synthesize<CS: ConstraintSystem<Scalar>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
let mut x_val = Scalar::from(2u64);
let mut x = cs.alloc(|| "", || Ok(x_val))?;
for _ in 0..self.interations {
// Allocate: x * x = x2
let x2_val = x_val.square();
let x2 = cs.alloc(|| "", || Ok(x2_val))?;
// Enforce: x * x = x2
cs.enforce(|| "", |lc| lc + x, |lc| lc + x, |lc| lc + x2);
x = x2;
x_val = x2_val;
}
cs.enforce(
|| "",
|lc| lc + (x_val, CS::one()),
|lc| lc + CS::one(),
|lc| lc + x,
);
Ok(())
}
}
#[cfg(any(feature = "cuda", feature = "opencl"))]
#[test]
pub fn test_parallel_prover() {
use bellperson::groth16::{
create_random_proof, create_random_proof_in_priority, generate_random_parameters,
prepare_verifying_key, verify_proof,
};
use blstrs::Bls12;
use rand::thread_rng;
use std::thread;
use std::time::{Duration, Instant};
let _ = env_logger::try_init();
let rng = &mut thread_rng();
println!("Initializing circuit...");
println!("Creating parameters...");
// Higher prio circuit
let c = DummyDemo {
#[cfg(not(feature = "_coverage"))]
interations: 10_000,
#[cfg(feature = "_coverage")]
interations: 100,
};
// Lower prio circuit
let c2 = DummyDemo {
#[cfg(not(feature = "_coverage"))]
interations: 500_000,
#[cfg(feature = "_coverage")]
interations: 5000,
};
let params = generate_random_parameters::<Bls12, _, _>(c.clone(), rng).unwrap();
let params2 = generate_random_parameters::<Bls12, _, _>(c2.clone(), rng).unwrap();
// Prepare the verification key (for proof verification)
let pvk = prepare_verifying_key(¶ms.vk);
let pvk2 = prepare_verifying_key(¶ms2.vk);
let higher_thread = thread::spawn(move || {
for _ in 0..20 {
let now = Instant::now();
let rng = &mut thread_rng();
let proof_higher = create_random_proof_in_priority(c.clone(), ¶ms, rng).unwrap();
assert!(verify_proof(&pvk, &proof_higher, &[]).unwrap());
println!(
"Higher proof gen finished in {}s and {}ms",
now.elapsed().as_secs(),
now.elapsed().subsec_millis()
);
// Sleep in between higher proofs so that LOWER thread can acquire GPU again
thread::sleep(Duration::from_millis(600));
}
});
// Start lower proofs after a few seconds
thread::sleep(Duration::from_millis(2000));
println!("Starting low priority proof gen...");
{
for _ in 0..10 {
let now = Instant::now();
let proof_lower = create_random_proof(c2.clone(), ¶ms2, rng).unwrap();
assert!(verify_proof(&pvk2, &proof_lower, &[]).unwrap());
println!(
"Lower proof gen finished in {}s and {}ms",
now.elapsed().as_secs(),
now.elapsed().subsec_millis()
);
}
}
higher_thread.join().unwrap();
}