profile

package
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 13, 2026 License: Apache-2.0 Imports: 12 Imported by: 14

Documentation

Overview

Package profile provides a simple way to generate pprof compatible gnark circuit profile.

Since the gnark frontend compiler is not thread safe and operates in a single go-routine, this package is also NOT thread safe and is meant to be called in the same go-routine.

Example
//go:build !windows

package main

import (
	"fmt"

	"github.com/consensys/gnark-crypto/ecc"
	"github.com/consensys/gnark/frontend"
	"github.com/consensys/gnark/frontend/cs/r1cs"
	"github.com/consensys/gnark/profile"
)

type Circuit struct {
	A frontend.Variable
}

type obj struct {
}

func (circuit *Circuit) Define(api frontend.API) error {
	var o obj
	o.Define(api, circuit.A)
	// api.AssertIsEqual(api.Mul(circuit.A, circuit.A), circuit.A)
	return nil
}

func (o *obj) Define(api frontend.API, A frontend.Variable) error {
	api.AssertIsEqual(api.Mul(A, A), A)
	return nil
}

func main() {
	// default options generate gnark.pprof in current dir
	// use pprof as usual (go tool pprof -http=:8080 gnark.pprof) to read the profile file
	// overlapping profiles are allowed (define profiles inside Define or subfunction to profile
	// part of the circuit only)
	p := profile.Start()
	_, _ = frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &Circuit{})
	p.Stop()

	// expected output fmt.Println(p.Top())
	const _ = `Showing nodes accounting for 2, 100% of 2 total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context              
----------------------------------------------------------+-------------
                                                 1   100% |   profile_test.(*Circuit).Define profile/profile_test.go:21
         1 50.00% 50.00%          1 50.00%                | r1cs.(*builder).AssertIsEqual frontend/cs/r1cs/api_assertions.go:37
----------------------------------------------------------+-------------
                                                 1   100% |   profile_test.(*Circuit).Define profile/profile_test.go:21
         1 50.00%   100%          1 50.00%                | r1cs.(*builder).Mul frontend/cs/r1cs/api.go:221
----------------------------------------------------------+-------------
         0     0%   100%          2   100%                | profile_test.(*Circuit).Define profile/profile_test.go:21
                                                 1 50.00% |   r1cs.(*builder).AssertIsEqual frontend/cs/r1cs/api_assertions.go:37
                                                 1 50.00% |   r1cs.(*builder).Mul frontend/cs/r1cs/api.go:221
----------------------------------------------------------+-------------`

	fmt.Println(p.NbConstraints())
}
Output:
2
Example (Operations)

Example_operations demonstrates how to use operation profiling with emulated arithmetic.

package main

import (
	"github.com/consensys/gnark-crypto/ecc"
	"github.com/consensys/gnark/frontend"
	"github.com/consensys/gnark/frontend/cs/scs"
	"github.com/consensys/gnark/profile"
	"github.com/consensys/gnark/std/math/emulated"
)

// EmulatedCircuit performs emulated arithmetic which uses deferred constraints
type EmulatedCircuit struct {
	A, B emulated.Element[emulated.Secp256k1Fp]
}

func (c *EmulatedCircuit) Define(api frontend.API) error {
	f, err := emulated.NewField[emulated.Secp256k1Fp](api)
	if err != nil {
		return err
	}

	res := f.Mul(&c.A, &c.B)
	res = f.Mul(res, &c.A)
	f.AssertIsEqual(res, &c.B)

	return nil
}

func main() {
	// Start profiling - operations will be tracked at call sites
	p := profile.Start(profile.WithNoOutput())

	// Compile a circuit using emulated arithmetic
	_, _ = frontend.Compile(ecc.BN254.ScalarField(), scs.NewBuilder, &EmulatedCircuit{})

	p.Stop()

	// View actual constraints (default)
	// go tool pprof -sample_index=0 gnark.pprof

	// View operations (shows where Mul/AssertIsEqual were called)
	// go tool pprof -sample_index=1 gnark.pprof

	// Or programmatically:
	// p.Top() - shows constraint tree
	// p.TopOperations() - shows operation tree
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func RecordConstraint

func RecordConstraint()

RecordConstraint add a sample (with count == 1) to all the active profiling sessions.

func RecordOperation added in v0.15.0

func RecordOperation(name string, count int)

RecordOperation records an operation with the given name and count. Operations are recorded at call sites (like emulated.Mul) and provide an immediate view of high-level operations independently of when actual constraints are created (which may happen later in deferred callbacks).

Operation samples appear in the same pprof file with a different sample type.

Usage:

go tool pprof gnark.pprof                    # constraints (default)
go tool pprof -sample_index=1 gnark.pprof   # operations

Web UI:

go tool pprof -http=:8080 gnark.pprof
# Select "operations" from SAMPLE dropdown (top-left) to see operations

The name parameter should be descriptive and can include metadata:

profile.RecordOperation("rangecheck_64bits", 1)
profile.RecordOperation("emulated.Mul_4limbs", 1)

Types

type Option

type Option func(*Profile)

Option defines configuration Options for Profile.

func WithNoOutput

func WithNoOutput() Option

WithNoOutput indicates that the profile is not going to be written to disk.

This is equivalent to WithPath("")

func WithOperationWeights added in v0.15.0

func WithOperationWeights(weights map[string]int) Option

WithOperationWeights sets weight multipliers for operation names. When RecordOperation is called with a name that matches a key in the weights map, the count is multiplied by the corresponding weight value.

This allows users to have more representative and tunable profiles for operations, especially useful when different operations have different costs.

Example:

p := profile.Start(profile.WithOperationWeights(map[string]int{
    "emulated.Mul": 10,
    "rangecheck":   5,
}))

func WithPath

func WithPath(path string) Option

WithPath controls the profile destination file. If blank, profile is not written.

Defaults to ./gnark.pprof.

func WithoutConstraints added in v0.15.0

func WithoutConstraints() Option

WithoutConstraints excludes constraint samples from the exported profile. When enabled, only operation samples will appear in the pprof output. This is useful when you only care about high-level operation counts.

func WithoutOperations added in v0.15.0

func WithoutOperations() Option

WithoutOperations excludes operation samples from the exported profile. When enabled, only constraint samples will appear in the pprof output. This is useful when you want a profile compatible with older tools that don't expect multiple sample types, or when you only care about constraints.

type Profile

type Profile struct {
	// contains filtered or unexported fields
}

Profile represents an active constraint system profiling session.

func Start

func Start(options ...Option) *Profile

Start creates a new active profiling session. When Stop() is called, this session is removed from active profiling sessions and may be serialized to disk as a pprof compatible file (see ProfilePath option).

All calls to profile.Start() and Stop() are meant to be executed in the same go routine (frontend.Compile).

It is allowed to create multiple overlapping profiling sessions in one circuit.

func (*Profile) NbConstraints

func (p *Profile) NbConstraints() int

NbConstraints return number of collected samples (constraints) by the profile session. Note: this counts samples, not actual constraint count when using sample values > 1. Returns 0 if WithoutConstraints option was used.

func (*Profile) NbOperations added in v0.15.0

func (p *Profile) NbOperations() int

NbOperations returns the total count of operations recorded. Returns 0 if WithoutOperations option was used.

func (*Profile) Stop

func (p *Profile) Stop()

Stop removes the profile from active session and may write the pprof file to disk. See ProfilePath option.

func (*Profile) Top

func (p *Profile) Top() string

Top return a similar output than pprof top command for constraints (sample_index=0). Returns empty string if WithoutConstraints option was used.

func (*Profile) TopOperations added in v0.15.0

func (p *Profile) TopOperations() string

TopOperations return a similar output than pprof top command for operations (sample_index=1). Returns empty string if WithoutOperations option was used.

Directories

Path Synopsis
internal
graph
Package graph collects a set of samples into a directed graph.
Package graph collects a set of samples into a directed graph.
measurement
Package measurement export utility functions to manipulate/format performance profile sample values.
Package measurement export utility functions to manipulate/format performance profile sample values.
report
Package report summarizes a performance profile into a human-readable report.
Package report summarizes a performance profile into a human-readable report.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL