Skip to content

Commit 31f9994

Browse files
committed
runner: reorg hint execution
1 parent 262f3cd commit 31f9994

File tree

2 files changed

+102
-73
lines changed

2 files changed

+102
-73
lines changed

crates/vm/src/bytecode/hint.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ use std::{
33
fmt::{Display, Formatter},
44
};
55

6+
use p3_field::{Field, PrimeCharacteristicRing};
7+
use utils::ToUsize;
8+
69
use super::MemOrConstant;
10+
use crate::{DIMENSION, F, Memory, RunnerError};
711

812
/// Hints are special instructions for the prover to resolve non-determinism.
913
///
@@ -50,6 +54,91 @@ pub enum Hint {
5054
},
5155
}
5256

57+
impl Hint {
58+
pub fn execute(
59+
&self,
60+
memory: &mut Memory,
61+
fp: usize,
62+
ap: &mut usize,
63+
ap_vec: &mut usize,
64+
std_out: &mut String,
65+
cpu_cycles: usize,
66+
last_checkpoint_cpu_cycles: &mut usize,
67+
checkpoint_ap: &mut usize,
68+
checkpoint_ap_vec: &mut usize,
69+
) -> Result<(), RunnerError> {
70+
match self {
71+
Self::RequestMemory {
72+
offset,
73+
size,
74+
vectorized,
75+
} => {
76+
let sz = size.read_value(memory, fp)?.to_usize();
77+
if *vectorized {
78+
// find the next multiple of 8
79+
memory.set(fp + *offset, F::from_usize(*ap_vec))?;
80+
*ap_vec += sz;
81+
} else {
82+
memory.set(fp + *offset, F::from_usize(*ap))?;
83+
*ap += sz;
84+
}
85+
// does not increase PC
86+
}
87+
Self::DecomposeBits {
88+
res_offset,
89+
to_decompose,
90+
} => {
91+
let to_decompose_value = to_decompose.read_value(memory, fp)?.to_usize();
92+
for i in 0..F::bits() {
93+
let bit = if to_decompose_value & (1 << i) != 0 {
94+
F::ONE
95+
} else {
96+
F::ZERO
97+
};
98+
memory.set(fp + *res_offset + i, bit)?;
99+
}
100+
}
101+
Self::Inverse { arg, res_offset } => {
102+
let value = arg.read_value(memory, fp)?;
103+
let result = value.try_inverse().unwrap_or(F::ZERO);
104+
memory.set(fp + *res_offset, result)?;
105+
}
106+
Self::Print { line_info, content } => {
107+
let values = content
108+
.iter()
109+
.map(|m| Ok(m.read_value(memory, fp)?.to_string()))
110+
.collect::<Result<Vec<_>, RunnerError>>()?;
111+
112+
// Logs for performance analysis:
113+
if values.first().is_some_and(|s| s == "123456789") {
114+
use utils::pretty_integer;
115+
if values.len() == 1 {
116+
*std_out += "[CHECKPOINT]\n";
117+
} else {
118+
let new_no_vec = *ap - *checkpoint_ap;
119+
let new_vec = (*ap_vec - *checkpoint_ap_vec) * DIMENSION;
120+
*std_out += &format!(
121+
"[CHECKPOINT {}] new CPU cycles: {}, new runtime memory: {} ({:.1}% vec)\n",
122+
values[1],
123+
pretty_integer(cpu_cycles - *last_checkpoint_cpu_cycles),
124+
pretty_integer(new_no_vec + new_vec),
125+
new_vec as f64 / (new_no_vec + new_vec) as f64 * 100.0
126+
);
127+
}
128+
*last_checkpoint_cpu_cycles = cpu_cycles;
129+
*checkpoint_ap = *ap;
130+
*checkpoint_ap_vec = *ap_vec;
131+
} else {
132+
let line_info = line_info.replace(';', "");
133+
*std_out += &format!("\"{}\" -> {}\n", line_info, values.join(", "));
134+
// does not increase PC
135+
}
136+
}
137+
}
138+
Ok(())
139+
}
140+
}
141+
53142
impl Display for Hint {
54143
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
55144
match self {

crates/vm/src/runner.rs

Lines changed: 13 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use p3_field::{BasedVectorSpace, Field, PrimeCharacteristicRing, dot_product};
1+
use p3_field::{BasedVectorSpace, PrimeCharacteristicRing, dot_product};
22
use p3_symmetric::Permutation;
33
use utils::{ToUsize, build_poseidon16, build_poseidon24, pretty_integer};
44
use whir_p3::poly::{evals::EvaluationsList, multilinear::MultilinearPoint};
55

66
use crate::{
77
DIMENSION, EF, F, MAX_MEMORY_SIZE, Memory, POSEIDON_16_NULL_HASH_PTR,
88
POSEIDON_24_NULL_HASH_PTR, PUBLIC_INPUT_START, RunnerError, ZERO_VEC_PTR,
9-
bytecode::{Bytecode, Hint, Instruction},
9+
bytecode::{Bytecode, Instruction},
1010
};
1111

1212
#[must_use]
@@ -123,77 +123,17 @@ fn execute_bytecode_helper(
123123
cpu_cycles += 1;
124124

125125
for hint in bytecode.hints.get(&pc).unwrap_or(&vec![]) {
126-
match hint {
127-
Hint::RequestMemory {
128-
offset,
129-
size,
130-
vectorized,
131-
} => {
132-
let size = size.read_value(&memory, fp)?.to_usize();
133-
134-
if *vectorized {
135-
// find the next multiple of 8
136-
memory.set(fp + *offset, F::from_usize(ap_vec))?;
137-
ap_vec += size;
138-
} else {
139-
memory.set(fp + *offset, F::from_usize(ap))?;
140-
ap += size;
141-
}
142-
// does not increase PC
143-
}
144-
Hint::DecomposeBits {
145-
res_offset,
146-
to_decompose,
147-
} => {
148-
let to_decompose_value = to_decompose.read_value(&memory, fp)?.to_usize();
149-
for i in 0..F::bits() {
150-
let bit = if to_decompose_value & (1 << i) != 0 {
151-
F::ONE
152-
} else {
153-
F::ZERO
154-
};
155-
memory.set(fp + *res_offset + i, bit)?;
156-
}
157-
}
158-
Hint::Inverse { arg, res_offset } => {
159-
let value = arg.read_value(&memory, fp)?;
160-
let result = value.try_inverse().unwrap_or(F::ZERO);
161-
memory.set(fp + *res_offset, result)?;
162-
}
163-
Hint::Print { line_info, content } => {
164-
let values = content
165-
.iter()
166-
.map(|value| Ok(value.read_value(&memory, fp)?.to_string()))
167-
.collect::<Result<Vec<_>, _>>()?;
168-
// Logs for performance analysis:
169-
if values[0] == "123456789" {
170-
if values.len() == 1 {
171-
*std_out += "[CHECKPOINT]\n";
172-
} else {
173-
assert_eq!(values.len(), 2);
174-
let new_no_vec_memory = ap - checkpoint_ap;
175-
let new_vec_memory = (ap_vec - checkpoint_ap_vec) * DIMENSION;
176-
*std_out += &format!(
177-
"[CHECKPOINT {}] new CPU cycles: {}, new runtime memory: {} ({:.1}% vec)\n",
178-
values[1],
179-
pretty_integer(cpu_cycles - last_checkpoint_cpu_cycles),
180-
pretty_integer(new_no_vec_memory + new_vec_memory),
181-
new_vec_memory as f64 / (new_no_vec_memory + new_vec_memory) as f64
182-
* 100.0
183-
);
184-
}
185-
186-
last_checkpoint_cpu_cycles = cpu_cycles;
187-
checkpoint_ap = ap;
188-
checkpoint_ap_vec = ap_vec;
189-
continue;
190-
}
191-
192-
let line_info = line_info.replace(';', "");
193-
*std_out += &format!("\"{}\" -> {}\n", line_info, values.join(", "));
194-
// does not increase PC
195-
}
196-
}
126+
hint.execute(
127+
&mut memory,
128+
fp,
129+
&mut ap,
130+
&mut ap_vec,
131+
std_out,
132+
cpu_cycles,
133+
&mut last_checkpoint_cpu_cycles,
134+
&mut checkpoint_ap,
135+
&mut checkpoint_ap_vec,
136+
)?;
197137
}
198138

199139
let instruction = &bytecode.instructions[pc];

0 commit comments

Comments
 (0)