Skip to content
reilabsPublic

About

Compiling Noir to R1CS with witness generation and automatic differentiation binaries

Topics

Resources

Contributing

Stars

23 stars

Watchers

1 watching

Forks

Latest commit

 

History

528 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mavros

Mavros is a toolchain for compiling Noir to R1CS with additional functionality for use with Spartan. It provides a complete pipeline from Noir source to the output of the eventual circuit, and is designed with mobile proving workflows in mind.

Building

This project uses Nix flakes to provide a pinned build environment with all the tools you need to build the project. Assuming you have nix installed, simply make shell to drop into your user shell inside the build environment, or run nix develop --command <your-command-here> to run a specific command in the build environment.

You can use one of the two following methods to experiment with Mavros.

  • Running make install will build and install Mavros to your cargo binary directory.
  • Running make release will build Mavros to ./target/release/mavros.

Run make to get an overview of the available utilities and targets. For complete guidance please see our contributing guidelines. See usage below for more information on how to use Mavros.

Usage

To use Mavros, navigate to the root of a Noir project (the directory containing Nargo.toml) in your shell. Then run mavros compile.

This will produce the following two files inside the project's target/ directory:

File Contents
target/basic.json ABI and the program binary (binary) containing the witgen and AD entry points
target/r1cs.bin Serialised R1CS constraint system (bincode)

Pass --include-debug-info to additionally write target/basic.debug.json. This standalone, versioned source map records VM bytecode word offsets, function names, and Noir source locations; the executable bytecode in basic.json remains byte-for-byte unchanged. Source paths are relative to the Noir package root by default; pass --absolute-paths to retain absolute paths.

Per-Function FlameGraphs

Run the full compiler and VM pipeline with --profile to generate interactive per-function FlameGraphs:

mavros --root . --profile

The command writes folded-stack inputs and SVGs under mavros_debug/flamegraphs/ for four dimensions: constraint_size, witness_size, witgen_time, and ad_time. The two time profiles use the VM's deterministic simulated instruction count rather than wall-clock samples, so profiles can be compared across machines and runs. Profiling automatically enables the VM debug mapping needed to recover Noir function names. Shared lookup-table allocations appear under a separate <lookup tables> branch; the cost of each lookup remains attributed to its callsite.

The command also writes witgen_time.cpuprofile and ad_time.cpuprofile. Load either file from the Chrome DevTools Performance panel to inspect it with the DevTools flame chart and call tree. These profiles preserve execution order and use deterministic instruction intervals rather than wall-clock time. Runs of up to 100,000 instructions contain one sample per instruction; larger runs use bounded, deterministic stratified sampling to avoid periodic sampling bias while keeping file size practical.

SVG rendering uses Brendan Gregg's FlameGraph flamegraph.pl. It is pinned and available in nix develop; outside the Nix shell, install FlameGraph and put flamegraph.pl on PATH. When the script is unavailable, Mavros still writes the folded profiles and Chrome .cpuprofile files and skips only the SVGs.

For advanced usage and the CLI options, run mavros --help. To output the witness generation binary for WASM-capable platforms, please see the WASM output section in our contributing docs.

Noir Workspaces

When pointed at a workspace, Mavros honors default-member. Without a default, the CLI runs or compiles every binary member in manifest order; library members remain available as dependencies. Each binary uses its own Prover.toml and mavros_debug directory. A failed member makes the workspace run fail, while the remaining members are still checked.

When mavros compile resolves a package root different from the supplied path, relative output paths use that package root, including for a single default member. The defaults then produce <member>/target/basic.json and <member>/target/r1cs.bin. Absolute output paths and paths containing .. are rejected for multi-binary compilations. Point Mavros directly at a member directory to compile just that package with the usual output-path behavior.

The functional test runner reports each selected binary workspace member as a separate test, with its own checks, circuit size, and artifact sizes. Libraries are not separate executable tests.

Usage Example

cd my-noir-project
mavros compile
# → target/basic.json
# → target/r1cs.bin

Noir Feature Support and Completeness

For the current status of Mavros' support for various Noir constructs, see the status doc that is generated by CI on every update. This provides information on how far the Mavros pipeline gets for each Noir test.

About

Compiling Noir to R1CS with witness generation and automatic differentiation binaries

Topics

Resources

Contributing

Stars

23 stars

Watchers

1 watching

Forks

Releases

Contributors

Languages