Skip to content

Commit cd9eb83

Browse files
add 5 new core unit tests covering STL containers, hash, spin_mutex, fiber, and platform utilities
1 parent 869d389 commit cd9eb83

File tree

6 files changed

+1266
-0
lines changed

6 files changed

+1266
-0
lines changed

src/tests/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ luisa_compute_add_test(test_mathematics unit/core/test_mathematics.cpp
3737
luisa_compute_add_test(test_matrix unit/core/test_matrix.cpp LABELS "unit;unit_core")
3838
luisa_compute_add_test(test_pool unit/core/test_pool.cpp LABELS "unit;unit_core")
3939
luisa_compute_add_test(test_type unit/core/test_type.cpp LABELS "unit;unit_core")
40+
luisa_compute_add_test(test_stl_containers unit/core/test_stl_containers.cpp LABELS "unit;unit_core")
41+
luisa_compute_add_test(test_hash unit/core/test_hash.cpp LABELS "unit;unit_core")
42+
luisa_compute_add_test(test_spin_mutex unit/core/test_spin_mutex.cpp LABELS "unit;unit_core")
43+
luisa_compute_add_test(test_fiber unit/core/test_fiber.cpp LABELS "unit;unit_core")
44+
luisa_compute_add_test(test_platform_utils unit/core/test_platform.cpp LABELS "unit;unit_core")
4045

4146
if (LUISA_COMPUTE_ENABLE_GUI)
4247
endif ()

src/tests/unit/core/test_fiber.cpp

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
// Test for luisa::fiber utilities.
2+
// Covers: scheduler, event, counter, Future<T>, parallel, async, async_parallel.
3+
4+
#include "ut/ut.hpp"
5+
6+
#include <atomic>
7+
#include <luisa/core/fiber.h>
8+
#include <luisa/core/logging.h>
9+
10+
using namespace boost::ut;
11+
using namespace boost::ut::literals;
12+
13+
// All fiber tests need a scheduler, so we create one for the process lifetime.
14+
static luisa::fiber::scheduler global_scheduler;
15+
16+
// ---- scheduler ----
17+
18+
static inline const auto reg_scheduler_worker_count = [] {
19+
"scheduler_worker_count"_test = [] {
20+
auto count = luisa::fiber::worker_thread_count();
21+
expect(count > 0u) << "worker_thread_count must be positive";
22+
};
23+
return 0;
24+
}();
25+
26+
// ---- event ----
27+
28+
static inline const auto reg_event_manual = [] {
29+
"event_manual_mode"_test = [] {
30+
luisa::fiber::event evt;
31+
expect(!evt.test()) << "event should not be signalled initially";
32+
expect(!evt.is_signalled());
33+
34+
evt.signal();
35+
expect(evt.test()) << "event should be signalled after signal()";
36+
expect(evt.is_signalled());
37+
38+
// manual mode: test() doesn't clear the signal
39+
expect(evt.is_signalled()) << "manual event stays signalled after test()";
40+
41+
evt.clear();
42+
expect(!evt.is_signalled()) << "event should be cleared after clear()";
43+
};
44+
return 0;
45+
}();
46+
47+
static inline const auto reg_event_wait = [] {
48+
"event_signal_wait"_test = [] {
49+
luisa::fiber::event evt;
50+
51+
// Signal from a scheduled task, wait on main fiber
52+
luisa::fiber::schedule([evt]() mutable {
53+
evt.signal();
54+
});
55+
evt.wait();
56+
expect(evt.is_signalled());
57+
};
58+
return 0;
59+
}();
60+
61+
static inline const auto reg_event_auto_mode = [] {
62+
"event_auto_mode"_test = [] {
63+
luisa::fiber::event evt{luisa::fiber::event::Mode::Auto, false};
64+
expect(!evt.test());
65+
66+
evt.signal();
67+
// In auto mode, test() returns true and clears the signal
68+
bool was_signalled = evt.test();
69+
expect(was_signalled);
70+
// After auto-clear, should not be signalled
71+
expect(!evt.is_signalled());
72+
};
73+
return 0;
74+
}();
75+
76+
// ---- counter (WaitGroup) ----
77+
78+
static inline const auto reg_counter_basic = [] {
79+
"counter_basic"_test = [] {
80+
luisa::fiber::counter c{3};
81+
82+
std::atomic<int> completed{0};
83+
for (int i = 0; i < 3; ++i) {
84+
luisa::fiber::schedule([c, &completed]() mutable {
85+
completed.fetch_add(1, std::memory_order_relaxed);
86+
c.done();
87+
});
88+
}
89+
c.wait();
90+
expect(completed.load() == 3_i) << "all 3 tasks should have completed";
91+
};
92+
return 0;
93+
}();
94+
95+
// ---- Future<T> ----
96+
97+
static inline const auto reg_future_basic = [] {
98+
"future_basic"_test = [] {
99+
luisa::fiber::Future<int> fut;
100+
expect(!fut.test()) << "future should not be signalled initially";
101+
expect(!fut.isSignalled());
102+
103+
fut.signal(42);
104+
expect(fut.test());
105+
expect(fut.isSignalled());
106+
107+
auto &val = fut.wait();
108+
expect(val == 42_i);
109+
};
110+
return 0;
111+
}();
112+
113+
static inline const auto reg_future_async = [] {
114+
"future_from_async"_test = [] {
115+
auto fut = luisa::fiber::async([]() -> int {
116+
return 100;
117+
});
118+
auto &result = fut.wait();
119+
expect(result == 100_i);
120+
};
121+
return 0;
122+
}();
123+
124+
static inline const auto reg_future_clear = [] {
125+
"future_clear"_test = [] {
126+
luisa::fiber::Future<int> fut;
127+
fut.signal(10);
128+
expect(fut.isSignalled());
129+
130+
fut.clear();
131+
expect(!fut.isSignalled());
132+
};
133+
return 0;
134+
}();
135+
136+
static inline const auto reg_future_signal_overwrite = [] {
137+
"future_signal_overwrite"_test = [] {
138+
luisa::fiber::Future<int> fut;
139+
fut.signal(1);
140+
expect(fut.wait() == 1_i);
141+
142+
// Signal again overwrites the value
143+
fut.signal(2);
144+
expect(fut.wait() == 2_i);
145+
};
146+
return 0;
147+
}();
148+
149+
// ---- async (void return) ----
150+
151+
static inline const auto reg_async_void = [] {
152+
"async_void_return"_test = [] {
153+
std::atomic<bool> executed{false};
154+
auto evt = luisa::fiber::async([&executed]() {
155+
executed.store(true, std::memory_order_release);
156+
});
157+
evt.wait();
158+
expect(executed.load(std::memory_order_acquire)) << "async void lambda should have executed";
159+
};
160+
return 0;
161+
}();
162+
163+
// ---- parallel ----
164+
165+
static inline const auto reg_parallel_basic = [] {
166+
"parallel_basic"_test = [] {
167+
constexpr uint32_t N = 1000;
168+
std::atomic<uint32_t> sum{0};
169+
luisa::fiber::parallel(N, [&sum](uint32_t i) {
170+
sum.fetch_add(i, std::memory_order_relaxed);
171+
});
172+
// sum of 0..999 = 999*1000/2 = 499500
173+
expect(sum.load() == 499500u);
174+
};
175+
return 0;
176+
}();
177+
178+
static inline const auto reg_parallel_single_job = [] {
179+
"parallel_single_job"_test = [] {
180+
std::atomic<int> called{0};
181+
luisa::fiber::parallel(1u, [&called](uint32_t) {
182+
called.fetch_add(1, std::memory_order_relaxed);
183+
});
184+
expect(called.load() == 1_i);
185+
};
186+
return 0;
187+
}();
188+
189+
static inline const auto reg_parallel_zero_jobs = [] {
190+
"parallel_zero_jobs"_test = [] {
191+
std::atomic<int> called{0};
192+
luisa::fiber::parallel(0u, [&called](uint32_t) {
193+
called.fetch_add(1, std::memory_order_relaxed);
194+
});
195+
expect(called.load() == 0_i) << "zero jobs should call lambda zero times";
196+
};
197+
return 0;
198+
}();
199+
200+
static inline const auto reg_parallel_range = [] {
201+
"parallel_range_signature"_test = [] {
202+
// Test the (job_count, lambda(begin, end)) overload
203+
constexpr uint32_t N = 100;
204+
std::atomic<uint32_t> total_range{0};
205+
luisa::fiber::parallel(N, [&total_range](uint32_t begin, uint32_t end) {
206+
total_range.fetch_add(end - begin, std::memory_order_relaxed);
207+
});
208+
expect(total_range.load() == N);
209+
};
210+
return 0;
211+
}();
212+
213+
// ---- async_parallel ----
214+
215+
static inline const auto reg_async_parallel = [] {
216+
"async_parallel_basic"_test = [] {
217+
constexpr uint32_t N = 500;
218+
std::atomic<uint32_t> sum{0};
219+
auto c = luisa::fiber::async_parallel(N, [&sum](uint32_t i) {
220+
sum.fetch_add(i, std::memory_order_relaxed);
221+
});
222+
c.wait();
223+
// sum of 0..499 = 499*500/2 = 124750
224+
expect(sum.load() == 124750u);
225+
};
226+
return 0;
227+
}();
228+
229+
static inline const auto reg_async_parallel_with_counter = [] {
230+
"async_parallel_with_external_counter"_test = [] {
231+
constexpr uint32_t N = 200;
232+
std::atomic<uint32_t> count{0};
233+
luisa::fiber::counter c{0u};
234+
235+
luisa::fiber::async_parallel(c, N, [&count](uint32_t) {
236+
count.fetch_add(1, std::memory_order_relaxed);
237+
});
238+
c.wait();
239+
expect(count.load() == N);
240+
};
241+
return 0;
242+
}();
243+
244+
int main() {}

0 commit comments

Comments
 (0)