From fc844f1d19a16174a0b6ea785f6cedc7156d21df Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Tue, 13 Aug 2024 14:12:44 +0000 Subject: [PATCH] done --- .../barretenberg/common/constexpr_utils.hpp | 71 -------- .../cpp/src/barretenberg/flavor/flavor.hpp | 156 ++++++------------ .../ultra_zk_flavor.hpp | 8 +- 3 files changed, 57 insertions(+), 178 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp b/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp index 9b5c7da2e86b..d098be977cb1 100644 --- a/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp +++ b/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp @@ -4,15 +4,6 @@ #include #include -/** - * @brief constexpr_utils defines some helper methods that perform some stl-equivalent operations - * but in a constexpr context over quantities known at compile-time - * - * 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 - */ namespace bb { /** @@ -97,66 +88,4 @@ template constexpr void constexp } } -/** - * @brief returns true/false depending on whether `key` is in `container` - * - * @tparam container i.e. what are we looking in? - * @tparam key i.e. what are we looking for? - * @return true found! - * @return false not found! - * - * @details method is constexpr and can be used in static_asserts - */ -template constexpr bool constexpr_find() -{ - // using ElementType = typename std::remove_extent::type; - bool found = false; - constexpr_for<0, container.size(), 1>([&]() { - if constexpr (std::get(container) == key) { - found = true; - } - }); - return found; -} - -/** - * @brief Create a constexpr array object whose elements contain a default value - * - * @tparam T type contained in the array - * @tparam Is index sequence - * @param value the value each array element is being initialized to - * @return constexpr std::array - * - * @details 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 bb::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) - */ -template -constexpr std::array create_array(T value, std::index_sequence /*unused*/) -{ - // cast Is to void to remove the warning: unused value - std::array result = { { (static_cast(Is), value)... } }; - return result; -} - -/** - * @brief Create a constexpr array object whose values all are 0 - * - * @tparam T - * @tparam N - * @return constexpr std::array - * - * @details Use in the same context as create_array, i.e. when encapsulated type has a default constructor that is not - * constexpr - */ -template constexpr std::array create_empty_array() -{ - return create_array(T(0), std::make_index_sequence()); -} }; // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index 9ffacd4c31e2..edc0c6ebaaa4 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -262,28 +262,21 @@ auto get_unshifted_then_shifted(const auto& all_entities) return concatenate(all_entities.get_unshifted(), all_entities.get_shifted()); }; -template -static constexpr auto _compute_max_partial_relation_length_internal([[maybe_unused]] std::index_sequence) -{ - constexpr std::array lengths = { std::tuple_element_t::RELATION_LENGTH... }; - return *std::max_element(lengths.begin(), lengths.end()); -} - /** * @brief Utility function to find max PARTIAL_RELATION_LENGTH tuples of Relations. * @details The "partial length" of a relation is 1 + the degree of the relation, where any challenges used in the * relation are as constants, not as variables.. */ -template static constexpr size_t compute_max_partial_relation_length() -{ - return _compute_max_partial_relation_length_internal(std::make_index_sequence>()); -} - -template -static constexpr auto _compute_max_total_relation_length_internal([[maybe_unused]] std::index_sequence) +template constexpr size_t compute_max_partial_relation_length() { - constexpr std::array lengths = { std::tuple_element_t::TOTAL_RELATION_LENGTH... }; - return *std::max_element(lengths.begin(), lengths.end()); + constexpr auto seq = std::make_index_sequence>(); + return [](std::index_sequence) { + if constexpr (ZK) { + return std::max({ std::tuple_element_t::ZK_RELATION_LENGTH... }); + } else { + return std::max({ std::tuple_element_t::RELATION_LENGTH... }); + } + }(seq); } /** @@ -291,61 +284,27 @@ static constexpr auto _compute_max_total_relation_length_internal([[maybe_unused * @details The "total length" of a relation is 1 + the degree of the relation, where any challenges used in the * relation are regarded as variables. */ -template static constexpr size_t compute_max_total_relation_length() -{ - return _compute_max_total_relation_length_internal(std::make_index_sequence>()); -} - -template -static constexpr auto _compute_number_of_subrelations_internal([[maybe_unused]] std::index_sequence) +template constexpr size_t compute_max_total_relation_length() { - constexpr std::array lengths = { - std::tuple_element_t::SUBRELATION_PARTIAL_LENGTHS.size()... - }; - return std::accumulate(lengths.begin(), lengths.end(), 0); + constexpr auto seq = std::make_index_sequence>(); + return [](std::index_sequence) { + if constexpr (ZK) { + return std::max({ std::tuple_element_t::ZK_TOTAL_RELATION_LENGTH... }); + } else { + return std::max({ std::tuple_element_t::TOTAL_RELATION_LENGTH... }); + } + }(seq); } /** * @brief Utility function to find the number of subrelations. */ -template static constexpr size_t compute_number_of_subrelations() -{ - return _compute_number_of_subrelations_internal(std::make_index_sequence>()); -} - -template -static constexpr auto _create_protogalaxy_tuple_of_tuples_of_univariates_internal( - [[maybe_unused]] std::index_sequence) +template constexpr size_t compute_number_of_subrelations() { - if constexpr (optimised) { - return std::make_tuple( - typename std::tuple_element_t::template OptimisedProtogalaxyTupleOfUnivariatesOverSubrelations< - NUM_INSTANCES>{}...); - } else { - return std::make_tuple( - typename std::tuple_element_t::template ProtogalaxyTupleOfUnivariatesOverSubrelations< - NUM_INSTANCES>{}...); - } -} - -/** - * @brief Takes a Tuple of objects in the Relation class and recursively computes the maximum among partial - * subrelation lengths incremented by corresponding subrelation witness degrees over all - * subrelations of given relations. This method is required to compute the size of - * Round Univariates in ZK Sumcheck. - * @tparam Tuple - * @tparam Index - * @return constexpr size_t - */ -template static constexpr size_t compute_max_total_zk_relation_length() -{ - if constexpr (Index >= std::tuple_size::value) { - return 0; // Return 0 when reach end of the tuple - } else { - constexpr size_t current_zk_length = std::tuple_element::type::ZK_TOTAL_RELATION_LENGTH; - constexpr size_t next_zk_length = compute_max_total_zk_relation_length(); - return (current_zk_length > next_zk_length) ? current_zk_length : next_zk_length; - } + constexpr auto seq = std::make_index_sequence>(); + return [](std::index_sequence) { + return (0 + ... + std::tuple_element_t::SUBRELATION_PARTIAL_LENGTHS.size()); + }(seq); } /** @@ -356,54 +315,40 @@ template static constexpr size_t compute * @tparam optimised Enable optimised version with skipping some of the computation */ template -static constexpr auto create_protogalaxy_tuple_of_tuples_of_univariates() -{ - return _create_protogalaxy_tuple_of_tuples_of_univariates_internal( - std::make_index_sequence>()); -} - -template -static constexpr auto _create_sumcheck_tuple_of_tuples_of_univariates_internal( - [[maybe_unused]] std::index_sequence) +constexpr auto create_protogalaxy_tuple_of_tuples_of_univariates() { - return std::make_tuple(typename std::tuple_element_t::SumcheckTupleOfUnivariatesOverSubrelations{}...); + constexpr auto seq = std::make_index_sequence>(); + return [](std::index_sequence) { + if constexpr (optimised) { + return std::make_tuple( + typename std::tuple_element_t:: + template OptimisedProtogalaxyTupleOfUnivariatesOverSubrelations{}...); + } else { + return std::make_tuple( + typename std::tuple_element_t::template ProtogalaxyTupleOfUnivariatesOverSubrelations< + NUM_INSTANCES>{}...); + } + }(seq); } -template -static constexpr auto _create_zk_sumcheck_tuple_of_tuples_of_univariates_internal( - [[maybe_unused]] std::index_sequence) -{ - return std::make_tuple(typename std::tuple_element_t::ZKSumcheckTupleOfUnivariatesOverSubrelations{}...); -} /** * @brief Utility function to construct a container for the subrelation accumulators of sumcheck proving. * @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of * univariates whose size is equal to the number of subrelations of the relation. The length of a univariate in an inner * tuple is determined by the corresponding subrelation length. */ -template static constexpr auto create_sumcheck_tuple_of_tuples_of_univariates() +template constexpr auto create_sumcheck_tuple_of_tuples_of_univariates() { - return _create_sumcheck_tuple_of_tuples_of_univariates_internal( - std::make_index_sequence>()); -} - -/** - * @brief Recursive utility function to construct a container for the subrelation accumulators of ZK Sumcheck prover. - * @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of - * univariates whose size is equal to the number of subrelations of the relation. The length of a univariate in an inner - * tuple is determined by the corresponding zk subrelation length, i.e. by the subrelation partial length corrected by - * the corresponding witness degree. - */ -template static constexpr auto create_zk_sumcheck_tuple_of_tuples_of_univariates() -{ - return _create_zk_sumcheck_tuple_of_tuples_of_univariates_internal( - std::make_index_sequence>()); -} - -template -static constexpr auto _create_tuple_of_arrays_of_values_internal([[maybe_unused]] std::index_sequence) -{ - return std::make_tuple(typename std::tuple_element_t::SumcheckArrayOfValuesOverSubrelations{}...); + constexpr auto seq = std::make_index_sequence>(); + return [](std::index_sequence) { + if constexpr (ZK) { + return std::make_tuple( + typename std::tuple_element_t::ZKSumcheckTupleOfUnivariatesOverSubrelations{}...); + } else { + return std::make_tuple( + typename std::tuple_element_t::SumcheckTupleOfUnivariatesOverSubrelations{}...); + } + }(seq); } /** @@ -411,9 +356,12 @@ static constexpr auto _create_tuple_of_arrays_of_values_internal([[maybe_unused] * @details Container for storing value of each identity in each relation. Each Relation contributes an array of * length num-identities. */ -template static constexpr auto create_tuple_of_arrays_of_values() +template constexpr auto create_tuple_of_arrays_of_values() { - return _create_tuple_of_arrays_of_values_internal(std::make_index_sequence>()); + constexpr auto seq = std::make_index_sequence>(); + return [](std::index_sequence) { + return std::make_tuple(typename std::tuple_element_t::SumcheckArrayOfValuesOverSubrelations{}...); + }(seq); } } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp index d5379680babc..f7cc6ba65002 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_zk_flavor.hpp @@ -3,6 +3,7 @@ #include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" namespace bb { + /*! \brief Child class of UltraFlavor that runs with ZK Sumcheck. \details @@ -16,19 +17,20 @@ univariate accumuluator size has to be increased by the subrelation's witness de \ref docs/src/sumcheck-outline.md "Sumcheck Outline". */ class UltraFlavorWithZK : public bb::UltraFlavor { - public: // This flavor runs with ZK Sumcheck static constexpr bool HasZK = true; // Compute the maximum over all partial subrelation lengths incremented by the corresponding subrelation witness // degrees for the Relations inherited from UltraFlavor - static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_total_zk_relation_length(); + static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_total_relation_length(); // Determine the number of evaluations of Prover and Libra Polynomials that the Prover sends to the Verifier in // the rounds of ZK Sumcheck. static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = MAX_PARTIAL_RELATION_LENGTH + 1; // Construct the container for the subrelations' contributions - using SumcheckTupleOfTuplesOfUnivariates = decltype(create_zk_sumcheck_tuple_of_tuples_of_univariates()); + using SumcheckTupleOfTuplesOfUnivariates = + decltype(create_sumcheck_tuple_of_tuples_of_univariates()); // Re-define ExtendedEdges to account for the incremented MAX_PARTIAL_RELATION_LENGTH using ExtendedEdges = ProverUnivariates; }; + } // namespace bb \ No newline at end of file