Skip to content

Commit 7bcb98d

Browse files
implement libfunc_counter
1 parent 4478643 commit 7bcb98d

File tree

8 files changed

+392
-1
lines changed

8 files changed

+392
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ with-cheatcode = []
6161
with-debug-utils = []
6262
with-mem-tracing = []
6363
with-libfunc-profiling = []
64+
with-libfunc-counter = []
6465
with-segfault-catcher = []
6566
with-trace-dump = ["dep:sierra-emu"]
6667

src/bin/cairo-native-run.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use cairo_native::{
1515
starknet_stub::StubSyscallHandler,
1616
};
1717
use clap::{Parser, ValueEnum};
18-
#[cfg(feature = "with-libfunc-profiling")]
18+
#[cfg(any(feature = "with-libfunc-profiling", feature = "with-libfunc-counter"))]
1919
use std::collections::HashMap;
2020
use std::path::PathBuf;
2121
use tracing_subscriber::{EnvFilter, FmtSubscriber};
@@ -57,6 +57,11 @@ struct Args {
5757
/// The output path for the libfunc profilling results
5858
profiler_output: Option<PathBuf>,
5959

60+
#[cfg(feature = "with-libfunc-counter")]
61+
#[arg(long)]
62+
/// The output path for the execution trace
63+
libfunc_counter_output: Option<PathBuf>,
64+
6065
#[cfg(feature = "with-trace-dump")]
6166
#[arg(long)]
6267
/// The output path for the execution trace
@@ -120,6 +125,17 @@ fn main() -> anyhow::Result<()> {
120125
}
121126
}
122127

128+
#[cfg(feature = "with-libfunc-counter")]
129+
{
130+
use cairo_native::metadata::libfunc_counter::LibfuncCounterBinding;
131+
if let Some(counter_id) =
132+
executor.find_symbol_ptr(LibfuncCounterBinding::CounterId.symbol())
133+
{
134+
let counter_id = counter_id.cast::<u64>();
135+
unsafe { *counter_id = 0 };
136+
}
137+
}
138+
123139
Box::new(move |function_id, args, gas, syscall_handler| {
124140
executor.invoke_dynamic_with_syscall_handler(
125141
function_id,
@@ -154,6 +170,17 @@ fn main() -> anyhow::Result<()> {
154170
}
155171
}
156172

173+
#[cfg(feature = "with-libfunc-counter")]
174+
{
175+
use cairo_native::metadata::libfunc_counter::LibfuncCounterBinding;
176+
if let Some(counter_id) =
177+
executor.find_symbol_ptr(LibfuncCounterBinding::CounterId.symbol())
178+
{
179+
let counter_id = counter_id.cast::<u64>();
180+
unsafe { *counter_id = 0 };
181+
}
182+
}
183+
157184
Box::new(move |function_id, args, gas, syscall_handler| {
158185
executor.invoke_dynamic_with_syscall_handler(
159186
function_id,
@@ -186,6 +213,18 @@ fn main() -> anyhow::Result<()> {
186213
.insert(0, ProfilerImpl::new());
187214
}
188215

216+
#[cfg(feature = "with-libfunc-counter")]
217+
{
218+
use cairo_native::metadata::libfunc_counter::libfunc_counter_runtime::{
219+
CounterImpl, LIBFUNC_COUNTER,
220+
};
221+
222+
LIBFUNC_COUNTER.lock().unwrap().insert(
223+
0,
224+
CounterImpl::new(sierra_program.libfunc_declarations.len()),
225+
);
226+
}
227+
189228
let gas_metadata =
190229
GasMetadata::new(&sierra_program, Some(MetadataComputationConfig::default())).unwrap();
191230

@@ -281,6 +320,37 @@ fn main() -> anyhow::Result<()> {
281320
}
282321
}
283322

323+
#[cfg(feature = "with-libfunc-counter")]
324+
if let Some(libfunc_counter_output) = args.libfunc_counter_output {
325+
use std::collections::HashMap;
326+
327+
let counters =
328+
cairo_native::metadata::libfunc_counter::libfunc_counter_runtime::LIBFUNC_COUNTER
329+
.lock()
330+
.unwrap();
331+
assert_eq!(counters.len(), 1);
332+
333+
let libfunc_counter = counters.values().next().unwrap();
334+
335+
let libfunc_counts = libfunc_counter
336+
.array_counter
337+
.iter()
338+
.enumerate()
339+
.map(|(i, count)| {
340+
let libfunc = &sierra_program.libfunc_declarations[i];
341+
let debug_name = libfunc.id.debug_name.clone().unwrap().to_string();
342+
343+
(debug_name, *count)
344+
})
345+
.collect::<HashMap<String, u32>>();
346+
dbg!(&libfunc_counts);
347+
serde_json::to_writer_pretty(
348+
std::fs::File::create(libfunc_counter_output).unwrap(),
349+
&libfunc_counts,
350+
)
351+
.unwrap();
352+
}
353+
284354
#[cfg(feature = "with-trace-dump")]
285355
if let Some(trace_output) = args.trace_output {
286356
let traces = cairo_native::metadata::trace_dump::trace_dump_runtime::TRACE_DUMP

src/compiler.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ use crate::{
6060
utils::{generate_function_name, walk_ir::walk_mlir_block, BlockExt},
6161
};
6262
use bumpalo::Bump;
63+
#[cfg(feature = "with-libfunc-counter")]
64+
use cairo_lang_sierra::ids::ConcreteLibfuncId;
6365
use cairo_lang_sierra::{
6466
edit_state,
6567
extensions::{
@@ -151,6 +153,14 @@ pub fn compile(
151153
let n_libfuncs = program.libfunc_declarations.len() + 1;
152154
let sierra_stmt_start_offset = num_types + n_libfuncs + 1;
153155

156+
#[cfg(feature = "with-libfunc-counter")]
157+
let libfunc_indexes = program
158+
.libfunc_declarations
159+
.iter()
160+
.enumerate()
161+
.map(|(idx, libf)| (libf.id.clone(), idx))
162+
.collect::<HashMap<ConcreteLibfuncId, usize>>();
163+
154164
for function in &program.funcs {
155165
tracing::info!("Compiling function `{}`.", function.id);
156166
compile_func(
@@ -159,6 +169,8 @@ pub fn compile(
159169
registry,
160170
function,
161171
&program.statements,
172+
#[cfg(feature = "with-libfunc-counter")]
173+
&libfunc_indexes,
162174
metadata,
163175
di_compile_unit_id,
164176
sierra_stmt_start_offset,
@@ -186,6 +198,7 @@ fn compile_func(
186198
registry: &ProgramRegistry<CoreType, CoreLibfunc>,
187199
function: &Function,
188200
statements: &[Statement],
201+
#[cfg(feature = "with-libfunc-counter")] libfunc_indexes: &HashMap<ConcreteLibfuncId, usize>,
189202
metadata: &mut MetadataStorage,
190203
di_compile_unit_id: Attribute,
191204
sierra_stmt_start_offset: usize,
@@ -640,6 +653,21 @@ fn compile_func(
640653
},
641654
};
642655

656+
#[cfg(feature = "with-libfunc-counter")]
657+
{
658+
// Can't fail since that would we got a libfunc which is not defined in the program
659+
let libfunc_idx = libfunc_indexes.get(&invocation.libfunc_id).unwrap();
660+
661+
crate::metadata::libfunc_counter::libfunc_counter_runtime::count_libfunc(
662+
context,
663+
module,
664+
block,
665+
location,
666+
metadata,
667+
*libfunc_idx,
668+
)?;
669+
}
670+
643671
libfunc.build(
644672
context,
645673
registry,

src/executor/aot.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ impl AotNativeExecutor {
6363
#[cfg(feature = "with-libfunc-profiling")]
6464
crate::metadata::profiler::setup_runtime(|name| executor.find_symbol_ptr(name));
6565

66+
#[cfg(feature = "with-libfunc-counter")]
67+
crate::metadata::libfunc_counter::setup_runtime(|name| executor.find_symbol_ptr(name));
68+
6669
executor
6770
}
6871

src/executor/contract.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ impl AotContractExecutor {
333333
#[cfg(feature = "with-libfunc-profiling")]
334334
crate::metadata::profiler::setup_runtime(|name| executor.find_symbol_ptr(name));
335335

336+
#[cfg(feature = "with-libfunc-counter")]
337+
crate::metadata::libfunc_counter::setup_runtime(|name| executor.find_symbol_ptr(name));
338+
336339
Ok(Some(executor))
337340
}
338341

src/executor/jit.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ impl<'m> JitNativeExecutor<'m> {
7474
#[cfg(feature = "with-libfunc-profiling")]
7575
crate::metadata::profiler::setup_runtime(|name| executor.find_symbol_ptr(name));
7676

77+
#[cfg(feature = "with-libfunc-counter")]
78+
crate::metadata::libfunc_counter::setup_runtime(|name| executor.find_symbol_ptr(name));
79+
7780
Ok(executor)
7881
}
7982

src/metadata.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod dup_overrides;
2121
pub mod enum_snapshot_variants;
2222
pub mod felt252_dict;
2323
pub mod gas;
24+
pub mod libfunc_counter;
2425
pub mod profiler;
2526
pub mod realloc_bindings;
2627
pub mod runtime_bindings;

0 commit comments

Comments
 (0)