Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
thread.test.cpp
Go to the documentation of this file.
1#include "thread.hpp"
3#include <atomic>
4#include <gtest/gtest.h>
5#include <set>
6#include <thread>
7
8namespace bb {
9
10class ThreadTest : public ::testing::Test {
11 protected:
12 void SetUp() override
13 {
14 // Store original concurrency for restoration
16 }
17
18 void TearDown() override
19 {
20 // Restore original concurrency
22 }
23
25};
26
27// Test basic parallel_for functionality
28TEST_F(ThreadTest, BasicParallelFor)
29{
30 constexpr size_t num_iterations = 100;
31 std::vector<char> flags(num_iterations, 0);
32
33 parallel_for(num_iterations, [&](size_t i) { flags[i] = 1; });
34
35 // All iterations should have been executed
36 for (size_t i = 0; i < num_iterations; ++i) {
37 EXPECT_TRUE(flags[i]);
38 }
39}
40
41// Test thread count calculation
42TEST_F(ThreadTest, CalculateNumThreads)
43{
45
46 // With default min iterations per thread (16)
47 // 160 iterations / 16 = 10 desired threads, min(10, 8) = 8
48 EXPECT_EQ(calculate_num_threads(160), 8);
49
50 // 64 iterations / 16 = 4 desired threads, min(4, 8) = 4
51 EXPECT_EQ(calculate_num_threads(64), 4);
52
53 // 8 iterations / 16 = 0 desired threads, but should be at least 1
54 EXPECT_EQ(calculate_num_threads(8), 1);
55
56 // Custom min iterations per thread
57 // 100 iterations / 10 = 10 desired threads, min(10, 8) = 8
58 EXPECT_EQ(calculate_num_threads(100, 10), 8);
59
60 // 30 iterations / 10 = 3 desired threads, min(3, 8) = 3
61 EXPECT_EQ(calculate_num_threads(30, 10), 3);
62}
63
64// Test parallel_for with zero iterations
65TEST_F(ThreadTest, ZeroIterations)
66{
67 size_t counter = 0;
68
69 parallel_for(0, [&](size_t) { counter++; });
70
71 EXPECT_EQ(counter, 0);
72}
73
74// Test parallel_for with one iteration
75TEST_F(ThreadTest, OneIteration)
76{
77 size_t counter = 0;
78
79 parallel_for(1, [&](size_t i) {
80 counter++;
81 EXPECT_EQ(i, 0);
82 });
83
84 EXPECT_EQ(counter, 1);
85}
86
87// Test parallel_for_range
88TEST_F(ThreadTest, ParallelForRange)
89{
90 constexpr size_t num_points = 100;
91 std::vector<char> flags(num_points, 0);
92
93 parallel_for_range(num_points, [&](size_t start, size_t end) {
94 for (size_t i = start; i < end; ++i) {
95 flags[i] = 1;
96 }
97 });
98
99 // All iterations should have been executed
100 for (size_t i = 0; i < num_points; ++i) {
101 EXPECT_TRUE(flags[i]);
102 }
103}
104
105// Test parallel_for_range with threshold
106TEST_F(ThreadTest, ParallelForRangeThreshold)
107{
108 constexpr size_t num_points = 10;
109 std::vector<char> flags(num_points, 0);
110
111 std::atomic<size_t> call_count{ 0 };
112
113 // Set threshold to 10, so with exactly 10 points it should run sequentially (1 call)
115 num_points,
116 [&](size_t start, size_t end) {
117 call_count++;
118 for (size_t i = start; i < end; ++i) {
119 flags[i] = 1;
120 }
121 },
122 10);
123
124 // All iterations should have been executed
125 for (size_t i = 0; i < num_points; ++i) {
126 EXPECT_TRUE(flags[i]);
127 }
128
129 // Should have been called exactly once (sequential)
130 EXPECT_EQ(call_count, 1);
131}
132
133// Test get_num_cpus with different hardware concurrency values
134TEST_F(ThreadTest, HardwareConcurrency)
135{
137 EXPECT_EQ(get_num_cpus(), 1);
138
140 EXPECT_EQ(get_num_cpus(), 4);
141
143 EXPECT_EQ(get_num_cpus(), 16);
144
146 EXPECT_EQ(get_num_cpus(), 128);
147}
148
149// Test that spawned threads can use parallel_for with set_parallel_for_concurrency
150TEST_F(ThreadTest, SpawnedThreadsCanUseParallelFor)
151{
153
154 constexpr size_t num_outer = 2;
155 constexpr size_t num_inner = 100;
156 std::vector<std::vector<char>> results(num_outer, std::vector<char>(num_inner, 0));
157
158 auto worker = [&](size_t outer_idx) {
160 parallel_for(num_inner, [&](size_t inner_idx) { results[outer_idx][inner_idx] = 1; });
161 };
162
163 std::vector<std::thread> threads;
164 for (size_t i = 0; i < num_outer; ++i) {
165 threads.emplace_back(worker, i);
166 }
167 for (auto& t : threads) {
168 t.join();
169 }
170
171 // Verify all work completed
172 for (size_t i = 0; i < num_outer; ++i) {
173 for (size_t j = 0; j < num_inner; ++j) {
174 EXPECT_TRUE(results[i][j]);
175 }
176 }
177}
178} // namespace bb
void TearDown() override
void SetUp() override
size_t original_concurrency
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:155
size_t get_num_cpus()
Definition thread.cpp:33
size_t calculate_num_threads(size_t num_iterations, size_t min_iterations_per_thread)
calculates number of threads to create based on minimum iterations per thread
Definition thread.cpp:233
void set_parallel_for_concurrency(size_t num_cores)
Definition thread.cpp:23
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
Definition thread.cpp:111
void parallel_for_range(size_t num_points, const std::function< void(size_t, size_t)> &func, size_t no_multhreading_if_less_or_equal)
Split a loop into several loops running in parallel.
Definition thread.cpp:141
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13