IsingMark is a Rust CLI that benchmarks quip Ising miner binaries. It acts as a coordinator. It spawns a miner over a Unix socket and feeds it consensus-identical problems, then records the results as JSONL plus a summary JSON. It does not join a chain and does not submit work.
Toolchain: Rust 1.97.1 (rust-toolchain.toml). Also requires protoc
(brew install protobuf, or apt-get install protobuf-compiler):
quip-proto generates its bindings at build time with prost-build, which
shells out to protoc.
cargo build
cargo build --release
cargo build --features plot # optional PNG plots via plottersInstall the binary on $PATH:
cargo install --path .# Default: real miner binaries must be on $PATH, or tests that need them FAIL
cargo test --all-targets
# Download released miners into miners/ (pinned to QUIP_MINER_REV):
./tools/fetch-miners.sh
export PATH="$(pwd)/miners:${PATH}"
# Local machines without a usable quip-cpu-sa:
ISINGMARK_ALLOW_MISSING_MINERS=1 cargo test --all-targets
# Plot tests (PNG generation):
ISINGMARK_ALLOW_MISSING_MINERS=1 cargo test --all-targets --features plotWithout ISINGMARK_ALLOW_MISSING_MINERS=1, a missing quip-cpu-sa (and related miners) makes those tests fail rather than skip. Set the variable only when you intend to opt out of real-binary coverage.
tools/fetch-miners.sh downloads each miner from its own GitLab package registry and checks that every binary can run on this host. Binaries that fail the host probe move to miners/unusable/ so miners/ on PATH holds only runners that work here. Cpu package assets are Linux ELFs with the arch in the name only, so macOS moves them to unusable/ and quip_cpu_sa_conformance still needs ISINGMARK_ALLOW_MISSING_MINERS=1. Metal miners are usable on Darwin. Each repo's version is resolved independently as the newest semver that repo publishes, so a release in one repo does not wait on any other. MINERS_ALLOW_PRERELEASE defaults to 1, which makes prereleases candidates. Setting it to 0 excludes prereleases entirely. With the flag on, a prerelease of a newer core version wins over an older stable, so v0.3.1-rc1 beats v0.3.0. With it off, prereleases are dropped rather than demoted. A repo that publishes no stable tag fails to resolve under MINERS_ALLOW_PRERELEASE=0. Pass through MINER_SET and DRY_RUN. An inherited MINERS_TAG is ignored with a warning, because one tag cannot express a per-repo answer. Network-free check: tools/fetch-miners.sh --select-version TAG....
cargo fmt --check
cargo clippy --all-targets -- -D warnings
cargo clippy --all-targets --features plot -- -D warningsDenied lints include unsafe_code, clippy::panic, clippy::unwrap_used, clippy::print_stdout, clippy::print_stderr, and clippy::allow_attributes. Prefer #[expect(..., reason = "...")] over #[allow(...)].
isingmark --help
isingmark throughput --backend cpu-sa --topology-preset smoke --duration 30s
isingmark sweep --backend cpu-sa --topology-preset smoke \
--param-grid '{"num_reads":[64,128],"num_sweeps":[100,500]}' --num-jobs 5
isingmark ttt --backend cpu-sa --topology-preset smoke \
--energy-targets "-5,-10" --num-trials 5
isingmark comparative --backend cpu-sa --topology-preset smoke \
--target-file path/to/records.jsonl
isingmark scaling --backend cpu-sa --sizes 8,16 --num-jobs 5
isingmark reproducibility --backend cpu-sa --topology-preset smoke --num-problems 10
isingmark compare --file-a a.jsonl --file-b b.jsonlOptional PNG plots (requires --features plot at build time):
isingmark sweep ... --plot out/sweep.png
isingmark ttt ... --plot out/ttt.png
isingmark compare --file-a a.jsonl --file-b b.jsonl --plot out/cdfs.pngWithout the plot feature, --plot still parses and exits non-zero with a rebuild message.
YAML config files under examples/configs/ can supply the same fields. Explicit flags override the file. Built-in defaults apply when both are absent.
src/
main.rs, cli.rs clap subcommands; --config YAML; flags override file
config.rs YAML load and merge
topology.rs TopologySpec JSON load and topology hash
problem.rs seed -> blake3 salt -> derive_nonce -> draw_ising_milli
corpus.rs replay chain-harvested nonces -> draw_ising_milli
backend/ registry + coordinator session loop over UDS
params.rs hardness [0,1] -> JobParams per BackendKind
record.rs JobRecord JSONL and Summary JSON
stats/ percentiles, KS distance, two-sample KS p-value
modes/ throughput, sweep, comparative, ttt, scaling,
reproducibility, compare
report/ text tables; plot.rs behind the plot feature
Pinned git deps (rev in Cargo.toml): quip-proto, quip-protocol, quip-miner-core from https://gitlab.com/quip.network/quip-miner.git.
Local override: copy .cargo/config.toml.example to .cargo/config.toml (gitignored) to patch those crates to a local checkout. While the patch is active, cargo rewrites Cargo.lock to path sources. Before commit, confirm three git sources remain:
rg -c 'source = "git\+https://gitlab.com/quip.network/quip-miner' Cargo.lock
# expect 3Prefer deleting .cargo/config.toml when you are not co-developing upstream.
- Backend: add a registry entry in
src/backend/registry.rspointing at a miner binary that speaks the quip session protocol. New annealers are miner binaries, not in-process adapters. - Topology: ship a JSON
TopologySpecunderfixtures/or pass--topology-file. - Dataset: ship a JSONL corpus of chain nonces under
corpora/. Add it tocorpus::BUNDLEDpaired with its fixture. Pin that fixture'stopology_hashintests/topology.rs. Seedocs/datasets.md. - Mode: add a module under
src/modes/, a clap subcommand insrc/cli.rs, and a branch insrc/main.rs. - Params: edit
ParamCurvedefaults or supplyparam_curvein YAML for hardness mapping.
| Mode | Measures |
|---|---|
throughput |
Jobs per minute over a fixed duration at fixed hardness. --corpus replays a chain dataset instead of deriving problems from --seed; the corpus is finite, so --duration becomes an upper bound |
sweep |
Grid over num_reads x num_sweeps or anneal_time_us |
comparative |
Hardness search that matches a reference energy distribution |
ttt |
Time-to-target per energy level |
scaling |
Fixed hardness across node counts |
reproducibility |
Two-sample KS on two identical-problem batches |
compare |
Post-hoc KS on two JSONL result files (no miner spawn) |
Built-in backends: cpu-sa, cpu-gibbs, cpu-fsa, cpu-msa, cpu-sb, cpu-bsb, cpu-hdsb, cpu-hbsb, cpu-gbsb, cpu-gdsb, cpu-tedsb, cpu-sbqa, cpu-ggdsb, cpu-mps, cpu-mfa, cpu-flatiron, cuda, cuda-gibbs, metal, dwave, beit, cuopt.
Of the CPU kernels, cpu-sa, cpu-gibbs, and cpu-sb ship as release assets. The other thirteen build behind the experimental feature of quip-miner-cpu and reach PATH only when someone builds them on purpose:
cargo build --release --features experimentalbeit (quip-beit-sa) and cuopt (quip-cuopt-milp) are not published as release assets, so tools/fetch-miners.sh cannot supply them. Build them from quip.network/ising-solver-beit (Rust) and quip.network/ising-solver-nvidia (Python), then put the binaries on PATH. Both need an external resource to run jobs: beit needs BEIT_CUSTOMER_KEY and bills per sample, cuopt needs a self-hosted cuOpt server.
AGPL-3.0-or-later
ALWAYS use non-interactive flags with file operations to avoid hanging on confirmation prompts.
Shell commands like cp, mv, and rm may be aliased to include -i (interactive) mode on some systems, causing the agent to hang indefinitely waiting for y/n input.
Use these forms instead:
# Force overwrite without prompting
cp -f source dest # NOT: cp source dest
mv -f source dest # NOT: mv source dest
rm -f file # NOT: rm file
# For recursive operations
rm -rf directory # NOT: rm -r directory
cp -rf source dest # NOT: cp -r source destOther commands that may prompt:
scp- use-o BatchMode=yesfor non-interactivessh- use-o BatchMode=yesto fail instead of promptingapt-get- use-yflagbrew- useHOMEBREW_NO_AUTO_UPDATE=1env var
This project uses bd (beads) for issue tracking. Run bd prime to see full workflow context and commands.
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work
bd close <id> # Complete work- Use
bdfor ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists - Run
bd primefor detailed command reference and session close protocol - Use
bd rememberfor persistent knowledge — do NOT use MEMORY.md files
Architecture in one line: issues live in a local Dolt DB; sync uses refs/dolt/data on your git remote; .beads/issues.jsonl is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.
The managed Beads block is task-tracking guidance, not permission to override repository, user, or orchestrator instructions.
- Conservative (default): Use
bdfor task tracking. Do not run git commits, git pushes, or Dolt remote sync unless explicitly asked. At handoff, report changed files, validation, and suggested next commands. - Minimal: Keep tool instruction files as pointers to
bd prime; use the same conservative git policy unless active instructions say otherwise. - Team-maintainer: Only when the repository explicitly opts in, agents may close beads, run quality gates, commit, and push as part of session close. A current "do not commit" or "do not push" instruction still wins.
This protocol applies when ending a Beads implementation workflow. It is subordinate to explicit user, repository, and orchestrator instructions.
- File issues for remaining work - Create beads for anything that needs follow-up
- Run quality gates (if code changed) - Tests, linters, builds
- Update issue status - Close finished work, update in-progress items
- Handle git/sync by active profile:
# Conservative/minimal/default: report status and proposed commands; wait for approval. git status # Team-maintainer opt-in only, unless current instructions forbid it: git pull --rebase git push git status
- Hand off - Summarize changes, validation, issue status, and any blocked sync/commit/push step
Critical rules:
- Explicit user or orchestrator instructions override this Beads block.
- Do not commit or push without clear authority from the active profile or the current user request.
- If a required sync or push is blocked, stop and report the exact command and error.
Use Beads (bd) for durable task tracking in repositories that include it. Use the beads skill at .agents/skills/beads/SKILL.md (project install) or ~/.agents/skills/beads/SKILL.md (global install) for Beads workflow guidance, then use the bd CLI for issue operations.
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --claim # Claim work
bd close <id> # Complete work
bd prime # Refresh Beads context- Use
bdfor all task tracking; do not create markdown TODO lists. - Run
bd primewhen Beads context is missing or stale. Codex 0.129.0+ can load Beads context automatically through native hooks; use/hooksto inspect or toggle them. - Keep persistent project memory in Beads via
bd remember; do not create ad hoc memory files.
Architecture in one line: issues live in a local Dolt DB; sync uses refs/dolt/data on your git remote; .beads/issues.jsonl is a passive export. See https://github.com/gastownhall/beads/blob/main/docs/SYNC_CONCEPTS.md for details and anti-patterns.