Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hash Relocatables over compact form #1505

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ test_utils = ["std", "dep:arbitrary", "starknet-types-core/arbitrary", "starknet
extensive_hints = []

[dependencies]
ahash = { version = "0.8.6", default-features = false }
zip = {version = "0.6.6", optional = true }
num-bigint = { workspace = true }
rand = { workspace = true }
Expand Down
82 changes: 10 additions & 72 deletions vm/src/types/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use core::num::NonZeroUsize;
use std::path::Path;

use super::builtin_name::BuiltinName;
#[cfg(feature = "extensive_hints")]
use super::relocatable::Relocatable;
#[cfg(feature = "test_utils")]
use arbitrary::{Arbitrary, Unstructured};
Expand Down Expand Up @@ -110,10 +109,7 @@ impl<'a> Arbitrary<'a> for SharedProgramData {
pub(crate) struct HintsCollection {
hints: Vec<HintParams>,
/// This maps a PC to the range of hints in `hints` that correspond to it.
#[cfg(not(feature = "extensive_hints"))]
pub(crate) hints_ranges: Vec<HintRange>,
#[cfg(feature = "extensive_hints")]
pub(crate) hints_ranges: HashMap<Relocatable, HintRange>,
pub(crate) hints_ranges: HashMap<Relocatable, HintRange, ahash::RandomState>,
}

impl HintsCollection {
Expand All @@ -138,20 +134,13 @@ impl HintsCollection {
}

let mut hints_values = Vec::with_capacity(full_len);
#[cfg(not(feature = "extensive_hints"))]
let mut hints_ranges = vec![None; max_hint_pc + 1];
#[cfg(feature = "extensive_hints")]
let mut hints_ranges = HashMap::default();

for (pc, hs) in hints.iter().filter(|(_, hs)| !hs.is_empty()) {
let range = (
hints_values.len(),
NonZeroUsize::new(hs.len()).expect("empty vecs already filtered"),
);
#[cfg(not(feature = "extensive_hints"))]
{
hints_ranges[*pc] = Some(range);
}
#[cfg(feature = "extensive_hints")]
hints_ranges.insert(Relocatable::from((0_isize, *pc)), range);
hints_values.extend_from_slice(&hs[..]);
}
Expand All @@ -165,24 +154,11 @@ impl HintsCollection {
pub fn iter_hints(&self) -> impl Iterator<Item = &HintParams> {
self.hints.iter()
}

#[cfg(not(feature = "extensive_hints"))]
pub fn get_hint_range_for_pc(&self, pc: usize) -> Option<HintRange> {
self.hints_ranges.get(pc).cloned()
}
}

impl From<&HintsCollection> for BTreeMap<usize, Vec<HintParams>> {
fn from(hc: &HintsCollection) -> Self {
let mut hint_map = BTreeMap::new();
#[cfg(not(feature = "extensive_hints"))]
for (i, r) in hc.hints_ranges.iter().enumerate() {
let Some(r) = r else {
continue;
};
hint_map.insert(i, hc.hints[r.0..r.0 + r.1.get()].to_owned());
}
#[cfg(feature = "extensive_hints")]
for (pc, r) in hc.hints_ranges.iter() {
hint_map.insert(pc.offset, hc.hints[r.0..r.0 + r.1.get()].to_owned());
}
Expand All @@ -191,10 +167,6 @@ impl From<&HintsCollection> for BTreeMap<usize, Vec<HintParams>> {
}

/// Represents a range of hints corresponding to a PC as a tuple `(start, length)`.
#[cfg(not(feature = "extensive_hints"))]
/// Is [`None`] if the range is empty, and it is [`Some`] tuple `(start, length)` otherwise.
type HintRange = Option<(usize, NonZeroUsize)>;
#[cfg(feature = "extensive_hints")]
pub type HintRange = (usize, NonZeroUsize);

#[cfg_attr(feature = "test_utils", derive(Arbitrary))]
Expand Down Expand Up @@ -475,22 +447,6 @@ impl TryFrom<CasmContractClass> for Program {
#[cfg(test)]
impl HintsCollection {
pub fn iter(&self) -> impl Iterator<Item = (usize, &[HintParams])> {
#[cfg(not(feature = "extensive_hints"))]
let iter = self
.hints_ranges
.iter()
.enumerate()
.filter_map(|(pc, range)| {
range.and_then(|(start, len)| {
let end = start + len.get();
if end <= self.hints.len() {
Some((pc, &self.hints[start..end]))
} else {
None
}
})
});
#[cfg(feature = "extensive_hints")]
let iter = self.hints_ranges.iter().filter_map(|(pc, (start, len))| {
let end = start + len.get();
if end <= self.hints.len() {
Expand Down Expand Up @@ -554,11 +510,10 @@ mod tests {
program.shared_program_data.hints_collection.hints,
Vec::new()
);
assert!(program
.shared_program_data
.hints_collection
.hints_ranges
.is_empty());
assert_eq!(
program.shared_program_data.hints_collection.hints_ranges,
HashMap::default()
);
}

#[test]
Expand Down Expand Up @@ -601,11 +556,10 @@ mod tests {
program.shared_program_data.hints_collection.hints,
Vec::new()
);
assert!(program
.shared_program_data
.hints_collection
.hints_ranges
.is_empty());
assert_eq!(
program.shared_program_data.hints_collection.hints_ranges,
HashMap::default()
);
}

#[test]
Expand Down Expand Up @@ -660,22 +614,6 @@ mod tests {
assert_eq!(program.shared_program_data.main, None);
assert_eq!(program.shared_program_data.identifiers, HashMap::new());

#[cfg(not(feature = "extensive_hints"))]
let program_hints: HashMap<_, _> = program
.shared_program_data
.hints_collection
.hints_ranges
.iter()
.enumerate()
.filter_map(|(pc, r)| r.map(|(s, l)| (pc, (s, s + l.get()))))
.map(|(pc, (s, e))| {
(
pc,
program.shared_program_data.hints_collection.hints[s..e].to_vec(),
)
})
.collect();
#[cfg(feature = "extensive_hints")]
let program_hints: HashMap<_, _> = program
.shared_program_data
.hints_collection
Expand Down
13 changes: 9 additions & 4 deletions vm/src/types/relocatable.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::stdlib::{
fmt::{self, Display},
hash::{Hash, Hasher},
ops::{Add, AddAssign, Sub},
prelude::*,
};
Expand All @@ -15,16 +16,20 @@ use serde::{Deserialize, Serialize};
use arbitrary::Arbitrary;

#[cfg_attr(feature = "test_utils", derive(Arbitrary))]
#[derive(
Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize, Default,
)]
#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize, Default)]
pub struct Relocatable {
pub segment_index: isize,
pub offset: usize,
}

impl Hash for Relocatable {
fn hash<H: Hasher>(&self, state: &mut H) {
(((self.segment_index as i64) << 48) | (self.offset as i64)).hash(state);
}
}

#[cfg_attr(feature = "test_utils", derive(Arbitrary))]
#[derive(Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Serialize, Deserialize)]
#[derive(Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Debug, Serialize, Deserialize)]
pub enum MaybeRelocatable {
RelocatableValue(Relocatable),
Int(Felt252),
Expand Down
44 changes: 14 additions & 30 deletions vm/src/vm/vm_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use crate::{

use crate::Felt252;
use core::cmp::Ordering;
#[cfg(feature = "extensive_hints")]
use core::num::NonZeroUsize;
use num_traits::{ToPrimitive, Zero};

Expand Down Expand Up @@ -476,7 +475,7 @@ impl VirtualMachine {
hint_processor: &mut dyn HintProcessor,
exec_scopes: &mut ExecutionScopes,
hint_datas: &mut Vec<Box<dyn Any>>,
hint_ranges: &mut HashMap<Relocatable, HintRange>,
hint_ranges: &mut HashMap<Relocatable, HintRange, ahash::RandomState>,
constants: &HashMap<String, Felt252>,
) -> Result<(), VirtualMachineError> {
// Check if there is a hint range for the current pc
Expand Down Expand Up @@ -548,16 +547,14 @@ impl VirtualMachine {
&mut self,
hint_processor: &mut dyn HintProcessor,
exec_scopes: &mut ExecutionScopes,
#[cfg(feature = "extensive_hints")] hint_datas: &mut Vec<Box<dyn Any>>,
#[cfg(not(feature = "extensive_hints"))] hint_datas: &[Box<dyn Any>],
#[cfg(feature = "extensive_hints")] hint_ranges: &mut HashMap<Relocatable, HintRange>,
hint_datas: &mut Vec<Box<dyn Any>>,
hint_ranges: &mut HashMap<Relocatable, HintRange, ahash::RandomState>,
constants: &HashMap<String, Felt252>,
) -> Result<(), VirtualMachineError> {
self.step_hint(
hint_processor,
exec_scopes,
hint_datas,
#[cfg(feature = "extensive_hints")]
hint_ranges,
constants,
)?;
Expand Down Expand Up @@ -2792,8 +2789,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new(),
),
Ok(())
Expand Down Expand Up @@ -3023,8 +3019,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new(),
),
Ok(())
Expand Down Expand Up @@ -3107,8 +3102,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new()
),
Ok(())
Expand Down Expand Up @@ -3211,8 +3205,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new()
),
Ok(())
Expand All @@ -3234,8 +3227,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new()
),
Ok(())
Expand All @@ -3258,8 +3250,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new()
),
Ok(())
Expand Down Expand Up @@ -3819,22 +3810,17 @@ mod tests {

//Run Steps
for _ in 0..6 {
#[cfg(not(feature = "extensive_hints"))]
let mut hint_data = if vm.run_context.pc == (0, 0).into() {
&hint_data[0..]
} else {
&hint_data[0..0]
};
assert_matches!(
vm.step(
&mut hint_processor,
exec_scopes_ref!(),
&mut hint_data,
#[cfg(feature = "extensive_hints")]
&mut HashMap::from([(
Relocatable::from((0, 0)),
(0_usize, NonZeroUsize::new(1).unwrap())
)]),
)]
.into_iter()
.collect(),
Oppen marked this conversation as resolved.
Show resolved Hide resolved
&HashMap::new(),
),
Ok(())
Expand Down Expand Up @@ -4483,8 +4469,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new()
),
Ok(())
Expand Down Expand Up @@ -4570,8 +4555,7 @@ mod tests {
&mut hint_processor,
exec_scopes_ref!(),
&mut Vec::new(),
#[cfg(feature = "extensive_hints")]
&mut HashMap::new(),
&mut HashMap::default(),
&HashMap::new()
),
Ok(())
Expand Down
Loading