From c9ba4bf4e77fc7f37a42d29c525cc3968fdbfd6b Mon Sep 17 00:00:00 2001 From: kevaundray Date: Sat, 25 Nov 2023 18:53:39 +0000 Subject: [PATCH 1/5] deterministically sort `cached_partial_non_native_field_multiplication` --- .../circuit_builder/ultra_circuit_builder.hpp | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 25c35737a12..fb9baec7e15 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -211,12 +211,31 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase Date: Mon, 27 Nov 2023 19:20:35 +0000 Subject: [PATCH 2/5] use stable_sort --- .../circuit_builder/ultra_circuit_builder.cpp | 4 ++-- .../circuit_builder/ultra_circuit_builder.hpp | 20 +------------------ 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index e51cacc67d4..78c3f3ba370 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -1665,8 +1665,8 @@ void UltraCircuitBuilder_::process_non_native_field_multiplicat c.b[j] = this->real_variable_index[c.b[j]]; } } - std::sort(cached_partial_non_native_field_multiplications.begin(), - cached_partial_non_native_field_multiplications.end()); + std::stable_sort(cached_partial_non_native_field_multiplications.begin(), + cached_partial_non_native_field_multiplications.end()); auto last = std::unique(cached_partial_non_native_field_multiplications.begin(), cached_partial_non_native_field_multiplications.end()); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index fb9baec7e15..41b43a0d683 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -217,25 +217,7 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase Date: Mon, 27 Nov 2023 19:36:52 +0000 Subject: [PATCH 3/5] Allow empty commit From 13e3716295401b194df4b43b6490f2fa12607366 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 27 Nov 2023 21:20:56 +0000 Subject: [PATCH 4/5] use hashset --- .../circuit_builder/ultra_circuit_builder.cpp | 12 +---- .../circuit_builder/ultra_circuit_builder.hpp | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index 78c3f3ba370..047e3e8489e 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -1665,17 +1665,10 @@ void UltraCircuitBuilder_::process_non_native_field_multiplicat c.b[j] = this->real_variable_index[c.b[j]]; } } - std::stable_sort(cached_partial_non_native_field_multiplications.begin(), - cached_partial_non_native_field_multiplications.end()); - - auto last = std::unique(cached_partial_non_native_field_multiplications.begin(), - cached_partial_non_native_field_multiplications.end()); - - auto it = cached_partial_non_native_field_multiplications.begin(); + cached_partial_non_native_field_multiplication::deduplicate(cached_partial_non_native_field_multiplications); // iterate over the cached items and create constraints - while (it != last) { - const auto input = *it; + for (const auto& input : cached_partial_non_native_field_multiplications) { w_l.emplace_back(input.a[1]); w_r.emplace_back(input.b[1]); @@ -1701,7 +1694,6 @@ void UltraCircuitBuilder_::process_non_native_field_multiplicat w_4.emplace_back(input.hi_1); apply_aux_selectors(AUX_SELECTORS::NONE); ++this->num_gates; - ++it; } } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 41b43a0d683..21e11c1078a 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -206,6 +206,25 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase& vec) + { + std::unordered_set + seen; + + std::vector uniqueVec; + + for (const auto& item : vec) { + if (seen.find(item) == seen.end()) { + seen.insert(item); + uniqueVec.push_back(item); + } + } + + vec.swap(uniqueVec); + } + bool operator<(const cached_partial_non_native_field_multiplication& other) const { if (a < other.a) { @@ -221,6 +240,36 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase> 2)); + }; + + // Combine hash for each element in arrays 'a' and 'b' + for (const auto& elem : obj.a) { + combined_hash = hash_combiner(combined_hash, std::hash()(elem)); + } + for (const auto& elem : obj.b) { + combined_hash = hash_combiner(combined_hash, std::hash()(elem)); + } + + return combined_hash; + } + }; + + struct CachedPartialNonNativeFieldMultiplicationEqual { + bool operator()(const cached_partial_non_native_field_multiplication& lhs, + const cached_partial_non_native_field_multiplication& rhs) const + { + return lhs == rhs; + } + }; + struct non_native_field_multiplication_cross_terms { uint32_t lo_0_idx; uint32_t lo_1_idx; From 7fc85894db00e80626cab9fc824030ab9ff75bae Mon Sep 17 00:00:00 2001 From: kevaundray Date: Mon, 27 Nov 2023 21:31:45 +0000 Subject: [PATCH 5/5] cleanup --- .../circuit_builder/ultra_circuit_builder.hpp | 57 ++++++++----------- 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index 21e11c1078a..a8186c477dc 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -208,16 +208,12 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase& vec) { - std::unordered_set - seen; + std::unordered_set> seen; std::vector uniqueVec; for (const auto& item : vec) { - if (seen.find(item) == seen.end()) { - seen.insert(item); + if (seen.insert(item).second) { uniqueVec.push_back(item); } } @@ -238,36 +234,31 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase> 2)); - }; + struct Hash { + size_t operator()(const cached_partial_non_native_field_multiplication& obj) const + { + size_t combined_hash = 0; + + // C++ does not have a standard way to hash values, so we use the + // common algorithm that boot uses. + // You can search for 'cpp hash_combine' to find more information. + // Here is one reference: + // https://stackoverflow.com/questions/2590677/how-do-i-combine-hash-values-in-c0x + auto hash_combiner = [](size_t lhs, size_t rhs) { + return lhs ^ (rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2)); + }; + + for (const auto& elem : obj.a) { + combined_hash = hash_combiner(combined_hash, std::hash()(elem)); + } + for (const auto& elem : obj.b) { + combined_hash = hash_combiner(combined_hash, std::hash()(elem)); + } - // Combine hash for each element in arrays 'a' and 'b' - for (const auto& elem : obj.a) { - combined_hash = hash_combiner(combined_hash, std::hash()(elem)); - } - for (const auto& elem : obj.b) { - combined_hash = hash_combiner(combined_hash, std::hash()(elem)); + return combined_hash; } - - return combined_hash; - } - }; - - struct CachedPartialNonNativeFieldMultiplicationEqual { - bool operator()(const cached_partial_non_native_field_multiplication& lhs, - const cached_partial_non_native_field_multiplication& rhs) const - { - return lhs == rhs; - } + }; }; struct non_native_field_multiplication_cross_terms {