github.com/consensys/gnark-crypto@v0.14.0/internal/generator/fft/generate.go (about)

     1  package fft
     2  
     3  import (
     4  	"math/bits"
     5  	"path/filepath"
     6  
     7  	"github.com/consensys/bavard"
     8  	"github.com/consensys/gnark-crypto/internal/generator/config"
     9  )
    10  
    11  func Generate(conf config.Curve, baseDir string, bgen *bavard.BatchGenerator) error {
    12  
    13  	conf.Package = "fft"
    14  
    15  	entries := []bavard.Entry{
    16  		{File: filepath.Join(baseDir, "doc.go"), Templates: []string{"doc.go.tmpl"}},
    17  		{File: filepath.Join(baseDir, "domain_test.go"), Templates: []string{"tests/domain.go.tmpl", "imports.go.tmpl"}},
    18  		{File: filepath.Join(baseDir, "domain.go"), Templates: []string{"domain.go.tmpl", "imports.go.tmpl"}},
    19  		{File: filepath.Join(baseDir, "fft_test.go"), Templates: []string{"tests/fft.go.tmpl", "imports.go.tmpl"}},
    20  		{File: filepath.Join(baseDir, "bitreverse_test.go"), Templates: []string{"tests/bitreverse.go.tmpl", "imports.go.tmpl"}},
    21  		{File: filepath.Join(baseDir, "fft.go"), Templates: []string{"fft.go.tmpl", "imports.go.tmpl"}},
    22  		{File: filepath.Join(baseDir, "bitreverse.go"), Templates: []string{"bitreverse.go.tmpl", "imports.go.tmpl"}},
    23  		{File: filepath.Join(baseDir, "options.go"), Templates: []string{"options.go.tmpl", "imports.go.tmpl"}},
    24  	}
    25  
    26  	funcs := make(map[string]interface{})
    27  	funcs["bitReverse"] = func(n, i int64) uint64 {
    28  		nn := uint64(64 - bits.TrailingZeros64(uint64(n)))
    29  		r := make([]uint64, n)
    30  		for i := 0; i < len(r); i++ {
    31  			r[i] = uint64(i)
    32  		}
    33  		for i := 0; i < len(r); i++ {
    34  			irev := bits.Reverse64(r[i]) >> nn
    35  			if irev > uint64(i) {
    36  				r[i], r[irev] = r[irev], r[i]
    37  			}
    38  		}
    39  		return r[i]
    40  	}
    41  	funcs["reverseBits"] = func(x, n any) uint64 {
    42  		return bits.Reverse64(anyToUint64(x)) >> anyToUint64(n)
    43  	}
    44  	funcs["shl"] = func(x, n any) uint64 {
    45  		return anyToUint64(x) << anyToUint64(n)
    46  	}
    47  	funcs["logicalOr"] = func(x, y any) uint64 {
    48  		return anyToUint64(x) | anyToUint64(y)
    49  	}
    50  
    51  	bavardOpts := []func(*bavard.Bavard) error{bavard.Funcs(funcs)}
    52  
    53  	if err := bgen.GenerateWithOptions(conf, conf.Package, "./fft/template/", bavardOpts, entries...); err != nil {
    54  		return err
    55  	}
    56  
    57  	// put the generator in the parent dir (fr)
    58  	frDir := filepath.Dir(baseDir)
    59  	entries = []bavard.Entry{
    60  		{File: filepath.Join(frDir, "generator.go"), Templates: []string{"fr.generator.go.tmpl"}},
    61  	}
    62  	return bgen.GenerateWithOptions(conf, "fr", "./fft/template/", bavardOpts, entries...)
    63  }
    64  
    65  func anyToUint64(x any) uint64 {
    66  	switch v := x.(type) {
    67  	case int:
    68  		return uint64(v)
    69  	case int64:
    70  		return uint64(v)
    71  	case uint64:
    72  		return v
    73  	default:
    74  		panic("unknown type")
    75  	}
    76  }