Skip to content

Commit 23ce6bf

Browse files
committed
WIP parallel processor
1 parent 5629e6e commit 23ce6bf

21 files changed

+2959
-1
lines changed

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

processor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ miette = { package = "miden-miette", version = "8.0", default-features = false,
3131
"fancy-no-syscall",
3232
"derive"
3333
] }
34+
tokio = { version = "1.45", default-features = false, features = ["rt", "sync"] }
3435
tracing = { version = "0.1", default-features = false, features = ["attributes"] }
3536
vm-core = { package = "miden-core", path = "../core", version = "0.15", default-features = false, features = ["diagnostics"] }
3637
winter-prover = { package = "winter-prover", version = "0.12", default-features = false }

processor/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use vm_core::{
3737
pub use winter_prover::matrix::ColMatrix;
3838

3939
pub mod fast;
40+
pub mod parallel;
4041

4142
mod operations;
4243

processor/src/parallel/call.rs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use core::ops::ControlFlow;
2+
3+
use vm_core::{Word, mast::CallNode};
4+
5+
use super::{MainTraceFragmentGenerator, TraceRowType, trace_builder::OperationTraceConfig};
6+
7+
impl MainTraceFragmentGenerator {
8+
/// Adds a trace row for a CALL/SYSCALL operation (start or end) to the main trace fragment.
9+
///
10+
/// This method populates the system, decoder, and stack columns for a single trace row
11+
/// corresponding to either the start or end of a CALL/SYSCALL block execution. It uses the
12+
/// shared control flow trace building infrastructure.
13+
pub fn add_call_trace_row(
14+
&mut self,
15+
call_node: &CallNode,
16+
program: &vm_core::mast::MastForest,
17+
trace_type: TraceRowType,
18+
) -> ControlFlow<()> {
19+
// For CALL/SYSCALL operations, the hasher state in start operations contains the callee
20+
// hash in the first half, and zeros in the second half (since CALL only has one
21+
// child)
22+
let callee_hash: Word = program
23+
.get_node_by_id(call_node.callee())
24+
.expect("callee should exist")
25+
.digest()
26+
.into();
27+
let zero_hash: Word = [vm_core::ZERO; 4];
28+
29+
let config = OperationTraceConfig {
30+
start_opcode: if call_node.is_syscall() {
31+
vm_core::Operation::SysCall.op_code()
32+
} else {
33+
vm_core::Operation::Call.op_code()
34+
},
35+
start_hasher_state: (callee_hash, zero_hash),
36+
end_node_digest: call_node.digest().into(),
37+
};
38+
39+
self.add_control_flow_trace_row(config, trace_type)
40+
}
41+
42+
/// Adds a trace row for the start of a CALL/SYSCALL operation.
43+
///
44+
/// This is a convenience method that calls `add_call_trace_row` with `TraceRowType::Start`.
45+
pub fn add_call_start_trace_row(
46+
&mut self,
47+
call_node: &CallNode,
48+
program: &vm_core::mast::MastForest,
49+
) -> ControlFlow<()> {
50+
self.add_call_trace_row(call_node, program, TraceRowType::Start)
51+
}
52+
53+
/// Adds a trace row for the end of a CALL/SYSCALL operation.
54+
///
55+
/// This is a convenience method that calls `add_call_trace_row` with `TraceRowType::End`.
56+
pub fn add_call_end_trace_row(
57+
&mut self,
58+
call_node: &CallNode,
59+
program: &vm_core::mast::MastForest,
60+
) -> ControlFlow<()> {
61+
self.add_call_trace_row(call_node, program, TraceRowType::End)
62+
}
63+
}

processor/src/parallel/dyn.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use core::ops::ControlFlow;
2+
3+
use vm_core::{Word, mast::DynNode};
4+
5+
use super::{MainTraceFragmentGenerator, TraceRowType, trace_builder::OperationTraceConfig};
6+
7+
impl MainTraceFragmentGenerator {
8+
/// Adds a trace row for a DYN/DYNCALL operation (start or end) to the main trace fragment.
9+
///
10+
/// This method populates the system, decoder, and stack columns for a single trace row
11+
/// corresponding to either the start or end of a DYN/DYNCALL block execution. It uses the
12+
/// shared control flow trace building infrastructure.
13+
pub fn add_dyn_trace_row(
14+
&mut self,
15+
dyn_node: &DynNode,
16+
trace_type: TraceRowType,
17+
) -> ControlFlow<()> {
18+
// For DYN/DYNCALL operations, the hasher state is set to zeros since the dynamic target
19+
// is resolved at runtime and cannot be known at compile time during parallel execution
20+
let zero_hash: Word = [vm_core::ZERO; 4];
21+
22+
let config = OperationTraceConfig {
23+
start_opcode: if dyn_node.is_dyncall() {
24+
vm_core::Operation::Dyncall.op_code()
25+
} else {
26+
vm_core::Operation::Dyn.op_code()
27+
},
28+
start_hasher_state: (zero_hash, zero_hash),
29+
end_node_digest: dyn_node.digest().into(),
30+
};
31+
32+
self.add_control_flow_trace_row(config, trace_type)
33+
}
34+
35+
/// Adds a trace row for the start of a DYN/DYNCALL operation.
36+
///
37+
/// This is a convenience method that calls `add_dyn_trace_row` with `TraceRowType::Start`.
38+
pub fn add_dyn_start_trace_row(&mut self, dyn_node: &DynNode) -> ControlFlow<()> {
39+
self.add_dyn_trace_row(dyn_node, TraceRowType::Start)
40+
}
41+
42+
/// Adds a trace row for the end of a DYN/DYNCALL operation.
43+
///
44+
/// This is a convenience method that calls `add_dyn_trace_row` with `TraceRowType::End`.
45+
pub fn add_dyn_end_trace_row(&mut self, dyn_node: &DynNode) -> ControlFlow<()> {
46+
self.add_dyn_trace_row(dyn_node, TraceRowType::End)
47+
}
48+
}

processor/src/parallel/join.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
use core::ops::ControlFlow;
2+
3+
use vm_core::{Word, mast::JoinNode};
4+
5+
use super::{MainTraceFragmentGenerator, TraceRowType, trace_builder::OperationTraceConfig};
6+
7+
impl MainTraceFragmentGenerator {
8+
/// Adds a trace row for a JOIN operation (start or end) to the main trace fragment.
9+
///
10+
/// This method populates the system, decoder, and stack columns for a single trace row
11+
/// corresponding to either the start or end of a JOIN block execution. It uses the
12+
/// shared control flow trace building infrastructure.
13+
pub fn add_join_trace_row(
14+
&mut self,
15+
join_node: &JoinNode,
16+
program: &vm_core::mast::MastForest,
17+
trace_type: TraceRowType,
18+
) -> ControlFlow<()> {
19+
// Get the child hashes for the hasher state
20+
let child1_hash: Word = program
21+
.get_node_by_id(join_node.first())
22+
.expect("first child should exist")
23+
.digest()
24+
.into();
25+
let child2_hash: Word = program
26+
.get_node_by_id(join_node.second())
27+
.expect("second child should exist")
28+
.digest()
29+
.into();
30+
31+
let config = OperationTraceConfig {
32+
start_opcode: vm_core::Operation::Join.op_code(),
33+
start_hasher_state: (child1_hash, child2_hash),
34+
end_node_digest: join_node.digest().into(),
35+
};
36+
37+
self.add_control_flow_trace_row(config, trace_type)
38+
}
39+
40+
/// Adds a trace row for starting a JOIN operation to the main trace fragment.
41+
///
42+
/// This is a convenience wrapper around `add_join_trace_row` for JOIN start operations.
43+
pub fn add_join_start_trace_row(
44+
&mut self,
45+
join_node: &JoinNode,
46+
program: &vm_core::mast::MastForest,
47+
) -> ControlFlow<()> {
48+
self.add_join_trace_row(join_node, program, TraceRowType::Start)
49+
}
50+
51+
/// Adds a trace row for ending a JOIN operation to the main trace fragment.
52+
///
53+
/// This is a convenience wrapper around `add_join_trace_row` for JOIN end operations.
54+
pub fn add_join_end_trace_row(
55+
&mut self,
56+
join_node: &JoinNode,
57+
program: &vm_core::mast::MastForest,
58+
) -> ControlFlow<()> {
59+
self.add_join_trace_row(join_node, program, TraceRowType::End)
60+
}
61+
}

processor/src/parallel/loop.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use core::ops::ControlFlow;
2+
3+
use vm_core::{Word, mast::LoopNode};
4+
5+
use super::{MainTraceFragmentGenerator, TraceRowType, trace_builder::OperationTraceConfig};
6+
7+
impl MainTraceFragmentGenerator {
8+
/// Adds a trace row for a LOOP operation (start or end) to the main trace fragment.
9+
///
10+
/// This method populates the system, decoder, and stack columns for a single trace row
11+
/// corresponding to either the start or end of a LOOP block execution. It uses the
12+
/// shared control flow trace building infrastructure.
13+
pub fn add_loop_trace_row(
14+
&mut self,
15+
loop_node: &LoopNode,
16+
program: &vm_core::mast::MastForest,
17+
trace_type: TraceRowType,
18+
) -> ControlFlow<()> {
19+
// For LOOP operations, the hasher state in start operations contains the loop body hash
20+
// in the first half, and zeros in the second half (since LOOP only has one child)
21+
let body_hash: Word = program
22+
.get_node_by_id(loop_node.body())
23+
.expect("loop body should exist")
24+
.digest()
25+
.into();
26+
let zero_hash: Word = [vm_core::ZERO; 4];
27+
28+
let config = OperationTraceConfig {
29+
start_opcode: vm_core::Operation::Loop.op_code(),
30+
start_hasher_state: (body_hash, zero_hash),
31+
end_node_digest: loop_node.digest().into(),
32+
};
33+
34+
self.add_control_flow_trace_row(config, trace_type)
35+
}
36+
37+
/// Adds a trace row for the start of a LOOP operation.
38+
///
39+
/// This is a convenience method that calls `add_loop_trace_row` with `TraceRowType::Start`.
40+
pub fn add_loop_start_trace_row(
41+
&mut self,
42+
loop_node: &LoopNode,
43+
program: &vm_core::mast::MastForest,
44+
) -> ControlFlow<()> {
45+
self.add_loop_trace_row(loop_node, program, TraceRowType::Start)
46+
}
47+
48+
/// Adds a trace row for the end of a LOOP operation.
49+
///
50+
/// This is a convenience method that calls `add_loop_trace_row` with `TraceRowType::End`.
51+
pub fn add_loop_end_trace_row(
52+
&mut self,
53+
loop_node: &LoopNode,
54+
program: &vm_core::mast::MastForest,
55+
) -> ControlFlow<()> {
56+
self.add_loop_trace_row(loop_node, program, TraceRowType::End)
57+
}
58+
}

0 commit comments

Comments
 (0)