Skip to content

Commit 05443c7

Browse files
Add tracing-texray streaming instrumentation for Aiur proving (#401)
Wraps `AiurSystem::prove` in `aiur/execute` and `aiur/witness` spans and exposes `TracingTexray.init` for Lean callers. Once installed, each tracked span emits `[texray] <name>: <dur> ── RAM Δ +X peak Y` on stderr as it closes (Linux RAM stats), and the full texray graph prints when `aiur/prove` exits.
1 parent da780ae commit 05443c7

7 files changed

Lines changed: 161 additions & 5 deletions

File tree

Cargo.lock

Lines changed: 44 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ itertools = "0.14.0"
1313
indexmap = { version = "2", features = ["rayon"] }
1414
lean-ffi = { git = "https://github.com/argumentcomputer/lean-ffi", rev = "cc98ebf67bf453ac3827cb767f78b13ea674dd6a" }
1515
mimalloc = { version = "0.1", default-features = false }
16-
multi-stark = { git = "https://github.com/argumentcomputer/multi-stark.git", rev = "a8a15ea6aa2890f9f60f32a6e0e5e66afc1535ff" }
16+
multi-stark = { git = "https://github.com/argumentcomputer/multi-stark.git", rev = "9ecab51d553445c0cc7b571af00a76b8a83a6f8c" }
1717
num-bigint = "0.4.6"
1818
rayon = "1"
1919
rustc-hash = "2"
@@ -27,8 +27,9 @@ iroh = { version = "0.97", optional = true }
2727
iroh-base = { version = "0.97", optional = true }
2828
n0-error = { version = "0.1", optional = true }
2929
getrandom = { version = "0.3", optional = true }
30-
tracing = { version = "0.1", optional = true }
31-
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
30+
tracing = "0.1"
31+
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
32+
tracing-texray = { git = "https://github.com/argumentcomputer/tracing-texray", rev = "8ce04e3422cd48e68ef47fab95dba7d06b8c368c" }
3233
bincode = { version = "2.0.1", optional = true }
3334
serde = { version = "1.0.219", features = ["derive"], optional = true }
3435

@@ -41,7 +42,7 @@ quickcheck_macros = "1.0.0"
4142
default = []
4243
parallel = ["multi-stark/parallel"]
4344
test-ffi = []
44-
net = ["bytes", "tokio", "iroh", "iroh-base", "n0-error", "getrandom", "tracing", "tracing-subscriber", "bincode", "serde" ]
45+
net = ["bytes", "tokio", "iroh", "iroh-base", "n0-error", "getrandom", "bincode", "serde" ]
4546

4647
[profile.dev]
4748
panic = "abort"

Ix.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ public import Ix.Claim
1515
public import Ix.Commit
1616
public import Ix.Benchmark.Bench
1717
public import Ix.Aiur
18+
public import Ix.TracingTexray

Ix/TracingTexray.lean

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/-
2+
tracing-texray + streaming Lean API.
3+
4+
The Rust prover emits `tracing` spans for each major Aiur proving stage
5+
(`aiur/execute`, `aiur/witness`, `aiur/prove`) and each STARK proving
6+
stage (`stark/...`). After `init` installs the subscriber:
7+
* a one-line `[texray] <span>: <dur> ── RAM Δ +X peak Y` is streamed
8+
to stderr as each tracked span closes (when `streaming = true`);
9+
* the full texray graph (with RAM block, Linux-only) prints when
10+
`aiur/prove` exits.
11+
-/
12+
13+
module
14+
15+
public section
16+
17+
namespace TracingTexray
18+
19+
/-- Configuration for the tracing-texray subscriber. -/
20+
structure Settings where
21+
/-- Comma-separated span-name prefixes to keep
22+
(default `"aiur/,stark/"`; empty string disables filtering). -/
23+
namePrefixes : String := "aiur/,stark/"
24+
/-- Sample VmRSS/VmHWM per span. Linux-only; zeros elsewhere. -/
25+
trackRam : Bool := true
26+
/-- Emit per-span `[texray] <name>: <dur> ── RAM Δ +X peak Y` lines
27+
on stderr as each span closes. The texray graph prints either way
28+
when the examined root span exits. -/
29+
streaming : Bool := true
30+
31+
@[extern "rs_texray_init"]
32+
private opaque initWith
33+
(namePrefixes : @& String)
34+
(trackRam : Bool)
35+
(streaming : Bool) : IO Unit
36+
37+
/-- Install the global tracing-texray subscriber with the given settings.
38+
Idempotent: subsequent calls are no-ops once installed. -/
39+
def init (s : Settings := {}) : IO Unit :=
40+
initWith s.namePrefixes s.trackRam s.streaming
41+
42+
end TracingTexray
43+
44+
end

src/aiur/synthesis.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,28 @@ impl AiurSystem {
109109
AiurSystem { system, key, toplevel }
110110
}
111111

112+
#[tracing::instrument(level = "info", skip_all, name = "aiur/prove")]
112113
pub fn prove(
113114
&self,
114115
fri_parameters: FriParameters,
115116
fun_idx: FunIdx,
116117
input: &[G],
117118
io_buffer: &mut IOBuffer,
118119
) -> (Vec<G>, Proof) {
120+
tracing_texray::examine_current();
121+
122+
// Execute the Aiur bytecode.
123+
let _g = tracing::info_span!("aiur/execute").entered();
119124
// Execute the Aiur bytecode. The prover assumes inputs are valid; any
120125
// execution error here is a programmer bug, so we unwrap.
121126
let (query_record, output) = self
122127
.toplevel
123128
.execute(fun_idx, input.to_vec(), io_buffer)
124129
.expect("Aiur execution failed during prove");
130+
drop(_g);
125131

126132
// Build the `SystemWitness`
133+
let _g = tracing::info_span!("aiur/witness").entered();
127134
let functions =
128135
(0..self.toplevel.functions.len()).into_par_iter().filter_map(|idx| {
129136
if self.toplevel.functions[idx].constrained {
@@ -155,6 +162,7 @@ impl AiurSystem {
155162
drop(query_record); // Early drop to free memory.
156163
let (traces, lookups) = witness_data.into_iter().unzip();
157164
let witness = SystemWitness { traces, lookups };
165+
drop(_g);
158166

159167
// Construct the claim.
160168
let mut claim = vec![function_channel(), G::from_usize(fun_idx)];

src/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod byte_array;
1414
pub mod iroh;
1515
pub mod keccak;
1616
pub mod lean_env;
17+
pub mod texray;
1718
pub mod unsigned;
1819

1920
// Modular FFI structure

src/ffi/texray.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//! FFI shim for installing the `tracing-texray` subscriber from Lean.
2+
//!
3+
//! With `streaming = true`, each tracked span (e.g. `aiur/execute`,
4+
//! `aiur/witness`, `aiur/prove`) emits a one-line `[texray] <name>: <dur>
5+
//! ── RAM Δ +X peak Y` to stderr as it closes, and the full texray
6+
//! graph prints when the examined root span exits.
7+
8+
use lean_ffi::object::{LeanBorrowed, LeanIOResult, LeanOwned, LeanString};
9+
use tracing_subscriber::{
10+
Layer, Registry, filter::FilterFn, layer::SubscriberExt,
11+
util::SubscriberInitExt,
12+
};
13+
14+
/// Install the `tracing-texray` subscriber as the global default.
15+
///
16+
/// Idempotent: subsequent calls are no-ops once the global subscriber has
17+
/// been set.
18+
///
19+
/// Parameters:
20+
/// - `name_prefixes`: comma-separated list of span-name prefixes to render
21+
/// (e.g. `"aiur/,stark/"`). Empty string disables filtering and renders
22+
/// everything, including upstream library spans.
23+
/// - `track_ram`: sample VmRSS/VmHWM per span. Linux-only; zeros elsewhere.
24+
/// - `streaming`: emit per-span `[texray] <name>: <dur> ── RAM Δ +X peak Y`
25+
/// lines on stderr as each span closes. The texray graph prints either
26+
/// way when the examined root span exits.
27+
#[unsafe(no_mangle)]
28+
extern "C" fn rs_texray_init(
29+
name_prefixes: LeanString<LeanBorrowed<'_>>,
30+
track_ram: bool,
31+
streaming: bool,
32+
) -> LeanIOResult<LeanOwned> {
33+
let prefixes: Vec<String> = name_prefixes
34+
.to_string()
35+
.split(',')
36+
.map(|s| s.trim().to_string())
37+
.filter(|s| !s.is_empty())
38+
.collect();
39+
40+
let mut layer = tracing_texray::TeXRayLayer::new();
41+
if track_ram {
42+
layer = layer.track_ram();
43+
}
44+
if streaming {
45+
layer = layer.streaming();
46+
}
47+
48+
let filter = FilterFn::new(move |metadata| {
49+
if !metadata.is_span() || prefixes.is_empty() {
50+
return true;
51+
}
52+
let name = metadata.name();
53+
prefixes.iter().any(|p| name.starts_with(p.as_str()))
54+
});
55+
56+
let _ = Registry::default().with(layer.with_filter(filter)).try_init();
57+
LeanIOResult::ok(LeanOwned::box_usize(0))
58+
}

0 commit comments

Comments
 (0)