barretenberg
Loading...
Searching...
No Matches
Classes | Typedefs | Enumerations | Functions | Variables
barretenberg Namespace Reference

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
 

Detailed Description

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

Typedef Documentation

◆ BarycentricData

template<class Fr , size_t domain_end, size_t num_evals, size_t domain_start = 0>
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

Template Parameters
Fr
domain_size
num_evals

Function Documentation

◆ array_to_array()

template<typename T , typename U , std::size_t N>
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).

Template Parameters
TOutput type
UInput type (deduced from elements)
NCommon array size (deduced from elements)
Parameters
elementsarray to be converted
Returns
std::array<T, N> result s.t. result[i] = T(elements[i])

◆ array_to_array_aux()

template<typename T , typename U , std::size_t N, std::size_t... Is>
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.

Template Parameters
Ttype to convert to
Utype to convert from
Nnumber (deduced by elements)
Islist 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.
Parameters
elementsarray to convert from
Returns
std::array<T, sizeof...(Is)> result array s.t. result[i] = T(elements[Is[i]]). By default, Is[i] = i when called with std::make_index_sequence<N>.

◆ constexpr_find()

template<const auto & container, auto key>
constexpr bool barretenberg::constexpr_find ( )
constexpr

returns true/false depending on whether key is in container

Template Parameters
containeri.e. what are we looking in?
keyi.e. what are we looking for?
Returns
true found!
false not found!

method is constexpr and can be used in static_asserts

◆ constexpr_for()

template<size_t Start, size_t End, size_t Inc, class F >
constexpr void barretenberg::constexpr_for ( F &&  f)
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.

Template Parameters
Startthe loop start value
Endthe loop end value
Inchow much the iterator increases by per iteration
Fa Lambda function that is executed once per loop
Parameters
fAn 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...

  1. I want to call a member of f that expects one or more template parameters
  2. The member of f that I want to call is the function operator
  3. The template parameter is Start
  4. The function operator itself contains no arguments

◆ create_array()

template<typename T , std::size_t... Is>
constexpr std::array< T, sizeof...(Is)> barretenberg::create_array ( value,
std::index_sequence< Is... >   
)
constexpr

Create a constexpr array object whose elements contain a default value.

Template Parameters
Ttype contained in the array
Isindex sequence
Parameters
valuethe value each array element is being initialized to
Returns
constexpr std::array<T, sizeof...(Is)>

This method is used to create constexpr arrays whose encapsulated type:

  1. HAS NO CONSTEXPR DEFAULT CONSTRUCTOR
  2. HAS A CONSTEXPR COPY CONSTRUCTOR

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)

◆ create_empty_array()

template<typename T , size_t N>
constexpr std::array< T, N > barretenberg::create_empty_array ( )
constexpr

Create a constexpr array object whose values all are 0.

Template Parameters
T
N
Returns
constexpr std::array<T, N>

Use in the same context as create_array, i.e. when encapsulated type has a default constructor that is not constexpr

◆ get_mem_slab()

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.

◆ get_mem_slab_raw()

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.

◆ init_slab_allocator()

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.