74 size_t size_override = 0,
83 const bool has_active_ranges = active_region_data.
size() > 0;
87 size_t domain_size = size_override == 0 ? full_polynomials.
get_polynomial_size() : size_override;
90 auto get_active_range_poly_idx = [&](
size_t i) {
return has_active_ranges ? active_region_data.get_idx(i) : i; };
92 size_t active_domain_size = has_active_ranges ? active_region_data.size() : domain_size;
105 parallel_for(active_range_thread_data.num_threads, [&](
size_t thread_idx) {
106 const size_t start = active_range_thread_data.start[thread_idx];
107 const size_t end = active_range_thread_data.end[thread_idx];
108 typename Flavor::AllValues row;
109 for (size_t i = start; i < end; ++i) {
111 auto row_idx = get_active_range_poly_idx(i);
112 if constexpr (IsUltraOrMegaHonk<Flavor>) {
113 row = full_polynomials.get_row_for_permutation_arg(row_idx);
115 row = full_polynomials.get_row(row_idx);
118 GrandProdRelation::template compute_grand_product_numerator<Accumulator>(row, relation_parameters);
120 GrandProdRelation::template compute_grand_product_denominator<Accumulator>(row, relation_parameters);
139 std::vector<FF> partial_numerators(active_range_thread_data.num_threads);
140 std::vector<FF> partial_denominators(active_range_thread_data.num_threads);
142 parallel_for(active_range_thread_data.num_threads, [&](
size_t thread_idx) {
143 const size_t start = active_range_thread_data.start[thread_idx];
144 const size_t end = active_range_thread_data.end[thread_idx];
145 for (size_t i = start; i < end - 1; ++i) {
146 numerator.at(i + 1) *= numerator[i];
147 denominator.at(i + 1) *= denominator[i];
149 partial_numerators[thread_idx] = numerator[end - 1];
150 partial_denominators[thread_idx] = denominator[end - 1];
156 parallel_for(active_range_thread_data.num_threads, [&](
size_t thread_idx) {
157 const size_t start = active_range_thread_data.start[thread_idx];
158 const size_t end = active_range_thread_data.end[thread_idx];
159 if (thread_idx > 0) {
160 FF numerator_scaling = 1;
161 FF denominator_scaling = 1;
163 for (size_t j = 0; j < thread_idx; ++j) {
164 numerator_scaling *= partial_numerators[j];
165 denominator_scaling *= partial_denominators[j];
167 for (size_t i = start; i < end; ++i) {
168 numerator.at(i) = numerator[i] * numerator_scaling;
169 denominator.at(i) = denominator[i] * denominator_scaling;
181 auto& grand_product_polynomial = GrandProdRelation::get_grand_product_polynomial(full_polynomials);
183 BB_ASSERT_EQ(grand_product_polynomial.start_index(), 1U);
186 if constexpr (IsUltraOrMegaHonk<Flavor>) {
187 grand_product_polynomial.at(1) = 1;
191 parallel_for(active_range_thread_data.num_threads, [&](
size_t thread_idx) {
192 const size_t start = active_range_thread_data.start[thread_idx];
193 const size_t end = active_range_thread_data.end[thread_idx];
194 for (size_t i = start; i < end; ++i) {
195 const auto poly_idx = get_active_range_poly_idx(i + 1);
196 grand_product_polynomial.at(poly_idx) = numerator[i] * denominator[i];
204 if (has_active_ranges) {
206 parallel_for(full_domain_thread_data.num_threads, [&](
size_t thread_idx) {
207 const size_t start = full_domain_thread_data.start[thread_idx];
208 const size_t end = full_domain_thread_data.end[thread_idx];
209 for (size_t i = start; i < end; ++i) {
210 for (size_t j = 0; j < active_region_data.num_ranges() - 1; ++j) {
211 const size_t previous_range_end = active_region_data.get_range(j).second;
212 const size_t next_range_start = active_region_data.get_range(j + 1).first;
214 if (i >= previous_range_end && i < next_range_start) {
215 grand_product_polynomial.at(i) = grand_product_polynomial[next_range_start];