Skip to content

Commit 0ea118f

Browse files
feat: E2E benchmark halo2 generate flamegraphs (#1203)
1 parent 2b28364 commit 0ea118f

File tree

12 files changed

+52
-16
lines changed

12 files changed

+52
-16
lines changed

benchmarks/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pprof = { version = "0.13", features = [
5656

5757
[features]
5858
default = ["parallel", "mimalloc", "bench-metrics"]
59-
bench-metrics = ["openvm-native-recursion/bench-metrics"]
59+
bench-metrics = ["openvm-native-recursion/bench-metrics", "openvm-native-compiler/bench-metrics"]
6060
profiling = ["openvm-sdk/profiling"]
6161
aggregation = []
6262
static-verifier = ["openvm-native-recursion/static-verifier"]

benchmarks/src/utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ impl BenchmarkCli {
122122
halo2_config: Halo2Config {
123123
verifier_k: self.halo2_outer_k.unwrap_or(24),
124124
wrapper_k: self.halo2_wrapper_k,
125+
profiling: self.profiling,
125126
},
126127
}
127128
}

ci/scripts/metric_unify/flamegraph.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,25 @@
66

77
from utils import FLAMEGRAPHS_DIR, get_git_root
88

9-
def get_stack_lines(metrics_dict, group_by_kvs, stack_keys, metric_name):
9+
def get_stack_lines(metrics_dict, group_by_kvs, stack_keys, metric_name, sum_metrics=None):
1010
"""
1111
Filters a metrics_dict obtained from json for entries that look like:
1212
[ { labels: [["key1", "span1;span2"], ["key2", "span3"]], "metric": metric_name, "value": 2 } ]
1313
1414
It will find entries that have all of stack_keys as present in the labels and then concatenate the corresponding values into a single flat stack entry and then add the value at the end.
1515
It will write a file with one line each for flamegraph.pl or inferno-flamegraph to consume.
16+
If sum_metrics is not None, instead of searching for metric_name, it will sum the values of the metrics in sum_metrics.
1617
"""
1718
lines = []
19+
stack_sums = {}
20+
non_zero = False
1821

1922
# Process counters
2023
for counter in metrics_dict.get('counter', []):
21-
if counter['metric'] != metric_name:
24+
if (sum_metrics is not None and counter['metric'] not in sum_metrics) or \
25+
(sum_metrics is None and counter['metric'] != metric_name):
2226
continue
27+
2328
# list of pairs -> dict
2429
labels = dict(counter['labels'])
2530
filter = False
@@ -41,15 +46,21 @@ def get_stack_lines(metrics_dict, group_by_kvs, stack_keys, metric_name):
4146

4247
stack = ';'.join(stack_values)
4348
value = int(counter['value'])
49+
stack_sums[stack] = stack_sums.get(stack, 0) + value
50+
51+
if value != 0:
52+
non_zero = True
4453

45-
lines.append(f"{stack} {value}")
54+
lines = [f"{stack} {value}" for stack, value in stack_sums.items() if value != 0]
4655

4756
# Currently cycle tracker does not use gauge
48-
return lines
57+
return lines if non_zero else []
4958

5059

51-
def create_flamegraph(fname, metrics_dict, group_by_kvs, stack_keys, metric_name, reverse=False):
52-
lines = get_stack_lines(metrics_dict, group_by_kvs, stack_keys, metric_name)
60+
def create_flamegraph(fname, metrics_dict, group_by_kvs, stack_keys, metric_name, sum_metrics=None, reverse=False):
61+
lines = get_stack_lines(metrics_dict, group_by_kvs, stack_keys, metric_name, sum_metrics)
62+
if not lines:
63+
return
5364

5465
suffixes = [key for key in stack_keys if key != "cycle_tracker_span"]
5566

@@ -74,7 +85,7 @@ def create_flamegraph(fname, metrics_dict, group_by_kvs, stack_keys, metric_name
7485
print(f"Created flamegraph at {flamegraph_path}")
7586

7687

77-
def create_flamegraphs(metrics_file, group_by, stack_keys, metric_name, reverse=False):
88+
def create_flamegraphs(metrics_file, group_by, stack_keys, metric_name, sum_metrics=None, reverse=False):
7889
fname_prefix = os.path.splitext(os.path.basename(metrics_file))[0]
7990

8091
with open(metrics_file, 'r') as f:
@@ -92,7 +103,7 @@ def create_flamegraphs(metrics_file, group_by, stack_keys, metric_name, reverse=
92103
for group_by_values in group_by_values_list:
93104
group_by_kvs = list(zip(group_by, group_by_values))
94105
fname = fname_prefix + '-' + '-'.join(group_by_values)
95-
create_flamegraph(fname, metrics_dict, group_by_kvs, stack_keys, metric_name, reverse=reverse)
106+
create_flamegraph(fname, metrics_dict, group_by_kvs, stack_keys, metric_name, sum_metrics, reverse=reverse)
96107

97108

98109
def create_custom_flamegraphs(metrics_file, group_by=["group"]):
@@ -101,6 +112,9 @@ def create_custom_flamegraphs(metrics_file, group_by=["group"]):
101112
reverse=reverse)
102113
create_flamegraphs(metrics_file, group_by, ["cycle_tracker_span", "dsl_ir", "opcode", "air_name"], "cells_used",
103114
reverse=reverse)
115+
create_flamegraphs(metrics_file, group_by, ["cell_tracker_span"], "cells_used",
116+
sum_metrics=["simple_advice_cells", "fixed_cells", "lookup_advice_cells"],
117+
reverse=reverse)
104118

105119

106120
def main():

crates/sdk/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ default = ["parallel"]
5050
bench-metrics = [
5151
"openvm-circuit/bench-metrics",
5252
"openvm-native-recursion/bench-metrics",
53+
"openvm-native-compiler/bench-metrics",
5354
]
5455
profiling = ["openvm-circuit/function-span", "openvm-transpiler/function-span"]
5556
parallel = ["openvm-circuit/parallel"]

crates/sdk/src/config/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ pub struct Halo2Config {
4949
pub verifier_k: usize,
5050
/// If not specified, keygen will tune wrapper_k automatically.
5151
pub wrapper_k: Option<usize>,
52+
/// Sets the profiling mode of halo2 VM
53+
pub profiling: bool,
5254
}
5355

5456
impl<VC> AppConfig<VC> {
@@ -101,6 +103,7 @@ impl Default for AggConfig {
101103
halo2_config: Halo2Config {
102104
verifier_k: 24,
103105
wrapper_k: None,
106+
profiling: false,
104107
},
105108
}
106109
}

crates/sdk/src/keygen/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pub struct Halo2ProvingKey {
7676
pub verifier: Halo2VerifierProvingKey,
7777
/// Wrapper circuit to verify static verifier and reduce the verification costs in the final proof.
7878
pub wrapper: Halo2WrapperProvingKey,
79+
/// Whether to collect detailed profiling metrics
80+
pub profiling: bool,
7981
}
8082

8183
impl<VC: VmConfig<F>> AppProvingKey<VC>
@@ -315,7 +317,11 @@ impl AggProvingKey {
315317
} else {
316318
Halo2WrapperProvingKey::keygen_auto_tune(reader, dummy_snark)
317319
};
318-
let halo2_pk = Halo2ProvingKey { verifier, wrapper };
320+
let halo2_pk = Halo2ProvingKey {
321+
verifier,
322+
wrapper,
323+
profiling: halo2_config.profiling,
324+
};
319325
Self {
320326
agg_stark_pk,
321327
halo2_pk,

crates/sdk/src/prover/halo2.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@ impl Halo2Prover {
3030
pub fn prove_for_evm(&self, root_proof: &Proof<RootSC>) -> EvmProof {
3131
let mut witness = Witness::default();
3232
root_proof.write(&mut witness);
33-
let snark = info_span!("prove", group = "halo2_outer")
34-
.in_scope(|| self.halo2_pk.verifier.prove(&self.verifier_srs, witness));
33+
let snark = info_span!("prove", group = "halo2_outer").in_scope(|| {
34+
self.halo2_pk
35+
.verifier
36+
.prove(&self.verifier_srs, witness, self.halo2_pk.profiling)
37+
});
3538
info_span!("prove_for_evm", group = "halo2_wrapper").in_scope(|| {
3639
self.halo2_pk
3740
.wrapper

crates/sdk/tests/integration_test.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ fn agg_config_for_test() -> AggConfig {
9090
halo2_config: Halo2Config {
9191
verifier_k: 24,
9292
wrapper_k: None,
93+
profiling: false,
9394
},
9495
}
9596
}

extensions/native/recursion/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static-verifier = [
4646
"dep:once_cell",
4747
]
4848
test-utils = ["openvm-circuit/test-utils"]
49-
bench-metrics = ["dep:metrics", "openvm-circuit/bench-metrics"]
49+
bench-metrics = ["dep:metrics", "openvm-circuit/bench-metrics", "openvm-native-compiler/bench-metrics"]
5050
mimalloc = ["openvm-stark-backend/mimalloc"]
5151
jemalloc = ["openvm-stark-backend/jemalloc"]
5252
nightly-features = ["openvm-circuit/nightly-features"]

extensions/native/recursion/src/halo2/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,14 +199,15 @@ impl Halo2Prover {
199199
pk: &ProvingKey<G1Affine>,
200200
dsl_operations: DslOperations<C>,
201201
witness: Witness<C>,
202+
profiling: bool,
202203
) -> Snark {
203204
let k = config_params.k;
204205
#[cfg(feature = "bench-metrics")]
205206
let start = std::time::Instant::now();
206207
let builder = Self::builder(CircuitBuilderStage::Prover, k)
207208
.use_params(config_params)
208209
.use_break_points(break_points);
209-
let builder = Self::populate(builder, dsl_operations, witness, false);
210+
let builder = Self::populate(builder, dsl_operations, witness, profiling);
210211
#[cfg(feature = "bench-metrics")]
211212
{
212213
let stats = builder.statistics();

0 commit comments

Comments
 (0)