Skip to content

Commit a1561db

Browse files
committed
Implement empty list initialization for uninitialized_fill[_n]
Tests for hetero backend remain
1 parent 7f0ec2b commit a1561db

File tree

2 files changed

+127
-2
lines changed

2 files changed

+127
-2
lines changed

include/oneapi/dpl/pstl/glue_memory_defs.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __
4545

4646
// [uninitialized.fill]
4747

48-
template <class _ExecutionPolicy, class _ForwardIterator, class _Tp>
48+
template <class _ExecutionPolicy, class _ForwardIterator,
49+
class _Tp = typename std::iterator_traits<_ForwardIterator>::value_type>
4950
oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy>
5051
uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
5152

52-
template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp>
53+
template <class _ExecutionPolicy, class _ForwardIterator, class _Size,
54+
class _Tp = typename std::iterator_traits<_ForwardIterator>::value_type>
5355
oneapi::dpl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator>
5456
uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value);
5557

test/parallel_api/memory/specialized.algorithms/uninitialized_fill_destroy.pass.cpp

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,126 @@ test_uninitialized_fill_destroy_by_type()
207207
}
208208
}
209209

210+
void test_empty_list_initialization_for_uninitialized_fill()
211+
{
212+
constexpr std::size_t size = 10;
213+
const auto deleter = [](auto ptr) { operator delete(ptr); };
214+
using deleter_type = decltype(deleter);
215+
{
216+
using value_type = TestUtils::Wrapper<int>;
217+
value_type::SetCount(0);
218+
std::unique_ptr<value_type, deleter_type> ptr((value_type*)operator new(sizeof(value_type) * size), deleter);
219+
oneapi::dpl::uninitialized_fill(oneapi::dpl::execution::seq, ptr.get(), ptr.get() + size, {1});
220+
EXPECT_TRUE(std::count_if(ptr.get(), ptr.get() + size, [](auto x) { return (*x.get_my_field()) == 1; }) == size,
221+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill with `seq` policy");
222+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill with `seq` policy");
223+
oneapi::dpl::destroy(oneapi::dpl::execution::seq, ptr.get(), ptr.get() + size);
224+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `seq` policy");
225+
}
226+
{
227+
using value_type = TestUtils::Wrapper<int>;
228+
value_type::SetCount(0);
229+
std::unique_ptr<TestUtils::Wrapper<int>, deleter_type> ptr((value_type*)operator new(sizeof(value_type) * size), deleter);
230+
oneapi::dpl::uninitialized_fill(oneapi::dpl::execution::unseq, ptr.get(), ptr.get() + size, {1});
231+
EXPECT_TRUE(std::count_if(ptr.get(), ptr.get() + size, [](auto x) { return (*x.get_my_field()) == 1; }) == size,
232+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill with `unseq` policy");
233+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill with `unseq` policy");
234+
oneapi::dpl::destroy(oneapi::dpl::execution::unseq, ptr.get(), ptr.get() + size);
235+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `unseq` policy");
236+
}
237+
238+
{
239+
{
240+
using value_type = TestUtils::Wrapper<TestUtils::DefaultInitializedToOne>;
241+
value_type::SetCount(0);
242+
std::unique_ptr<value_type, deleter_type> ptr_custom{(value_type*)operator new(sizeof(value_type) * size), deleter};
243+
oneapi::dpl::uninitialized_fill(oneapi::dpl::execution::par, ptr_custom.get(), ptr_custom.get() + size, {});
244+
EXPECT_TRUE(std::count_if(ptr_custom.get(), ptr_custom.get() + size, [](auto x) { return (*x.get_my_field()) == TestUtils::DefaultInitializedToOne{1}; }) == size,
245+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill with `par` policy");
246+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill with `par` policy");
247+
oneapi::dpl::destroy(oneapi::dpl::execution::par, ptr_custom.get(), ptr_custom.get() + size);
248+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `par` policy");
249+
}
250+
{
251+
using value_type = TestUtils::Wrapper<TestUtils::DefaultInitializedToOne>;
252+
value_type::SetCount(0);
253+
std::unique_ptr<value_type, deleter_type> ptr_custom{(value_type*)operator new(sizeof(value_type) * size), deleter};
254+
oneapi::dpl::uninitialized_fill(oneapi::dpl::execution::par_unseq, ptr_custom.get(), ptr_custom.get() + size, {});
255+
EXPECT_TRUE(std::count_if(ptr_custom.get(), ptr_custom.get() + size, [](auto x) { return (*x.get_my_field()) == TestUtils::DefaultInitializedToOne{1}; }) == size,
256+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill with `par_unseq` policy");
257+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill with `par_unseq` policy");
258+
oneapi::dpl::destroy(oneapi::dpl::execution::par_unseq, ptr_custom.get(), ptr_custom.get() + size);
259+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `par_unseq` policy");
260+
}
261+
}
262+
#if TEST_DPCPP_BACKEND_PRESENT
263+
std::vector<int> v{3,6,5,4,3,7,8,0,2,4};
264+
sycl::buffer<int> buf(v);
265+
auto it = oneapi::dpl::uninitialized_fill(oneapi::dpl::execution::dpcpp_default, oneapi::dpl::begin(buf), oneapi::dpl::end(buf), {});
266+
EXPECT_TRUE(std::count(v.begin(), v.end(), 0) == v.size(), "a sequence is not filled properly by oneapi::dpl::uninitialized_fill with `device_policy` policy");
267+
#endif
268+
}
269+
270+
void test_empty_list_initialization_for_uninitialized_fill_n()
271+
{
272+
constexpr std::size_t size = 10;
273+
const auto deleter = [](auto ptr) { operator delete(ptr); };
274+
using deleter_type = decltype(deleter);
275+
{
276+
using value_type = TestUtils::Wrapper<int>;
277+
value_type::SetCount(0);
278+
std::unique_ptr<value_type, deleter_type> ptr((value_type*)operator new(sizeof(value_type) * size), deleter);
279+
oneapi::dpl::uninitialized_fill_n(oneapi::dpl::execution::seq, ptr.get(), size, {1});
280+
EXPECT_TRUE(std::count_if(ptr.get(), ptr.get() + size, [](auto x) { return (*x.get_my_field()) == 1; }) == size,
281+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill_n with `seq` policy");
282+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill_n with `seq` policy");
283+
oneapi::dpl::destroy(oneapi::dpl::execution::seq, ptr.get(), ptr.get() + size);
284+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `seq` policy");
285+
}
286+
{
287+
using value_type = TestUtils::Wrapper<int>;
288+
value_type::SetCount(0);
289+
std::unique_ptr<TestUtils::Wrapper<int>, deleter_type> ptr((value_type*)operator new(sizeof(value_type) * size), deleter);
290+
oneapi::dpl::uninitialized_fill_n(oneapi::dpl::execution::unseq, ptr.get(), size, {1});
291+
EXPECT_TRUE(std::count_if(ptr.get(), ptr.get() + size, [](auto x) { return (*x.get_my_field()) == 1; }) == size,
292+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill_n with `unseq` policy");
293+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill_n with `unseq` policy");
294+
oneapi::dpl::destroy(oneapi::dpl::execution::unseq, ptr.get(), ptr.get() + size);
295+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `unseq` policy");
296+
}
297+
298+
{
299+
{
300+
using value_type = TestUtils::Wrapper<TestUtils::DefaultInitializedToOne>;
301+
value_type::SetCount(0);
302+
std::unique_ptr<value_type, deleter_type> ptr_custom{(value_type*)operator new(sizeof(value_type) * size), deleter};
303+
oneapi::dpl::uninitialized_fill_n(oneapi::dpl::execution::par, ptr_custom.get(), size, {});
304+
EXPECT_TRUE(std::count_if(ptr_custom.get(), ptr_custom.get() + size, [](auto x) { return (*x.get_my_field()) == TestUtils::DefaultInitializedToOne{1}; }) == size,
305+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill_n with `par` policy");
306+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill_n with `par` policy");
307+
oneapi::dpl::destroy(oneapi::dpl::execution::par, ptr_custom.get(), ptr_custom.get() + size);
308+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `par` policy");
309+
}
310+
{
311+
using value_type = TestUtils::Wrapper<TestUtils::DefaultInitializedToOne>;
312+
value_type::SetCount(0);
313+
std::unique_ptr<value_type, deleter_type> ptr_custom{(value_type*)operator new(sizeof(value_type) * size), deleter};
314+
oneapi::dpl::uninitialized_fill_n(oneapi::dpl::execution::par_unseq, ptr_custom.get(), size, {});
315+
EXPECT_TRUE(std::count_if(ptr_custom.get(), ptr_custom.get() + size, [](auto x) { return (*x.get_my_field()) == TestUtils::DefaultInitializedToOne{1}; }) == size,
316+
"a sequence is not filled properly by oneapi::dpl::uninitialized_fill_n with `par_unseq` policy");
317+
EXPECT_TRUE(value_type::Count() == 10, "wrong effect of calling `oneapi::dpl::uninitialized_fill_n with `par_unseq` policy");
318+
oneapi::dpl::destroy(oneapi::dpl::execution::par_unseq, ptr_custom.get(), ptr_custom.get() + size);
319+
EXPECT_TRUE(value_type::Count() == 0, "wrong effect of calling `oneapi::dpl::destroy with `par_unseq` policy");
320+
}
321+
}
322+
#if TEST_DPCPP_BACKEND_PRESENT
323+
std::vector<int> v{3,6,5,4,3,7,8,0,2,4};
324+
sycl::buffer<int> buf(v);
325+
auto it = oneapi::dpl::uninitialized_fill_n(oneapi::dpl::execution::dpcpp_default, oneapi::dpl::begin(buf), oneapi::dpl::end(buf), {});
326+
EXPECT_TRUE(std::count(v.begin(), v.end(), 0) == v.size(), "a sequence is not filled properly by oneapi::dpl::uninitialized_fill_n with `device_policy` policy");
327+
#endif
328+
}
329+
210330
int
211331
main()
212332
{
@@ -220,5 +340,8 @@ main()
220340
test_uninitialized_fill_destroy_by_type<Wrapper<std::int8_t*>>();
221341
#endif
222342

343+
test_empty_list_initialization_for_uninitialized_fill();
344+
test_empty_list_initialization_for_uninitialized_fill_n();
345+
223346
return done();
224347
}

0 commit comments

Comments
 (0)