Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
ratankaliani committed Aug 7, 2024
1 parent d97b7f0 commit e8ad538
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 40 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
// // Examples.
// "examples/chess/program/Cargo.toml",
// "examples/chess/script/Cargo.toml",
// "examples/cycle-tracking/program/Cargo.toml",
// "examples/cycle-tracking/script/Cargo.toml",
// "examples/fibonacci/program/Cargo.toml",
// "examples/fibonacci/script/Cargo.toml",
// "examples/io/program/Cargo.toml",
Expand Down
2 changes: 1 addition & 1 deletion book/writing-programs/cycle-tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ When writing a program, it is useful to know how many RISC-V cycles a portion of
To track the number of cycles spent in a portion of the program, you can either put `println!("cycle-tracker-start: block name")` + `println!("cycle-tracker-end: block name")` statements (block name must be same between start and end) around the portion of your program you want to profile or use the `#[sp1_derive::cycle_tracker]` macro on a function. An example is shown below:

```rust,noplayground
{{#include ../../examples/cycle-tracking/program/src/main.rs}}
{{#include ../../examples/cycle-tracking/program/bin/normal.rs}}
```

Note that to use the macro, you must add the `sp1-derive` crate to your dependencies for your program.
Expand Down
19 changes: 9 additions & 10 deletions core/src/syscall/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,16 @@ enum CycleTrackerCommand {

/// Parse a cycle tracker command from a string. If the string does not match any known command, returns None.
fn parse_cycle_tracker_command(s: &str) -> Option<CycleTrackerCommand> {
if let Some((command, fn_name)) = s.split_once(':') {
let trimmed_name = fn_name.trim().to_string();
match command {
"cycle-tracker-start" => Some(CycleTrackerCommand::Start(trimmed_name)),
"cycle-tracker-end" => Some(CycleTrackerCommand::End(trimmed_name)),
"cycle-tracker-report-start" => Some(CycleTrackerCommand::ReportStart(trimmed_name)),
"cycle-tracker-report-end" => Some(CycleTrackerCommand::ReportEnd(trimmed_name)),
_ => None,
};
let (command, fn_name) = s.split_once(':')?;
let trimmed_name = fn_name.trim().to_string();

match command {
"cycle-tracker-start" => Some(CycleTrackerCommand::Start(trimmed_name)),
"cycle-tracker-end" => Some(CycleTrackerCommand::End(trimmed_name)),
"cycle-tracker-report-start" => Some(CycleTrackerCommand::ReportStart(trimmed_name)),
"cycle-tracker-report-end" => Some(CycleTrackerCommand::ReportEnd(trimmed_name)),
_ => None,
}
None
}

/// Handle a cycle tracker command.
Expand Down
8 changes: 8 additions & 0 deletions examples/cycle-tracking/program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ version = "1.1.0"
edition = "2021"
publish = false

[[bin]]
name = "normal"
path = "bin/normal.rs"

[[bin]]
name = "report"
path = "bin/report.rs"

[dependencies]
sp1-zkvm = { path = "../../../zkvm/entrypoint" }
sp1-derive = { path = "../../../derive" }
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ pub fn main() {
let mut nums = vec![1, 1];

// Setup a large vector with Fibonacci-esque numbers.
println!("cycle-tracker-report-start: setup");
println!("cycle-tracker-start: setup");
for _ in 0..100 {
let mut c = nums[nums.len() - 1] + nums[nums.len() - 2];
c %= 7919;
nums.push(c);
}
println!("cycle-tracker-report-end: setup");
println!("cycle-tracker-end: setup");

println!("cycle-tracker-start: main-body");
for i in 0..2 {
Expand Down
25 changes: 25 additions & 0 deletions examples/cycle-tracking/program/bin/report.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#![no_main]
sp1_zkvm::entrypoint!(main);

#[sp1_derive::cycle_tracker]
pub fn expensive_function(x: usize) -> usize {
let mut y = 1;
for _ in 0..100 {
y *= x;
y %= 7919;
}
y
}

pub fn main() {
let mut nums = vec![1, 1];

// Setup a large vector with Fibonacci-esque numbers.
println!("cycle-tracker-report-start: setup");
for _ in 0..100 {
let mut c = nums[nums.len() - 1] + nums[nums.len() - 2];
c %= 7919;
nums.push(c);
}
println!("cycle-tracker-report-end: setup");
}
File renamed without changes.
Binary file added examples/cycle-tracking/program/elf/report
Binary file not shown.
18 changes: 16 additions & 2 deletions examples/cycle-tracking/script/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
use sp1_helper::build_program;
use sp1_helper::{build_program_with_args, BuildArgs};

fn main() {
build_program("../program")
build_program_with_args(
"../program",
BuildArgs {
binary: "report".to_string(),
..Default::default()
},
);

build_program_with_args(
"../program",
BuildArgs {
binary: "normal".to_string(),
..Default::default()
},
);
}
48 changes: 23 additions & 25 deletions examples/cycle-tracking/script/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use sp1_sdk::{utils, ProverClient, SP1ProofWithPublicValues, SP1Stdin};

/// The ELF we want to execute inside the zkVM.
const ELF: &[u8] = include_bytes!("../../program/elf/riscv32im-succinct-zkvm-elf");
/// The ELF with normal cycle tracking.
const NORMAL_ELF: &[u8] = include_bytes!("../../program/elf/normal");

/// The ELF with cycle tracking that gets added to the execution report.
const REPORT_ELF: &[u8] = include_bytes!("../../program/elf/report");

fn main() {
// Setup a tracer for logging.
Expand All @@ -10,29 +13,24 @@ fn main() {
// Create an input stream.
let stdin = SP1Stdin::new();

// Generate the proof for the given program.
// Generate the proof for the cycle tracking program.
let client = ProverClient::new();
let (_, report) = client.execute(ELF, stdin.clone()).run().expect("execution failed");

println!("{}", report.cycle_tracker.get("setup").unwrap());

let (pk, vk) = client.setup(ELF);
let proof = client.prove(&pk, stdin).run().expect("proving failed");

// Verify proof.
client.verify(&proof, &vk).expect("verification failed");

// Test a round trip of proof serialization and deserialization.
proof
.save("proof-with-pis.bin")
.expect("saving proof failed");
let deserialized_proof =
SP1ProofWithPublicValues::load("proof-with-pis.bin").expect("loading proof failed");

// Verify the deserialized proof.
client
.verify(&deserialized_proof, &vk)
.expect("verification failed");

println!("successfully generated and verified proof for the program!")
// Execute the normal ELF, which shows the cycle tracking.
let (_, report) = client
.execute(NORMAL_ELF, stdin.clone())
.run()
.expect("execution failed");

// Execute the report ELF, and print the tracked cycles added to the report.
let (_, report) = client
.execute(REPORT_ELF, stdin.clone())
.run()
.expect("execution failed");

// Print the cycles added to the report.
// Print all the keys from report.cycle_tracker.
for (key, value) in report.cycle_tracker {
println!("{}: {}", key, value);
}
}

0 comments on commit e8ad538

Please sign in to comment.