VTK-m  2.0
ParallelRadixSortInterface.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 
11 #ifndef vtk_m_cont_internal_ParallelRadixSortInterface_h
12 #define vtk_m_cont_internal_ParallelRadixSortInterface_h
13 
14 #include <vtkm/BinaryPredicates.h>
15 #include <vtkm/cont/ArrayHandle.h>
16 
17 #include <functional>
18 #include <type_traits>
19 
20 namespace vtkm
21 {
22 namespace cont
23 {
24 namespace internal
25 {
26 namespace radix
27 {
28 
29 const size_t MIN_BYTES_FOR_PARALLEL = 400000;
30 const size_t BYTES_FOR_MAX_PARALLELISM = 4000000;
31 
32 struct RadixSortTag
33 {
34 };
35 
36 struct PSortTag
37 {
38 };
39 
40 // Detect supported functors for radix sort:
41 template <typename T>
42 struct is_valid_compare_type : std::integral_constant<bool, false>
43 {
44 };
45 template <typename T>
46 struct is_valid_compare_type<std::less<T>> : std::integral_constant<bool, true>
47 {
48 };
49 template <typename T>
50 struct is_valid_compare_type<std::greater<T>> : std::integral_constant<bool, true>
51 {
52 };
53 template <>
54 struct is_valid_compare_type<vtkm::SortLess> : std::integral_constant<bool, true>
55 {
56 };
57 template <>
58 struct is_valid_compare_type<vtkm::SortGreater> : std::integral_constant<bool, true>
59 {
60 };
61 
62 // Convert vtkm::Sort[Less|Greater] to the std:: equivalents:
63 template <typename BComp, typename T>
64 BComp&& get_std_compare(BComp&& b, T&&)
65 {
66  return std::forward<BComp>(b);
67 }
68 template <typename T>
69 std::less<T> get_std_compare(vtkm::SortLess, T&&)
70 {
71  return std::less<T>{};
72 }
73 template <typename T>
74 std::greater<T> get_std_compare(vtkm::SortGreater, T&&)
75 {
76  return std::greater<T>{};
77 }
78 
79 // Determine if radix sort can be used for a given ValueType, StorageType, and
80 // comparison functor.
81 template <typename T, typename StorageTag, typename BinaryCompare>
82 struct sort_tag_type
83 {
84  using type = PSortTag;
85 };
86 template <typename T, typename BinaryCompare>
87 struct sort_tag_type<T, vtkm::cont::StorageTagBasic, BinaryCompare>
88 {
89  using PrimT = std::is_arithmetic<T>;
90  using LongDT = std::is_same<T, long double>;
91  using BComp = is_valid_compare_type<BinaryCompare>;
92  using type = typename std::
93  conditional<PrimT::value && BComp::value && !LongDT::value, RadixSortTag, PSortTag>::type;
94 };
95 
96 template <typename KeyType,
97  typename ValueType,
98  typename KeyStorageTagType,
99  typename ValueStorageTagType,
100  class BinaryCompare>
101 struct sortbykey_tag_type
102 {
103  using type = PSortTag;
104 };
105 template <typename KeyType, typename ValueType, class BinaryCompare>
106 struct sortbykey_tag_type<KeyType,
107  ValueType,
108  vtkm::cont::StorageTagBasic,
110  BinaryCompare>
111 {
112  using PrimKey = std::is_arithmetic<KeyType>;
113  using PrimValue = std::is_arithmetic<ValueType>;
114  using LongDKey = std::is_same<KeyType, long double>;
115  using BComp = is_valid_compare_type<BinaryCompare>;
116  using type = typename std::conditional<PrimKey::value && PrimValue::value && BComp::value &&
117  !LongDKey::value,
118  RadixSortTag,
119  PSortTag>::type;
120 };
121 
122 #define VTKM_INTERNAL_RADIX_SORT_DECLARE(key_type) \
123  VTKM_CONT_EXPORT void parallel_radix_sort( \
124  key_type* data, size_t num_elems, const std::greater<key_type>& comp); \
125  VTKM_CONT_EXPORT void parallel_radix_sort( \
126  key_type* data, size_t num_elems, const std::less<key_type>& comp); \
127  VTKM_CONT_EXPORT void parallel_radix_sort_key_values( \
128  key_type* keys, vtkm::Id* vals, size_t num_elems, const std::greater<key_type>& comp); \
129  VTKM_CONT_EXPORT void parallel_radix_sort_key_values( \
130  key_type* keys, vtkm::Id* vals, size_t num_elems, const std::less<key_type>& comp);
131 
132 // Generate radix sort interfaces for key and key value sorts.
133 #define VTKM_DECLARE_RADIX_SORT() \
134  VTKM_INTERNAL_RADIX_SORT_DECLARE(short int) \
135  VTKM_INTERNAL_RADIX_SORT_DECLARE(unsigned short int) \
136  VTKM_INTERNAL_RADIX_SORT_DECLARE(int) \
137  VTKM_INTERNAL_RADIX_SORT_DECLARE(unsigned int) \
138  VTKM_INTERNAL_RADIX_SORT_DECLARE(long int) \
139  VTKM_INTERNAL_RADIX_SORT_DECLARE(unsigned long int) \
140  VTKM_INTERNAL_RADIX_SORT_DECLARE(long long int) \
141  VTKM_INTERNAL_RADIX_SORT_DECLARE(unsigned long long int) \
142  VTKM_INTERNAL_RADIX_SORT_DECLARE(unsigned char) \
143  VTKM_INTERNAL_RADIX_SORT_DECLARE(signed char) \
144  VTKM_INTERNAL_RADIX_SORT_DECLARE(char) \
145  VTKM_INTERNAL_RADIX_SORT_DECLARE(char16_t) \
146  VTKM_INTERNAL_RADIX_SORT_DECLARE(char32_t) \
147  VTKM_INTERNAL_RADIX_SORT_DECLARE(wchar_t) \
148  VTKM_INTERNAL_RADIX_SORT_DECLARE(float) \
149  VTKM_INTERNAL_RADIX_SORT_DECLARE(double)
150 }
151 }
152 }
153 } // end vtkm::cont::internal::radix
154 
155 #endif // vtk_m_cont_internal_ParallelRadixSortInterface_h
ArrayHandle.h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::SortLess
Binary Predicate that takes two arguments argument x, and y and returns True if and only if x is less...
Definition: BinaryPredicates.h:45
vtkm::SortGreater
Binary Predicate that takes two arguments argument x, and y and returns True if and only if x is grea...
Definition: BinaryPredicates.h:58
BinaryPredicates.h
vtkm::cont::StorageTagBasic
A tag for the basic implementation of a Storage object.
Definition: ArrayHandle.h:45