Skip to content

Commit

Permalink
feat: gnark/profile now filter frontend private method for clarity an…
Browse files Browse the repository at this point in the history
…d return a tree as txt repr (Consensys#538)
  • Loading branch information
gbotrel authored Mar 8, 2023
1 parent c439508 commit 1ef6a1b
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 30 deletions.
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
github.com/consensys/gnark-crypto v0.9.1 h1:mru55qKdWl3E035hAoh1jj9d7hVnYY5pfb6tmovSmII=
github.com/consensys/gnark-crypto v0.9.1/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4=
github.com/consensys/gnark-crypto v0.9.2-0.20230222154459-49b5c6cfd875 h1:FTOvlE+90hvp+XHi8i89xCejJ0627wfbP0RSWzmVFks=
github.com/consensys/gnark-crypto v0.9.2-0.20230222154459-49b5c6cfd875/go.mod h1:a2DQL4+5ywF6safEeZFEPGRiiGbjzGFRUN2sg06VuU4=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
Expand Down
6 changes: 3 additions & 3 deletions profile/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func Start(options ...Option) *Profile {

log := logger.Logger()
if p.filePath == "" {
log.Warn().Msg("gnark profiling enabled [not writting to disk]")
log.Warn().Msg("gnark profiling enabled [not writing to disk]")
} else {
log.Info().Str("path", p.filePath).Msg("gnark profiling enabled")
}
Expand Down Expand Up @@ -131,7 +131,7 @@ func (p *Profile) Stop() {
f.Close()
log.Info().Str("path", p.filePath).Msg("gnark profiling disabled")
} else {
log.Warn().Msg("gnark profiling disabled [not writting to disk]")
log.Warn().Msg("gnark profiling disabled [not writing to disk]")
}

}
Expand All @@ -144,7 +144,7 @@ func (p *Profile) NbConstraints() int {
// Top return a similar output than pprof top command
func (p *Profile) Top() string {
r := report.NewDefault(&p.pprof, report.Options{
OutputFormat: report.Text,
OutputFormat: report.Tree,
CompactLabels: true,
NodeFraction: 0.005,
EdgeFraction: 0.001,
Expand Down
27 changes: 22 additions & 5 deletions profile/profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ package profile_test

import (
"fmt"
"strings"

"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/frontend/cs/r1cs"
"github.com/consensys/gnark/profile"
"golang.org/x/exp/slices"
)

type Circuit struct {
Expand All @@ -29,12 +31,27 @@ func Example() {
_, _ = frontend.Compile(ecc.BN254.ScalarField(), r1cs.NewBuilder, &Circuit{})
p.Stop()

const expectedOutput = `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
----------------------------------------------------------+-------------`

a := strings.Fields(p.Top())
b := strings.Fields(expectedOutput)

fmt.Println(p.NbConstraints())
fmt.Println(p.Top())
fmt.Println(slices.Equal(a, b))
// Output:
// 2
// Showing nodes accounting for 2, 100% of 2 total
// flat flat% sum% cum cum%
// 1 50.00% 50.00% 2 100% profile_test.(*Circuit).Define profile/profile_test.go:19
// 1 50.00% 100% 1 50.00% r1cs.(*builder).AssertIsEqual frontend/cs/r1cs/api_assertions.go:37
// true
}
47 changes: 27 additions & 20 deletions profile/profile_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"
"sync"
"sync/atomic"
"unicode"

"github.com/google/pprof/profile"
)
Expand Down Expand Up @@ -68,26 +69,8 @@ func collectSample(pc []uintptr) {
continue
}

// to avoid aving a location that concentrates 99% of the calls, we transfer the "addConstraint"
// occuring in Mul to the previous level in the stack
if strings.Contains(frame.Function, "github.com/consensys/gnark/frontend/cs/r1cs.(*builder).Mul") {
continue
}

if strings.HasPrefix(frame.Function, "github.com/consensys/gnark/frontend/cs/scs.(*scs).Mul") {
continue
}

if strings.HasPrefix(frame.Function, "github.com/consensys/gnark/frontend/cs/scs.(*scs).split") {
continue
}

// with scs.Builder (Plonk) Add and Sub always add a constraint --> we record the caller as the constraint adder
// but in the future we may record a different type of sample for these
if strings.HasPrefix(frame.Function, "github.com/consensys/gnark/frontend/cs/scs.(*scs).Add") {
continue
}
if strings.HasPrefix(frame.Function, "github.com/consensys/gnark/frontend/cs/scs.(*scs).Sub") {
// filter internal builder functions
if filterSCSPrivateFunc(frame.Function) || filterR1CSPrivateFunc(frame.Function) {
continue
}

Expand Down Expand Up @@ -123,3 +106,27 @@ func collectSample(pc []uintptr) {
}

}

func filterSCSPrivateFunc(f string) bool {
const scsPrefix = "github.com/consensys/gnark/frontend/cs/scs.(*builder)."
if strings.HasPrefix(f, scsPrefix) && len(f) > len(scsPrefix) {
// filter plonk frontend private APIs from the trace.
c := []rune(f)[len(scsPrefix)]
if unicode.IsLower(c) {
return true
}
}
return false
}

func filterR1CSPrivateFunc(f string) bool {
const r1csPrefix = "github.com/consensys/gnark/frontend/cs/r1cs.(*builder)."
if strings.HasPrefix(f, r1csPrefix) && len(f) > len(r1csPrefix) {
// filter r1cs frontend private APIs from the trace.
c := []rune(f)[len(r1csPrefix)]
if unicode.IsLower(c) {
return true
}
}
return false
}

0 comments on commit 1ef6a1b

Please sign in to comment.