Skip to content

Commit eb31c2d

Browse files
[SYCL] Use mp11 to sort compile-time properties (#8168)
Currently, compile-time properties are sorted using a hand-written implementation of merge-sort. However, this PR propose to sort compile-time properties using Boost's MP11 metaprogramming library instead. Mp11's sorting functionality is more optimized and it also improves the overall code readability (83 LOC vs just 11 LOC). PS:- This PR does not introduce any new dependency as Mp11 is already integrated into the code base (See [#5791](#5791)).
1 parent ba26732 commit eb31c2d

File tree

2 files changed

+13
-85
lines changed

2 files changed

+13
-85
lines changed

sycl/cmake/modules/PreprocessBoostMp11Headers.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ function(preprocess_mp11_header)
3737
# `namespace sycl { namespace detail { namespace boost { ... } } }`
3838
string(REGEX REPLACE
3939
"(\n[ \t]*namespace[ \t\n\r]+boost)"
40-
"namespace sycl\n{\nnamespace detail\n{\\1"
40+
"namespace sycl\n{\ninline namespace _V1\n{\nnamespace detail\n{\\1"
4141
FILE_CONTENTS "${FILE_CONTENTS}")
4242
# ... use '} // namespace boost' as a marker for end-of-scope '}' replacement
4343
string(REGEX REPLACE
4444
"(\n[ \t]*}[ \t]*//[ \t]*namespace[ \t]+boost[ \t]*\n)"
45-
"\\1} // namespace detail\n} // namespace sycl\n"
45+
"\\1} // namespace detail\n} // namespace _V1\n} // namespace sycl\n"
4646
FILE_CONTENTS "${FILE_CONTENTS}")
4747
# 3) replace `boost` in `#include <boost/...>` or `#include "boost/..."` with
4848
# `sycl/detail/boost`

sycl/include/sycl/ext/oneapi/properties/property_utils.hpp

Lines changed: 11 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <sycl/detail/property_helper.hpp>
1212
#include <sycl/ext/oneapi/properties/property.hpp>
13+
#include <sycl/detail/boost/mp11.hpp>
1314

1415
#include <tuple>
1516

@@ -106,93 +107,20 @@ template <typename RHS> struct SelectNonVoid<void, RHS> {
106107
using type = RHS;
107108
};
108109

109-
// Merges two tuples by recursively extracting the type with the minimum
110-
// PropertyID in the two tuples and prepending it to the merging of the
111-
// remaining elements.
112-
template <typename T1, typename T2> struct Merge {};
113-
template <typename... LTs> struct Merge<std::tuple<LTs...>, std::tuple<>> {
114-
using type = std::tuple<LTs...>;
110+
// Sort types accoring to their PropertyID.
111+
struct SortByPropertyId {
112+
template <typename T1, typename T2>
113+
using fn = sycl::detail::boost::mp11::mp_bool<(PropertyID<T1>::value <
114+
PropertyID<T2>::value)>;
115115
};
116-
template <typename... RTs> struct Merge<std::tuple<>, std::tuple<RTs...>> {
117-
using type = std::tuple<RTs...>;
118-
};
119-
template <typename... LTs, typename... RTs>
120-
struct Merge<std::tuple<LTs...>, std::tuple<RTs...>> {
121-
using l_head = GetFirstType<LTs...>;
122-
using r_head = GetFirstType<RTs...>;
123-
static constexpr bool left_has_min =
124-
PropertyID<l_head>::value < PropertyID<r_head>::value;
125-
using l_split = HeadSplit<std::tuple<LTs...>, left_has_min>;
126-
using r_split = HeadSplit<std::tuple<RTs...>, !left_has_min>;
127-
using min = typename SelectNonVoid<typename l_split::htype,
128-
typename r_split::htype>::type;
129-
using merge_tails =
130-
typename Merge<typename l_split::ttype, typename r_split::ttype>::type;
131-
using type = typename PrependTuple<min, merge_tails>::type;
132-
};
133-
134-
// Creates pairs of tuples with a single element from a tuple with N elements.
135-
// Resulting tuple will have ceil(N/2) elements.
136-
template <typename...> struct CreateTuplePairs {
137-
using type = typename std::tuple<>;
138-
};
139-
template <typename T> struct CreateTuplePairs<T> {
140-
using type = typename std::tuple<std::pair<std::tuple<T>, std::tuple<>>>;
141-
};
142-
template <typename L, typename R, typename... Rest>
143-
struct CreateTuplePairs<L, R, Rest...> {
144-
using type =
145-
typename PrependTuple<std::pair<std::tuple<L>, std::tuple<R>>,
146-
typename CreateTuplePairs<Rest...>::type>::type;
147-
};
148-
149-
// Merges pairs of tuples and creates new pairs of the merged pairs. Let N be
150-
// the number of pairs in the supplied tuple, then the resulting tuple will
151-
// contain ceil(N/2) pairs of tuples.
152-
template <typename T> struct MergePairs {
153-
using type = std::tuple<>;
154-
};
155-
template <typename... LTs, typename... RTs, typename... Rest>
156-
struct MergePairs<
157-
std::tuple<std::pair<std::tuple<LTs...>, std::tuple<RTs...>>, Rest...>> {
158-
using merged = typename Merge<std::tuple<LTs...>, std::tuple<RTs...>>::type;
159-
using type = std::tuple<std::pair<merged, std::tuple<>>>;
160-
};
161-
template <typename... LLTs, typename... LRTs, typename... RLTs,
162-
typename... RRTs, typename... Rest>
163-
struct MergePairs<
164-
std::tuple<std::pair<std::tuple<LLTs...>, std::tuple<LRTs...>>,
165-
std::pair<std::tuple<RLTs...>, std::tuple<RRTs...>>, Rest...>> {
166-
using lmerged =
167-
typename Merge<std::tuple<LLTs...>, std::tuple<LRTs...>>::type;
168-
using rmerged =
169-
typename Merge<std::tuple<RLTs...>, std::tuple<RRTs...>>::type;
170-
using type = typename PrependTuple<
171-
std::pair<lmerged, rmerged>,
172-
typename MergePairs<std::tuple<Rest...>>::type>::type;
173-
};
174-
175-
// Recursively merges all pairs of tuples until only a single pair of tuples
176-
// is left, where the right element of the pair is an empty tuple.
177-
template <typename T> struct MergeAll {};
178-
template <typename... Ts> struct MergeAll<std::tuple<Ts...>> {
179-
using type = std::tuple<Ts...>;
180-
};
181-
template <typename... Ts>
182-
struct MergeAll<std::tuple<std::pair<std::tuple<Ts...>, std::tuple<>>>> {
183-
using type = std::tuple<Ts...>;
184-
};
185-
template <typename T, typename... Ts> struct MergeAll<std::tuple<T, Ts...>> {
186-
using reduced = typename MergePairs<std::tuple<T, Ts...>>::type;
187-
using type = typename MergeAll<reduced>::type;
188-
};
189-
190-
// Performs merge-sort on types with PropertyID.
191116
template <typename... Ts> struct Sorted {
192117
static_assert(detail::AllPropertyValues<std::tuple<Ts...>>::value,
193118
"Unrecognized property in property list.");
194-
using split = typename CreateTuplePairs<Ts...>::type;
195-
using type = typename MergeAll<split>::type;
119+
using properties = sycl::detail::boost::mp11::mp_list<Ts...>;
120+
using sortedProperties =
121+
sycl::detail::boost::mp11::mp_sort_q<properties, SortByPropertyId>;
122+
using type =
123+
sycl::detail::boost::mp11::mp_rename<sortedProperties, std::tuple>;
196124
};
197125

198126
// Checks if the types in a tuple are sorted w.r.t. their PropertyID.

0 commit comments

Comments
 (0)