DPC++ Runtime
Runtime libraries for oneAPI DPC++
group_sort.hpp
Go to the documentation of this file.
1 //==--------- group_sort.hpp --- SYCL extension group sorting algorithm-----==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
11 #if (!defined(_HAS_STD_BYTE) || _HAS_STD_BYTE != 0)
12 
13 #include "group_helpers_sorters.hpp" // for default_sorter, group_with_sc...
14 
15 #include <sycl/detail/pi.h> // for PI_ERROR_INVALID_DEVICE
16 #include <sycl/detail/type_traits.hpp> // for is_generic_group
17 #include <sycl/exception.hpp> // for sycl_category, exception
18 
19 #include <stddef.h> // for size_t
20 #include <system_error> // for error_code
21 #include <type_traits> // for enable_if_t, decay_t, false_type
22 #include <utility> // for declval
23 
24 namespace sycl {
25 inline namespace _V1 {
26 namespace ext::oneapi::experimental {
27 namespace detail {
28 
29 // ---- traits
30 template <typename T, typename = void> struct has_difference_type {};
31 
32 template <typename T>
33 struct has_difference_type<T, std::void_t<typename T::difference_type>>
34  : std::true_type {};
35 
36 template <typename T> struct has_difference_type<T *> : std::true_type {};
37 
38 template <typename Sorter, typename Group, typename Val, typename = void>
40  template <typename G>
42  typename std::is_same<Val, decltype(std::declval<Sorter>()(
43  std::declval<G>(), std::declval<Val>()))>;
44 
45  template <typename G = Group>
46  static decltype(std::integral_constant<bool,
48  sycl::is_group_v<G>>{})
49  test(int);
50 
51  template <typename = Group> static std::false_type test(...);
52 };
53 
54 template <typename Sorter, typename Group,
55  typename Ptr> // multi_ptr has difference_type and don't have other
56  // iterator's fields
57 struct is_sorter_impl<Sorter, Group, Ptr,
58  std::void_t<typename has_difference_type<Ptr>::type>> {
59  template <typename G = Group>
60  static decltype(std::declval<Sorter>()(std::declval<G>(), std::declval<Ptr>(),
61  std::declval<Ptr>()),
62  sycl::detail::is_generic_group<G>{})
63  test(int);
64 
65  template <typename = Group> static std::false_type test(...);
66 };
67 
68 template <typename Sorter, typename Group, typename ValOrPtr>
69 struct is_sorter : decltype(is_sorter_impl<Sorter, Group, ValOrPtr>::test(0)) {
70 };
71 } // namespace detail
72 
73 // ---- sort_over_group
74 template <typename Group, typename T, typename Sorter>
75 std::enable_if_t<detail::is_sorter<Sorter, Group, T>::value, T>
76 sort_over_group(Group group, T value, Sorter sorter) {
77 #ifdef __SYCL_DEVICE_ONLY__
78  return sorter(group, value);
79 #else
80  (void)group;
81  (void)value;
82  (void)sorter;
83  throw sycl::exception(
84  std::error_code(PI_ERROR_INVALID_DEVICE, sycl::sycl_category()),
85  "Group algorithms are not supported on host device.");
86 #endif
87 }
88 
89 template <typename Group, typename T, typename Compare, size_t Extent>
90 std::enable_if_t<!detail::is_sorter<Compare, Group, T>::value, T>
92  T value, Compare comp) {
93  return sort_over_group(
94  exec.get_group(), value,
96 }
97 
98 template <typename Group, typename T, size_t Extent>
99 std::enable_if_t<sycl::is_group_v<std::decay_t<Group>>, T>
101  T value) {
102  return sort_over_group(exec.get_group(), value,
104 }
105 
106 // ---- joint_sort
107 template <typename Group, typename Iter, typename Sorter>
108 std::enable_if_t<detail::is_sorter<Sorter, Group, Iter>::value, void>
109 joint_sort(Group group, Iter first, Iter last, Sorter sorter) {
110 #ifdef __SYCL_DEVICE_ONLY__
111  sorter(group, first, last);
112 #else
113  (void)group;
114  (void)first;
115  (void)last;
116  (void)sorter;
117  throw sycl::exception(
118  std::error_code(PI_ERROR_INVALID_DEVICE, sycl::sycl_category()),
119  "Group algorithms are not supported on host device.");
120 #endif
121 }
122 
123 template <typename Group, typename Iter, typename Compare, size_t Extent>
124 std::enable_if_t<!detail::is_sorter<Compare, Group, Iter>::value, void>
126  Iter last, Compare comp) {
127  joint_sort(exec.get_group(), first, last,
129 }
130 
131 template <typename Group, typename Iter, size_t Extent>
132 std::enable_if_t<sycl::is_group_v<std::decay_t<Group>>, void>
134  Iter last) {
135  joint_sort(exec.get_group(), first, last,
137 }
138 
139 } // namespace ext::oneapi::experimental
140 } // namespace _V1
141 } // namespace sycl
142 #endif
std::enable_if_t< detail::is_sorter< Sorter, Group, T >::value, T > sort_over_group(Group group, T value, Sorter sorter)
Definition: group_sort.hpp:76
std::enable_if_t< detail::is_sorter< Sorter, Group, Iter >::value, void > joint_sort(Group group, Iter first, Iter last, Sorter sorter)
Definition: group_sort.hpp:109
const std::error_category & sycl_category() noexcept
Definition: exception.cpp:82
Definition: access.hpp:18
error_code
Definition: defs.hpp:59
static decltype(std::declval< Sorter >()(std::declval< G >(), std::declval< Ptr >(), std::declval< Ptr >()), sycl::detail::is_generic_group< G >{}) test(int)
static decltype(std::integral_constant< bool, is_expected_return_type< G >::value &&sycl::is_group_v< G >>{}) test(int)
Definition: group_sort.hpp:49
typename std::is_same< Val, decltype(std::declval< Sorter >()(std::declval< G >(), std::declval< Val >()))> is_expected_return_type
Definition: group_sort.hpp:43