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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# Scaffolding from running `init` in the repo root (the tool profiling itself)
/cu-profiler.toml
/examples/
/bench.toml

# Local-only tooling and agent config — intentionally not shared
.gate/
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- `cu-profiler init` now scaffolds a starter `bench.toml` for the turnkey real-CU
path, so `cu-profiler bench` is discoverable and validates out of the box.

## [0.2.0] - 2026-06-21

### Added
Expand Down
21 changes: 21 additions & 0 deletions crates/cu-profiler-cli/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,26 @@ pub fn swap_exact_in() -> Scenario {
}
"#;

const BENCH_TOML: &str = r#"# bench.toml — the turnkey real-CU path (`cu-profiler bench`).
#
# Declare the instruction(s) to run against your compiled SBF program so that
# cu-profiler bench --program-name <your_program>
# meters their REAL compute units (via the Linux `cu-profiler-bench` executor).
# Replace the placeholder program_id with your program's address, and add the
# accounts and instruction data your program needs.

[[instruction]]
scenario = "swap_exact_in"
program_id = "11111111111111111111111111111111" # <-- replace with your program id
data = "" # hex instruction data ("" = no args)

# [[instruction.account]]
# pubkey = "11111111111111111111111111111111"
# signer = true
# writable = true
# lamports = 1000000
"#;

const WORKFLOW: &str = r#"name: CU Profiler

on:
Expand Down Expand Up @@ -148,6 +168,7 @@ pub fn run(args: &InitArgs, quiet: bool) -> Result<ExitCode> {
args.force,
quiet,
)?;
write_file(&dir.join("bench.toml"), BENCH_TOML, args.force, quiet)?;
if args.workflow {
write_file(
&dir.join(".github/workflows/cu-profiler.yml"),
Expand Down
23 changes: 23 additions & 0 deletions crates/cu-profiler-cli/tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,29 @@ fn import_file_without_logs_reports_error() {
assert!(!dir.join(".cu/logs/empty.log").exists());
}

#[test]
fn init_scaffolds_a_valid_bench_toml() {
let dir = scratch_dir("init-bench");
assert!(run(&dir, &["init"]).status.success());

// `init` writes a starter bench.toml, and it must pass `bench`'s validation
// out of the box (so the turnkey path is discoverable and correct by default).
assert!(
dir.join("bench.toml").exists(),
"init should scaffold bench.toml"
);
let out = run(&dir, &["bench"]); // defaults to --fixtures bench.toml
assert!(
out.status.success(),
"scaffolded bench.toml should validate: {out:?}"
);
assert!(
String::from_utf8_lossy(&out.stdout).contains("bench plan OK"),
"stdout: {}",
String::from_utf8_lossy(&out.stdout)
);
}

#[test]
fn bench_validates_a_plan_and_summarises() {
let dir = scratch_dir("bench-ok");
Expand Down
1 change: 1 addition & 0 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,7 @@ cu-profiler.toml
.cu/baseline.json (if desired)
.github/workflows/cu-profiler.yml (if flag)
examples/scenarios.rs
bench.toml (starter plan for the turnkey real-CU path)
```

### `cu-profiler run`
Expand Down