Skip to content

Commit 9be78e9

Browse files
committed
line level and instruction level profiling
1 parent d2d1d72 commit 9be78e9

File tree

4 files changed

+82
-36
lines changed

4 files changed

+82
-36
lines changed

crates/lean_vm/src/diagnostics/profiler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub(crate) fn profiling_report(
2121
let mut call_stack: Vec<String> = Vec::new();
2222
let mut prev_function_name = String::new();
2323

24-
for (&line_num, &cycle_count) in instructions.lines.iter().zip(&instructions.cycles) {
24+
for (&line_num, &cycle_count) in instructions.lines.iter().zip(&instructions.lines_cycles) {
2525
let (_, current_function_name) = find_function_for_line(line_num, function_locations);
2626

2727
if prev_function_name != current_function_name {

crates/lean_vm/src/execution/context.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use crate::core::SourceLineNumber;
1+
use crate::core::{SourceLineNumber};
22
use std::collections::BTreeMap;
33

44
#[derive(Debug, Clone, Default)]
55
pub struct ExecutionHistory {
66
pub lines: Vec<SourceLineNumber>,
7-
pub cycles: Vec<usize>, // for each line, how many cycles it took
7+
pub lines_cycles: Vec<usize>, // for each line, how many cycles it took
88
}
99

1010
impl ExecutionHistory {
@@ -14,11 +14,11 @@ impl ExecutionHistory {
1414

1515
pub fn add_line(&mut self, location: SourceLineNumber, cycles: usize) {
1616
self.lines.push(location);
17-
self.cycles.push(cycles);
17+
self.lines_cycles.push(cycles);
1818
}
1919

2020
pub fn total_cycles(&self) -> usize {
21-
self.cycles.iter().sum()
21+
self.lines_cycles.iter().sum()
2222
}
2323

2424
pub const fn len(&self) -> usize {

crates/lean_vm/src/execution/runner.rs

Lines changed: 76 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! VM execution runner
22
3-
use crate::HintExecutionContext;
3+
use crate::{CodeAddress, SourceLineNumber, HintExecutionContext};
44
use crate::core::{
55
DIMENSION, F, ONE_VEC_PTR, POSEIDON_16_NULL_HASH_PTR, POSEIDON_24_NULL_HASH_PTR,
66
PUBLIC_INPUT_START, VECTOR_LEN, ZERO_VEC_PTR,
@@ -72,36 +72,82 @@ pub fn execute_bytecode(
7272
) -> ExecutionResult {
7373
let mut std_out = String::new();
7474
let mut instruction_history = ExecutionHistory::new();
75-
execute_bytecode_helper(
76-
bytecode,
77-
public_input,
78-
private_input,
79-
no_vec_runtime_memory,
80-
&mut std_out,
81-
&mut instruction_history,
82-
profiler,
83-
function_locations,
84-
)
85-
.unwrap_or_else(|err| {
86-
let lines_history = &instruction_history.lines;
87-
let latest_instructions =
88-
&lines_history[lines_history.len().saturating_sub(STACK_TRACE_INSTRUCTIONS)..];
89-
println!(
90-
"\n{}",
91-
crate::diagnostics::pretty_stack_trace(
92-
source_code,
93-
latest_instructions,
94-
function_locations
95-
)
96-
);
97-
if !std_out.is_empty() {
98-
println!("╔══════════════════════════════════════════════════════════════╗");
99-
println!("║ STD-OUT ║");
100-
println!("╚══════════════════════════════════════════════════════════════╝\n");
101-
print!("{std_out}");
75+
let result =
76+
execute_bytecode_helper(
77+
bytecode,
78+
public_input,
79+
private_input,
80+
no_vec_runtime_memory,
81+
&mut std_out,
82+
&mut instruction_history,
83+
profiler,
84+
function_locations,
85+
)
86+
.unwrap_or_else(|err| {
87+
let lines_history = &instruction_history.lines;
88+
let latest_instructions =
89+
&lines_history[lines_history.len().saturating_sub(STACK_TRACE_INSTRUCTIONS)..];
90+
println!(
91+
"\n{}",
92+
crate::diagnostics::pretty_stack_trace(
93+
source_code,
94+
latest_instructions,
95+
function_locations
96+
)
97+
);
98+
if !std_out.is_empty() {
99+
println!("╔══════════════════════════════════════════════════════════════╗");
100+
println!("║ STD-OUT ║");
101+
println!("╚══════════════════════════════════════════════════════════════╝\n");
102+
print!("{std_out}");
103+
}
104+
panic!("Error during bytecode execution: {err}");
105+
});
106+
if profiler {
107+
print_line_cycle_counts(instruction_history);
108+
print_instruction_cycle_counts(bytecode, result.pcs.clone());
109+
}
110+
result
111+
}
112+
113+
fn print_line_cycle_counts(history: ExecutionHistory) {
114+
println!("Line by line cycle counts");
115+
println!("=========================\n");
116+
117+
let mut gross_cycle_counts: BTreeMap<SourceLineNumber, usize> = BTreeMap::new();
118+
for (line, cycle_count) in history.lines.iter().zip(history.lines_cycles.iter()) {
119+
let prev_count = gross_cycle_counts.get(line).unwrap_or(&0);
120+
gross_cycle_counts.insert(*line, *prev_count + cycle_count);
121+
}
122+
for (line, cycle_count) in gross_cycle_counts.iter() {
123+
println!("line {line}: {cycle_count} cycles");
124+
}
125+
println!("");
126+
}
127+
128+
fn print_instruction_cycle_counts(bytecode: &Bytecode, pcs: Vec<CodeAddress>) {
129+
println!("Instruction level cycle counts");
130+
println!("==============================");
131+
132+
let mut gross_cycle_counts: BTreeMap<CodeAddress, usize> = BTreeMap::new();
133+
for pc in pcs.iter() {
134+
let prev_count = gross_cycle_counts.get(pc).unwrap_or(&0);
135+
gross_cycle_counts.insert(*pc, *prev_count + 1);
136+
}
137+
for (pc, cycle_count) in gross_cycle_counts.iter() {
138+
let instruction = &bytecode.instructions[*pc];
139+
let hints = bytecode.hints.get(pc);
140+
match hints {
141+
Some(hints) => {
142+
for hint in hints {
143+
println!("hint: {hint}");
144+
}
145+
},
146+
None => {},
102147
}
103-
panic!("Error during bytecode execution: {err}");
104-
})
148+
println!("pc {pc}: {cycle_count} cycles: {instruction}");
149+
}
150+
println!("");
105151
}
106152

107153
/// Helper function that performs the actual bytecode execution

crates/lean_vm/src/isa/hint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ impl Hint {
187187
Self::LocationReport { location } => {
188188
ctx.instruction_history.lines.push(*location);
189189
ctx.instruction_history
190-
.cycles
190+
.lines_cycles
191191
.push(*ctx.cpu_cycles_before_new_line);
192192
*ctx.cpu_cycles_before_new_line = 0;
193193
}

0 commit comments

Comments
 (0)