|
barretenberg
|
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a constexpr context over quantities known at compile-time More...
Classes | |
| class | BarycentricDataCompileTime |
| class | BarycentricDataRunTime |
| struct | Bn254Fq12Params |
| struct | Bn254Fq2Params |
| struct | Bn254Fq6Params |
| class | Bn254FqParams |
| class | Bn254FrParams |
| struct | Bn254G1Params |
| struct | Bn254G2Params |
| class | ContainerSlabAllocator |
| class | EvaluationDomain |
| struct | field |
| class | field12 |
| struct | field2 |
| class | field6 |
| class | Goblin |
| class | GoblinTestingUtils |
| class | group |
| group class. Represents an elliptic curve group element. Group is parametrised by coordinate_field and subgroup_field More... | |
| struct | is_field_type |
| Helper to determine whether input is bberg::field type. More... | |
| struct | is_field_type< barretenberg::field< Params > > |
| class | Polynomial |
| struct | PowUnivariate |
| class | RelationUtils |
| struct | TranslationEvaluations |
| class | Univariate |
| A univariate polynomial represented by its values on {domain_start, domain_start + 1,..., domain_end - 1}. For memory efficiency purposes, we store the evaluations in an array starting from 0 and make the mapping to the right domain under the hood. More... | |
| class | UnivariateView |
| A view of a univariate, also used to truncate univariates. More... | |
Typedefs | |
| using | fq = field< Bn254FqParams > |
| using | fq12 = field12< fq2, fq6, Bn254Fq12Params > |
| using | fq2 = field2< fq, Bn254Fq2Params > |
| using | fq6 = field6< fq2, Bn254Fq6Params > |
| using | fr = field< Bn254FrParams > |
| using | g1 = group< fq, fr, Bn254G1Params > |
| using | g2 = group< fq2, fr, Bn254G2Params > |
| template<class Fr , size_t domain_end, size_t num_evals, size_t domain_start = 0> | |
| using | BarycentricData = std::conditional_t< is_field_type_v< Fr >, BarycentricDataCompileTime< Fr, domain_end, num_evals, domain_start >, BarycentricDataRunTime< Fr, domain_end, num_evals, domain_start > > |
| Exposes BarycentricData with compile time arrays if the type is bberg::field and runtime arrays otherwise. | |
| using | evaluation_domain = EvaluationDomain< barretenberg::fr > |
| using | polynomial = Polynomial< barretenberg::fr > |
Enumerations | |
| enum class | DontZeroMemory { FLAG } |
Functions | |
| template<size_t Start, size_t End, size_t Inc, class F > | |
| constexpr void | constexpr_for (F &&f) |
| Implements a loop using a compile-time iterator. Requires c++20. Implementation (and description) from https://artificial-mind.net/blog/2020/10/31/constexpr-for. | |
| template<const auto & container, auto key> | |
| constexpr bool | constexpr_find () |
returns true/false depending on whether key is in container | |
| template<typename T , std::size_t... Is> | |
| constexpr std::array< T, sizeof...(Is)> | create_array (T value, std::index_sequence< Is... >) |
| Create a constexpr array object whose elements contain a default value. | |
| template<typename T , size_t N> | |
| constexpr std::array< T, N > | create_empty_array () |
| Create a constexpr array object whose values all are 0. | |
| void | init_slab_allocator (size_t circuit_subgroup_size) |
| std::shared_ptr< void > | get_mem_slab (size_t size) |
| void * | get_mem_slab_raw (size_t size) |
| void | free_mem_slab_raw (void *p) |
| template<typename B , typename base_field , typename Params > | |
| void | read (B &it, field2< base_field, Params > &value) |
| template<typename B , typename base_field , typename Params > | |
| void | write (B &buf, field2< base_field, Params > const &value) |
| template<typename B , typename Params > | |
| void | read (B &it, field< Params > &value) |
| template<typename B , typename Params > | |
| void | write (B &buf, field< Params > const &value) |
| template<typename Fr > | |
| std::shared_ptr< Fr[]> | _allocate_aligned_memory (const size_t n_elements) |
| template<typename Fr > | |
| std::ostream & | operator<< (std::ostream &os, Polynomial< Fr > const &p) |
| template<typename B > | |
| void | read (B &buf, polynomial &p) |
| void | write (uint8_t *&buf, polynomial const &p) |
| void | write (std::vector< uint8_t > &buf, polynomial const &p) |
| void | read (std::istream &is, polynomial &p) |
| void | write (std::ostream &os, polynomial const &p) |
| template<typename B , class Fr , size_t domain_end, size_t domain_start = 0> | |
| void | read (B &it, Univariate< Fr, domain_end, domain_start > &univariate) |
| template<typename B , class Fr , size_t domain_end, size_t domain_start = 0> | |
| void | write (B &it, Univariate< Fr, domain_end, domain_start > const &univariate) |
| template<typename T , typename U , std::size_t N, std::size_t... Is> | |
| std::array< T, sizeof...(Is)> | array_to_array_aux (const std::array< U, N > &elements, std::index_sequence< Is... >) |
Create a sub-array of elements at the indices given in the template pack Is, converting them to the new type T. | |
| template<typename T , typename U , std::size_t N> | |
| std::array< T, N > | array_to_array (const std::array< U, N > &elements) |
| Given an std::array<U,N>, returns an std::array<T,N>, by calling the (explicit) constructor T(U). | |
Variables | |
| template<typename T > | |
| constexpr bool | is_field_type_v = is_field_type<T>::value |
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a constexpr context over quantities known at compile-time
Note, this file contains the definitions. of field2 class. Declarations are in field2_declarations.hpp. Include ordering ensures linter/language server has knowledge of declarations when parsing definitions.
Current methods are:
constexpr_for : loop over a range , where the size_t iterator i is a constexpr variable constexpr_find : find if an element is in an array
| using barretenberg::BarycentricData = typedef std::conditional_t<is_field_type_v<Fr>, BarycentricDataCompileTime<Fr, domain_end, num_evals, domain_start>, BarycentricDataRunTime<Fr, domain_end, num_evals, domain_start> > |
Exposes BarycentricData with compile time arrays if the type is bberg::field and runtime arrays otherwise.
This method is also needed for stdlib field, for which the arrays are not compile time computable
| Fr | |
| domain_size | |
| num_evals |
| std::array< T, N > barretenberg::array_to_array | ( | const std::array< U, N > & | elements | ) |
Given an std::array<U,N>, returns an std::array<T,N>, by calling the (explicit) constructor T(U).
https://stackoverflow.com/a/32175958 The main use case is to convert an array of Univariate into UnivariateView. The main use case would be to let Sumcheck decide the required degree of the relation evaluation, rather than hardcoding it inside the relation. The _aux version could also be used to create an array of only the polynomials required by the relation, and it could help us implement the optimization where we extend each edge only up to the maximum degree that is required over all relations (for example, L_LAST only needs degree 3).
| T | Output type |
| U | Input type (deduced from elements) |
| N | Common array size (deduced from elements) |
| elements | array to be converted |
| std::array< T, sizeof...(Is)> barretenberg::array_to_array_aux | ( | const std::array< U, N > & | elements, |
| std::index_sequence< Is... > | |||
| ) |
Create a sub-array of elements at the indices given in the template pack Is, converting them to the new type T.
| T | type to convert to |
| U | type to convert from |
| N | number (deduced by elements) |
| Is | list of indices we want in the returned array. When the second argument is called with std::make_index_sequence<N>, these will be 0, 1, ..., N-1. |
| elements | array to convert from |
std::make_index_sequence<N>.
|
constexpr |
returns true/false depending on whether key is in container
| container | i.e. what are we looking in? |
| key | i.e. what are we looking for? |
method is constexpr and can be used in static_asserts
|
constexpr |
Implements a loop using a compile-time iterator. Requires c++20. Implementation (and description) from https://artificial-mind.net/blog/2020/10/31/constexpr-for.
| Start | the loop start value |
| End | the loop end value |
| Inc | how much the iterator increases by per iteration |
| F | a Lambda function that is executed once per loop |
| f | An rvalue reference to the lambda |
Implements a for loop where the iterator is a constexpr variable. Use this when you need to evaluate if constexpr statements on the iterator (or apply other constexpr expressions) Outside of this use-case avoid using this fn as it gives negligible performance increases vs regular loops.
N.B. A side-effect of this method is that all loops will be unrolled (each loop iteration uses different iterator template parameters => unique constexpr_for implementation per iteration) Do not use this for large (~100+) loops!
EXAMPLE USE OF constexpr_for
constexpr_for<0, 10, 1>([&]<size_t i>(){ if constexpr (i & 1 == 0) { foo[i] = even_container[i >> 1]; } else { foo[i] = odd_container[i >> 1]; } });
In the above example we are iterating from i = 0 to i < 10. The provided lambda function has captured everything in its surrounding scope (via [&]), which is where foo, even_container and odd_container have come from.
We do not need to explicitly define the class F parameter as the compiler derives it from our provided input argument F&& f (i.e. the lambda function)
In the loop itself we're evaluating a constexpr if statement that defines which code path is taken.
The above example benefits from constexpr_for because a run-time if statement has been reduced to a compile-time if statement. N.B. this would only give measurable improvements if the constexpr_for statement is itself in a hot loop that's iterated over many (>thousands) times
Explaining f.template operator()<Start>()
The following line must explicitly tell the compiler that <Start> is a template parameter by using the template keyword. (if we wrote f<Start>(), the compiler could legitimately interpret < as a less than symbol)
The fragment f.template tells the compiler that we're calling a templated member of f. The "member" being called is the function operator, operator(), which must be explicitly provided (for any function X, X(args) is an alias for X.operator()(args)) The compiler has no alias X.template <tparam>(args) for X.template operator()<tparam>(args) so we must write it explicitly here
To summarize what the next line tells the compiler...
f that expects one or more template parametersf that I want to call is the function operatorStart
|
constexpr |
Create a constexpr array object whose elements contain a default value.
| T | type contained in the array |
| Is | index sequence |
| value | the value each array element is being initialized to |
This method is used to create constexpr arrays whose encapsulated type:
An example of this is barretenberg::field_t (the default constructor does not default assign values to the field_t member variables for efficiency reasons, to reduce the time require to construct large arrays of field elements. This means the default constructor for field_t cannot be constexpr)
|
constexpr |
Create a constexpr array object whose values all are 0.
| T | |
| N |
Use in the same context as create_array, i.e. when encapsulated type has a default constructor that is not constexpr
| std::shared_ptr< void > barretenberg::get_mem_slab | ( | size_t | size | ) |
Returns a slab from the preallocated pool of slabs, or fallback to a new heap allocation (32 byte aligned). Ref counted result so no need to manually free.
| void * barretenberg::get_mem_slab_raw | ( | size_t | size | ) |
Sometimes you want a raw pointer to a slab so you can manage when it's released manually (e.g. c_binds, containers). This still gets a slab with a shared_ptr, but holds the shared_ptr internally until free_mem_slab_raw is called.
| void barretenberg::init_slab_allocator | ( | size_t | circuit_subgroup_size | ) |
Allocates a bunch of memory slabs sized to serve an UltraPLONK proof construction. If you want normal memory allocator behavior, just don't call this init function.
WARNING: If client code is still holding onto slabs from previous use, when those slabs are released they'll end up back in the allocator. That's probably not desired as presumably those slabs are now too small, so they're effectively leaked. But good client code should be releasing it's resources promptly anyway. It's not considered "proper use" to call init, take slab, and call init again, before releasing the slab.
TODO: Take a composer type and allocate slabs according to those requirements? TODO: De-globalise. Init the allocator and pass around. Use a PolynomialFactory (PolynomialStore?). TODO: Consider removing, but once due-dilligence has been done that we no longer have memory limitations.