Skip to content

Commit 7e69868

Browse files
committed
Update libdispatch test
1 parent 5a30183 commit 7e69868

1 file changed

Lines changed: 91 additions & 3 deletions

File tree

test/exec/test_libdispatch.cpp

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "test_common/catch2.hpp"
2020
#include "test_common/type_helpers.hpp"
2121

22+
#include <atomic>
2223
#include <numeric>
2324
#include <utility>
2425
#include <vector>
@@ -108,6 +109,92 @@ namespace
108109
CHECK(res == 30);
109110
}
110111

112+
TEST_CASE("libdispatch queue bulk_chunked uses one task per index for parallel policies")
113+
{
114+
exec::libdispatch_queue queue;
115+
auto sch = queue.get_scheduler();
116+
117+
std::vector<int> visited(5, 0);
118+
std::atomic<int> chunks{0};
119+
120+
auto sender = STDEXEC::schedule(sch)
121+
| STDEXEC::bulk_chunked(STDEXEC::par,
122+
5,
123+
[&](int begin, int end)
124+
{
125+
++chunks;
126+
for (; begin != end; ++begin)
127+
visited[begin] = 1;
128+
});
129+
130+
REQUIRE(STDEXEC::sync_wait(std::move(sender)).has_value());
131+
132+
CHECK(chunks.load() == 5);
133+
CHECK(visited == std::vector<int>{1, 1, 1, 1, 1});
134+
}
135+
136+
TEST_CASE("libdispatch queue runs a non-parallel bulk_chunked in a single task")
137+
{
138+
exec::libdispatch_queue queue;
139+
auto sch = queue.get_scheduler();
140+
141+
std::vector<int> bounds;
142+
143+
auto sender = STDEXEC::schedule(sch)
144+
| STDEXEC::bulk_chunked(STDEXEC::seq,
145+
5,
146+
[&](int begin, int end)
147+
{
148+
bounds.push_back(begin);
149+
bounds.push_back(end);
150+
});
151+
152+
REQUIRE(STDEXEC::sync_wait(std::move(sender)).has_value());
153+
154+
// `seq` forbids splitting the index space, so a single chunk covers all of it
155+
CHECK(bounds == std::vector<int>{0, 5});
156+
}
157+
158+
TEST_CASE("libdispatch queue bulk_unchunked should call callback function with every index")
159+
{
160+
exec::libdispatch_queue queue;
161+
auto sch = queue.get_scheduler();
162+
163+
std::vector<int> data{1, 2, 3, 4, 5};
164+
auto size = data.size();
165+
auto expensive_computation = [](auto i, auto &data)
166+
{
167+
data[i] = 2 * data[i];
168+
};
169+
auto add = [](auto const &data)
170+
{
171+
return std::accumulate(std::begin(data), std::end(data), 0);
172+
};
173+
auto sender = STDEXEC::just(std::move(data)) | STDEXEC::continues_on(sch)
174+
| STDEXEC::bulk_unchunked(STDEXEC::par, size, expensive_computation)
175+
| STDEXEC::then(add);
176+
177+
auto [res] = STDEXEC::sync_wait(sender).value();
178+
CHECK(res == 30);
179+
}
180+
181+
TEST_CASE("libdispatch queue runs a non-parallel bulk_unchunked in a single task")
182+
{
183+
exec::libdispatch_queue queue;
184+
auto sch = queue.get_scheduler();
185+
186+
std::vector<int> indices;
187+
188+
auto sender = STDEXEC::schedule(sch)
189+
| STDEXEC::bulk_unchunked(STDEXEC::seq,
190+
4,
191+
[&](int idx) { indices.push_back(idx); });
192+
193+
REQUIRE(STDEXEC::sync_wait(std::move(sender)).has_value());
194+
195+
CHECK(indices == std::vector<int>{0, 1, 2, 3});
196+
}
197+
111198
#if !STDEXEC_NO_STDCPP_EXCEPTIONS()
112199
TEST_CASE("libdispatch bulk should handle exceptions gracefully")
113200
{
@@ -241,10 +328,11 @@ namespace
241328
TEST_CASE("libdispatch bulk connects an lvalue child sender as an lvalue")
242329
{
243330
exec::libdispatch_queue queue;
244-
auto fun = [](int, int &) noexcept {};
245-
using sender_t = exec::__libdispatch::bulk_sender<lvalue_connect_sender, int, decltype(fun)>;
331+
auto fun = [](int, int, int &) noexcept {};
332+
using sender_t =
333+
exec::__libdispatch::bulk_sender<lvalue_connect_sender, int, decltype(fun), true>;
246334

247-
sender_t sender{queue, lvalue_connect_sender{}, 0, std::move(fun)};
335+
sender_t sender{queue, lvalue_connect_sender{}, 0, std::move(fun), true};
248336
auto result = STDEXEC::sync_wait(sender);
249337

250338
REQUIRE(result.has_value());

0 commit comments

Comments
 (0)