Skip to content

Commit 3edc61e

Browse files
committed
Distributed prover
1 parent dd032eb commit 3edc61e

File tree

16 files changed

+1766
-299
lines changed

16 files changed

+1766
-299
lines changed

Cargo.lock

+335-299
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+10
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ p3-uni-stark = "0.1.3-succinct"
7979
p3-maybe-rayon = "0.1.3-succinct"
8080
p3-bn254-fr = "0.1.3-succinct"
8181

82+
8283
# For local development.
8384

8485
# p3-air = { path = "../Plonky3/air" }
@@ -101,3 +102,12 @@ p3-bn254-fr = "0.1.3-succinct"
101102
# p3-uni-stark = { path = "../Plonky3/uni-stark" }
102103
# p3-maybe-rayon = { path = "../Plonky3/maybe-rayon" }
103104
# p3-bn254-fr = { path = "../Plonky3/bn254-fr" }
105+
106+
# Patch Plonky3 for Serialize and Deserialize of DuplexChallenger
107+
[patch.crates-io]
108+
p3-field = { git = "https://github.com/Champii/Plonky3.git", branch = "serde_patch" }
109+
p3-challenger = { git = "https://github.com/Champii/Plonky3.git", branch = "serde_patch" }
110+
p3-poseidon2 = { git = "https://github.com/Champii/Plonky3.git", branch = "serde_patch" }
111+
p3-baby-bear = { git = "https://github.com/Champii/Plonky3.git", branch = "serde_patch" }
112+
p3-symmetric = { git = "https://github.com/Champii/Plonky3.git", branch = "serde_patch" }
113+

core/src/utils/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ mod options;
66
#[cfg(any(test, feature = "programs"))]
77
mod programs;
88
mod prove;
9+
pub mod prove_distributed;
910
mod serde;
1011
mod tracer;
1112

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
use std::sync::{mpsc::SyncSender, Arc};
2+
3+
pub use crate::{air::PublicValues, runtime::Program, stark::RiscvAir};
4+
5+
use crate::{
6+
runtime::{ExecutionRecord, NoOpSubproofVerifier, Runtime},
7+
stark::{MachineProver, MachineRecord},
8+
utils::{baby_bear_poseidon2::Val, BabyBearPoseidon2, SP1CoreOpts},
9+
};
10+
11+
use super::Checkpoint;
12+
13+
fn trace_checkpoint(
14+
program: Program,
15+
checkpoint: Checkpoint,
16+
opts: SP1CoreOpts,
17+
) -> (Vec<ExecutionRecord>, Checkpoint) {
18+
let mut runtime = Runtime::recover(program, checkpoint, opts);
19+
20+
runtime.subproof_verifier = Arc::new(NoOpSubproofVerifier);
21+
22+
let (events, _) =
23+
tracing::debug_span!("runtime.trace").in_scope(|| runtime.execute_record().unwrap());
24+
25+
let state = runtime.state.clone();
26+
27+
(events, state)
28+
}
29+
30+
pub fn process<P: MachineProver<BabyBearPoseidon2, RiscvAir<Val>>>(
31+
prover: &P,
32+
program: &Program,
33+
checkpoint: Checkpoint,
34+
nb_checkpoints: usize,
35+
state: PublicValues<u32, u32>,
36+
opts: SP1CoreOpts,
37+
records_tx: SyncSender<Vec<ExecutionRecord>>,
38+
deferred: &mut ExecutionRecord,
39+
is_deferred: bool,
40+
) {
41+
if is_deferred {
42+
process_deferred(program, checkpoint, state, opts, records_tx, deferred);
43+
} else {
44+
process_regular(
45+
prover,
46+
program,
47+
checkpoint,
48+
nb_checkpoints,
49+
state,
50+
opts,
51+
records_tx,
52+
deferred,
53+
);
54+
}
55+
}
56+
57+
fn process_regular<P: MachineProver<BabyBearPoseidon2, RiscvAir<Val>>>(
58+
prover: &P,
59+
program: &Program,
60+
mut checkpoint: Checkpoint,
61+
nb_checkpoints: usize,
62+
mut state: PublicValues<u32, u32>,
63+
opts: SP1CoreOpts,
64+
records_tx: SyncSender<Vec<ExecutionRecord>>,
65+
deferred: &mut ExecutionRecord,
66+
) {
67+
tracing::debug_span!("phase 1 record generator").in_scope(|| {
68+
let mut processed_checkpoints = 0;
69+
70+
while processed_checkpoints < nb_checkpoints {
71+
log::info!(
72+
"Processing checkpoint {}/{}",
73+
processed_checkpoints + 1,
74+
nb_checkpoints
75+
);
76+
// Trace the checkpoint and reconstruct the execution records.
77+
let (mut records, new_checkpoint) = tracing::debug_span!("trace checkpoint")
78+
.in_scope(|| trace_checkpoint(program.clone(), checkpoint, opts));
79+
80+
checkpoint = new_checkpoint;
81+
82+
// Update the public values & prover state for the shards which contain "cpu events".
83+
for record in records.iter_mut() {
84+
state.shard += 1;
85+
state.execution_shard = record.public_values.execution_shard;
86+
state.start_pc = record.public_values.start_pc;
87+
state.next_pc = record.public_values.next_pc;
88+
record.public_values = state;
89+
}
90+
91+
// Generate the dependencies.
92+
tracing::debug_span!("generate dependencies")
93+
.in_scope(|| prover.machine().generate_dependencies(&mut records, &opts));
94+
95+
// Defer events that are too expensive to include in every shard.
96+
for record in records.iter_mut() {
97+
deferred.append(&mut record.defer());
98+
}
99+
100+
// See if any deferred shards are ready to be commited to.
101+
let mut _deferred = deferred.split(false, opts.split_opts);
102+
103+
// Update the public values & prover state for the shards which do not contain "cpu events"
104+
// before committing to them.
105+
state.execution_shard += 1;
106+
107+
records_tx.send(records).unwrap();
108+
109+
processed_checkpoints += 1;
110+
}
111+
});
112+
}
113+
114+
fn process_deferred(
115+
program: &Program,
116+
checkpoint: Checkpoint,
117+
mut state: PublicValues<u32, u32>,
118+
opts: SP1CoreOpts,
119+
records_tx: SyncSender<Vec<ExecutionRecord>>,
120+
deferred: &mut ExecutionRecord,
121+
) {
122+
tracing::debug_span!("phase 1 record generator").in_scope(|| {
123+
// Trace the checkpoint and reconstruct the execution records.
124+
let (mut records, _) = tracing::debug_span!("trace checkpoint")
125+
.in_scope(|| trace_checkpoint(program.clone(), checkpoint, opts));
126+
127+
// Update the public values & prover state for the shards which contain "cpu events".
128+
for record in records.iter_mut() {
129+
// state.shard += 1;
130+
state.execution_shard = record.public_values.execution_shard;
131+
state.start_pc = record.public_values.start_pc;
132+
state.next_pc = record.public_values.next_pc;
133+
record.public_values = state;
134+
}
135+
136+
// See if any deferred shards are ready to be commited to.
137+
let mut deferred = deferred.split(true, opts.split_opts);
138+
139+
// Update the public values & prover state for the shards which do not contain "cpu events"
140+
// before committing to them.
141+
142+
for record in deferred.iter_mut() {
143+
state.shard += 1;
144+
state.previous_init_addr_bits = record.public_values.previous_init_addr_bits;
145+
state.last_init_addr_bits = record.public_values.last_init_addr_bits;
146+
state.previous_finalize_addr_bits = record.public_values.previous_finalize_addr_bits;
147+
state.last_finalize_addr_bits = record.public_values.last_finalize_addr_bits;
148+
state.start_pc = state.next_pc;
149+
record.public_values = state;
150+
}
151+
152+
records_tx.send(deferred).unwrap();
153+
});
154+
}

0 commit comments

Comments
 (0)