Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ cairo-lang-runner = "=2.12.0-dev.0"
cairo-lang-semantic = "=2.12.0-dev.0"
cairo-lang-sierra = "=2.12.0-dev.0"
cairo-lang-sierra-generator = "=2.12.0-dev.0"
cairo-lang-sierra-to-casm = "=2.12.0-dev.0"
educe = "0.5.11" # can't update until https://github.com/magiclen/educe/issues/27
itertools = "0.14.0"
lazy_static = "1.5"
Expand Down
3 changes: 2 additions & 1 deletion src/bin/cairo-native-run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use cairo_lang_compiler::{
compile_prepared_db, db::RootDatabase, project::setup_project, CompilerConfig,
};
use cairo_lang_runner::short_string::as_cairo_short_string;
use cairo_lang_sierra_to_casm::metadata::MetadataComputationConfig;
use cairo_native::{
context::NativeContext,
executor::{AotNativeExecutor, JitNativeExecutor},
metadata::gas::{GasMetadata, MetadataComputationConfig},
metadata::gas::GasMetadata,
starknet_stub::StubSyscallHandler,
};
use clap::{Parser, ValueEnum};
Expand Down
5 changes: 4 additions & 1 deletion src/bin/utils/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::{find_function, format_for_panic, result_to_runresult, RunArgs, RunMo
use anyhow::Context;
use cairo_lang_runner::RunResultValue;
use cairo_lang_sierra::{extensions::gas::CostTokenType, ids::FunctionId, program::Program};
use cairo_lang_sierra_to_casm::metadata::MetadataComputationConfig;
use cairo_lang_test_plugin::{
test_config::{PanicExpectation, TestExpectation},
TestConfig,
Expand All @@ -11,7 +12,7 @@ use cairo_lang_utils::{casts::IntoOrPanic, ordered_hash_map::OrderedHashMap};
use cairo_native::{
context::NativeContext,
executor::{AotNativeExecutor, JitNativeExecutor},
metadata::gas::{GasMetadata, MetadataComputationConfig},
metadata::gas::GasMetadata,
starknet_stub::StubSyscallHandler,
};
use colored::Colorize;
Expand Down Expand Up @@ -173,6 +174,8 @@ pub fn run_tests(
function_set_costs,
linear_ap_change_solver: true,
linear_gas_solver: true,
skip_non_linear_solver_comparisons: false,
compute_runtime_costs: false,
}),
)
.unwrap();
Expand Down
7 changes: 2 additions & 5 deletions src/context.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use crate::{
error::{panic::ToNativeAssertError, Error},
ffi::{get_data_layout_rep, get_target_triple},
metadata::{
gas::{GasMetadata, MetadataComputationConfig},
runtime_bindings::RuntimeBindingsMeta,
MetadataStorage,
},
metadata::{gas::GasMetadata, runtime_bindings::RuntimeBindingsMeta, MetadataStorage},
module::NativeModule,
native_assert,
utils::run_pass_manager,
Expand All @@ -15,6 +11,7 @@ use cairo_lang_sierra::{
program::Program,
program_registry::ProgramRegistry,
};
use cairo_lang_sierra_to_casm::metadata::MetadataComputationConfig;
use llvm_sys::target::{
LLVM_InitializeAllAsmPrinters, LLVM_InitializeAllTargetInfos, LLVM_InitializeAllTargetMCs,
LLVM_InitializeAllTargets,
Expand Down
5 changes: 4 additions & 1 deletion src/executor/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use crate::{
error::{panic::ToNativeAssertError, Error, Result},
execution_result::{BuiltinStats, ContractExecutionResult},
executor::{invoke_trampoline, BuiltinCostsGuard},
metadata::{gas::MetadataComputationConfig, runtime_bindings::setup_runtime},
metadata::runtime_bindings::setup_runtime,
module::NativeModule,
native_assert, native_panic,
starknet::{handler::StarknetSyscallHandlerCallbacks, StarknetSyscallHandler},
Expand All @@ -60,6 +60,7 @@ use cairo_lang_sierra::{
program::{GenFunction, Program, StatementIdx},
program_registry::ProgramRegistry,
};
use cairo_lang_sierra_to_casm::metadata::MetadataComputationConfig;
use cairo_lang_starknet_classes::contract_class::ContractEntryPoints;
use cairo_lang_starknet_classes::{
casm_contract_class::ENTRY_POINT_COST, compiler_version::VersionId,
Expand Down Expand Up @@ -206,6 +207,8 @@ impl AotContractExecutor {
.collect(),
linear_gas_solver: no_eq_solver,
linear_ap_change_solver: no_eq_solver,
skip_non_linear_solver_comparisons: false,
compute_runtime_costs: false,
}),
)?;

Expand Down
137 changes: 46 additions & 91 deletions src/metadata/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,20 @@ use cairo_lang_sierra::{
ids::FunctionId,
program::{Program, StatementIdx},
};
use cairo_lang_sierra_ap_change::{ap_change_info::ApChangeInfo, calc_ap_changes};
use cairo_lang_sierra_ap_change::{
compute::calc_ap_changes as linear_calc_ap_changes, ApChangeError,
use cairo_lang_sierra_ap_change::{ap_change_info::ApChangeInfo, ApChangeError};
use cairo_lang_sierra_gas::{gas_info::GasInfo, CostError};
use cairo_lang_sierra_to_casm::metadata::{
calc_metadata, calc_metadata_ap_change_only, Metadata as CairoGasMetadata,
MetadataComputationConfig, MetadataError as CairoGasMetadataError,
};
use cairo_lang_sierra_gas::{
compute_postcost_info, compute_precost_info, gas_info::GasInfo, CostError,
};
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;

use crate::{error::Result as NativeResult, native_panic};

use std::collections::BTreeMap;
use std::{collections::BTreeMap, fmt, ops::Deref};

/// Holds global gas info.
#[derive(Debug, Default, PartialEq, Eq)]
pub struct GasMetadata {
pub ap_change_info: ApChangeInfo,
pub gas_info: GasInfo,
}
#[derive(Default)]
pub struct GasMetadata(pub CairoGasMetadata);

/// The gas cost associated to a determined sierra statement.
///
Expand All @@ -43,15 +38,6 @@ pub struct GasMetadata {
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GasCost(pub Vec<(u64, CostTokenType)>);

/// Configuration for metadata computation.
#[derive(Debug, Clone)]
pub struct MetadataComputationConfig {
pub function_set_costs: OrderedHashMap<FunctionId, OrderedHashMap<CostTokenType, i32>>,
// ignored, its always used
pub linear_gas_solver: bool,
pub linear_ap_change_solver: bool,
}

/// Error for metadata calculations.
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
pub enum GasMetadataError {
Expand All @@ -63,26 +49,18 @@ pub enum GasMetadataError {
NotEnoughGas { gas: Box<(u64, u64)> },
}

impl Default for MetadataComputationConfig {
fn default() -> Self {
Self {
function_set_costs: Default::default(),
linear_gas_solver: true,
linear_ap_change_solver: true,
}
}
}

impl GasMetadata {
pub fn new(
sierra_program: &Program,
config: Option<MetadataComputationConfig>,
) -> Result<GasMetadata, GasMetadataError> {
if let Some(metadata_config) = config {
calc_metadata(sierra_program, metadata_config)
let cairo_gas_metadata = if let Some(metadata_config) = config {
calc_metadata(sierra_program, metadata_config)?
} else {
calc_metadata_ap_change_only(sierra_program)
}
calc_metadata_ap_change_only(sierra_program)?
};

Ok(GasMetadata::from(cairo_gas_metadata))
}

/// Returns the initial value for the gas counter.
Expand Down Expand Up @@ -183,9 +161,32 @@ impl GasMetadata {
}
}

impl From<CairoGasMetadata> for GasMetadata {
fn from(value: CairoGasMetadata) -> Self {
Self(value)
}
}

impl Deref for GasMetadata {
type Target = CairoGasMetadata;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl fmt::Debug for GasMetadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("GasMetadata")
.field("ap_change_info", &self.ap_change_info)
.field("gas_info", &self.gas_info)
.finish()
}
}

impl Clone for GasMetadata {
fn clone(&self) -> Self {
Self {
Self(CairoGasMetadata {
ap_change_info: ApChangeInfo {
variable_values: self.ap_change_info.variable_values.clone(),
function_ap_change: self.ap_change_info.function_ap_change.clone(),
Expand All @@ -194,61 +195,15 @@ impl Clone for GasMetadata {
variable_values: self.gas_info.variable_values.clone(),
function_costs: self.gas_info.function_costs.clone(),
},
}
})
}
}

// Methods from https://github.com/starkware-libs/cairo/blob/fbdbbe4c42a6808eccbff8436078f73d0710c772/crates/cairo-lang-sierra-to-casm/src/metadata.rs#L71

/// Calculates the metadata for a Sierra program, with ap change info only.
fn calc_metadata_ap_change_only(program: &Program) -> Result<GasMetadata, GasMetadataError> {
Ok(GasMetadata {
ap_change_info: calc_ap_changes(program, |_, _| 0)?,
gas_info: GasInfo {
variable_values: Default::default(),
function_costs: Default::default(),
},
})
}

/// Calculates the metadata for a Sierra program.
///
/// `no_eq_solver` uses a linear-time algorithm for calculating the gas, instead of solving
/// equations.
fn calc_metadata(
program: &Program,
config: MetadataComputationConfig,
) -> Result<GasMetadata, GasMetadataError> {
let pre_gas_info = compute_precost_info(program)?;

let ap_change_info = if config.linear_ap_change_solver {
linear_calc_ap_changes
} else {
calc_ap_changes
}(program, |idx, token_type| {
pre_gas_info.variable_values[&(idx, token_type)] as usize
})?;

let enforced_function_costs: OrderedHashMap<FunctionId, i32> = config
.function_set_costs
.iter()
.map(|(func, costs)| (func.clone(), costs[&CostTokenType::Const]))
.collect();
let post_gas_info = compute_postcost_info(
program,
&|idx| {
ap_change_info
.variable_values
.get(idx)
.copied()
.unwrap_or_default()
},
&pre_gas_info,
&enforced_function_costs,
)?;

Ok(GasMetadata {
ap_change_info,
gas_info: pre_gas_info.combine(post_gas_info),
})
impl From<CairoGasMetadataError> for GasMetadataError {
fn from(value: CairoGasMetadataError) -> Self {
match value {
CairoGasMetadataError::ApChangeError(x) => GasMetadataError::ApChangeError(x),
CairoGasMetadataError::CostError(x) => GasMetadataError::CostError(x),
}
}
}
Loading