-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add explicit deduction guides for blocked_nd_range #1525
Changes from 15 commits
eeed3f8
3fe65dc
ee470d8
1a6717f
887e933
5309e14
6ccb883
559ce1e
64610c6
fe56f9f
54b0137
f45b27f
1ccd670
67d4a76
75b60d9
ed3b67d
7049dd2
3935022
1110b0c
6337734
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -147,6 +147,36 @@ class blocked_nd_range : public blocked_nd_range_impl<Value, N> { | |
using base::base; | ||
}; | ||
|
||
#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT | ||
template <typename Value, unsigned int... Ns, | ||
typename = std::enable_if_t<(... && (Ns == 2 || Ns == 3))>> | ||
blocked_nd_range(const Value (&... dim)[Ns]) | ||
-> blocked_nd_range<Value, sizeof...(Ns)>; | ||
|
||
template <typename Value, typename... Values, | ||
typename = std::enable_if_t<(... && std::is_same_v<Value, Values>)>> | ||
blocked_nd_range(blocked_range<Value>, blocked_range<Values>...) | ||
-> blocked_nd_range<Value, 1 + sizeof...(Values)>; | ||
|
||
template <typename Value, unsigned int N, | ||
typename = std::enable_if_t<(N != 2 && N != 3)>> | ||
blocked_nd_range(const Value (&)[N]) | ||
-> blocked_nd_range<Value, N>; | ||
|
||
template <typename Value, unsigned int N> | ||
blocked_nd_range(const Value (&)[N], typename blocked_nd_range<Value, N>::size_type) | ||
-> blocked_nd_range<Value, N>; | ||
|
||
template <typename Value, unsigned int N> | ||
blocked_nd_range(blocked_nd_range<Value, N>, oneapi::tbb::split) | ||
-> blocked_nd_range<Value, N>; | ||
|
||
template <typename Value, unsigned int N> | ||
blocked_nd_range(blocked_nd_range<Value, N>, oneapi::tbb::proportional_split) | ||
-> blocked_nd_range<Value, N>; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Splitting constructors are not really for users but for algorithms. Do we need deduction guides for these? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think the main purpose of the splitting constructors are TBB algorithms that don't currently use CTAD. But they are still part of the specification and the user may expect that for some implementation these constructors can be covered by the implicit deduction guides (see short example here). I feel that these deduction guides can be excluded from the future specification, but should be added into the implementation. |
||
#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT | ||
|
||
} // namespace d1 | ||
} // namespace detail | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
Copyright (c) 2017-2024 Intel Corporation | ||
Copyright (c) 2017-2025 Intel Corporation | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
|
@@ -291,3 +291,71 @@ TEST_CASE("blocked_nd_range proportional splitting") { | |
utils::check_range_bounds_after_splitting(original.dim(0), first.dim(0), second.dim(0), expected_first_end); | ||
} | ||
} | ||
|
||
#if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT | ||
//! Testing blocked_rangeNd deduction guides | ||
//! \brief \ref interface | ||
TEST_CASE("blocked_rangeNd deduction guides") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The test misses any checks for constructing explicitly from an array. It needs to check construction from arrays of different sizes (incl. 2 and 3), with and without a grainsize argument. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
using oneapi::tbb::blocked_nd_range; | ||
|
||
std::vector<const unsigned long*> v; | ||
using iterator = typename decltype(v)::iterator; | ||
|
||
oneapi::tbb::blocked_range<int> dim_range(0, 100); | ||
|
||
blocked_nd_range<int, 2> source_range(dim_range, dim_range); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we test with something more fancy than int for the value type? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
{ | ||
blocked_nd_range range(dim_range, dim_range, dim_range); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 3>>); | ||
} | ||
{ | ||
blocked_nd_range range({v.begin(), v.end()}, {v.begin(), v.end()}); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<iterator, 2>>); | ||
} | ||
{ | ||
blocked_nd_range range({0, 100}, {0, 100, 5}, {0, 100}, {0, 100, 5}); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 4>>); | ||
} | ||
{ | ||
blocked_nd_range range({100}); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 1>>); | ||
} | ||
{ | ||
blocked_nd_range range({100}, 5); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 1>>); | ||
} | ||
{ | ||
blocked_nd_range range({100, 200}, 5); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 2>>); | ||
} | ||
{ | ||
blocked_nd_range range({100, 200, 300}, 5); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 3>>); | ||
} | ||
{ | ||
blocked_nd_range range({100, 200, 300, 400}); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 4>>); | ||
} | ||
{ | ||
blocked_nd_range range({100, 200, 300, 400}, 5); | ||
static_assert(std::is_same_v<decltype(range), blocked_nd_range<int, 4>>); | ||
} | ||
{ | ||
blocked_nd_range range(source_range, oneapi::tbb::split{}); | ||
static_assert(std::is_same_v<decltype(range), decltype(source_range)>); | ||
} | ||
{ | ||
blocked_nd_range range(source_range, oneapi::tbb::proportional_split{1, 3}); | ||
static_assert(std::is_same_v<decltype(range), decltype(source_range)>); | ||
} | ||
{ | ||
blocked_nd_range range(source_range); | ||
static_assert(std::is_same_v<decltype(range), decltype(source_range)>); | ||
} | ||
{ | ||
blocked_nd_range range(std::move(source_range)); | ||
static_assert(std::is_same_v<decltype(range), decltype(source_range)>); | ||
} | ||
} | ||
#endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the argument is explicitly an array of 2 or 3 elements, not a braced init list? Seems there is no deduction guide for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing single array of 2 or 3 elements should be considered as a valid use-case, but having an extra deduction guide for array of 2 or 3 will also cover the braced-init-list of size 2 and 3.
As we discussed braced-init-list of size 2 and 3 should not be supported because of ambiguity between 1-D range constructed from single blocked_range and 2/3-D range constructed from the array.
This use-case is the main open question in the RFC #1607
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed in the RFC, added support for both single array and single braced-init-list with preference to multi-dimensional ranges