VTK-m  2.0
StableSortIndices.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 #ifndef vtk_m_worklet_SortAndUniqueIndices_h
11 #define vtk_m_worklet_SortAndUniqueIndices_h
12 
13 #include <vtkm/cont/Algorithm.h>
14 #include <vtkm/cont/ArrayHandle.h>
17 
18 namespace vtkm
19 {
20 namespace worklet
21 {
22 
26 {
28 
29  // Allows Sort to be called on an array that indexes into KeyPortal.
30  // If the values compare equal, the indices are compared to stabilize the
31  // result.
32  template <typename KeyPortalType>
34  {
35  using KeyType = typename KeyPortalType::ValueType;
36 
37  const KeyPortalType KeyPortal;
38 
39  VTKM_CONT
40  IndirectSortPredicate(const KeyPortalType& keyPortal)
41  : KeyPortal(keyPortal)
42  {
43  }
44 
45  template <typename IndexType>
46  VTKM_EXEC bool operator()(const IndexType& a, const IndexType& b) const
47  {
48  // If the values compare equal, compare the indices as well so we get
49  // consistent outputs.
50  const KeyType valueA = this->KeyPortal.Get(a);
51  const KeyType valueB = this->KeyPortal.Get(b);
52  if (valueA < valueB)
53  {
54  return true;
55  }
56  else if (valueB < valueA)
57  {
58  return false;
59  }
60  else
61  {
62  return a < b;
63  }
64  }
65  };
66 
67  // Allows you to pass an IndirectSortPredicate to a device algorithm without knowing the device.
68  template <typename KeyArrayType>
70  {
71  const KeyArrayType KeyArray;
72 
73  VTKM_CONT IndirectSortPredicateExecObject(const KeyArrayType& keyArray)
74  : KeyArray(keyArray)
75  {
76  }
77 
78  template <typename Device>
80  Device,
81  vtkm::cont::Token& token) const
82  {
83  auto keyPortal = this->KeyArray.PrepareForInput(Device(), token);
85  }
86  };
87 
88  // Allows Unique to be called on an array that indexes into KeyPortal.
89  template <typename KeyPortalType>
91  {
92  const KeyPortalType KeyPortal;
93 
94  VTKM_CONT
95  IndirectUniquePredicate(const KeyPortalType& keyPortal)
96  : KeyPortal(keyPortal)
97  {
98  }
99 
100  template <typename IndexType>
101  VTKM_EXEC bool operator()(const IndexType& a, const IndexType& b) const
102  {
103  return this->KeyPortal.Get(a) == this->KeyPortal.Get(b);
104  }
105  };
106 
107  // Allows you to pass an IndirectUniquePredicate to a device algorithm without knowing the device.
108  template <typename KeyArrayType>
110  {
111  const KeyArrayType KeyArray;
112 
113  VTKM_CONT IndirectUniquePredicateExecObject(const KeyArrayType& keyArray)
114  : KeyArray(keyArray)
115  {
116  }
117 
118  template <typename Device>
120  Device,
121  vtkm::cont::Token& token) const
122  {
123  auto keyPortal = this->KeyArray.PrepareForInput(Device(), token);
125  }
126  };
127 
139  template <typename KeyType, typename Storage>
142  IndexArrayType& indices)
143  {
144  using KeyArrayType = vtkm::cont::ArrayHandle<KeyType, Storage>;
145  using SortPredicate = IndirectSortPredicateExecObject<KeyArrayType>;
146 
147  VTKM_ASSERT(keys.GetNumberOfValues() == indices.GetNumberOfValues());
148 
149  vtkm::cont::Algorithm::Sort(device, indices, SortPredicate(keys));
150  }
151 
162  template <typename KeyType, typename Storage>
164  IndexArrayType& indices)
165  {
166  StableSortIndices::Sort(vtkm::cont::DeviceAdapterTagAny(), keys, indices);
167  }
168 
173  template <typename KeyType, typename Storage>
176  {
177  // Generate the initial index array
178  IndexArrayType indices;
179  {
181  vtkm::cont::Algorithm::Copy(device, indicesSrc, indices);
182  }
183 
184  StableSortIndices::Sort(device, keys, indices);
185 
186  return indices;
187  }
188 
193  template <typename KeyType, typename Storage>
195  {
196  return StableSortIndices::Sort(vtkm::cont::DeviceAdapterTagAny(), keys);
197  }
198 
203  template <typename KeyType, typename Storage>
206  IndexArrayType& indices)
207  {
208  using KeyArrayType = vtkm::cont::ArrayHandle<KeyType, Storage>;
209  using UniquePredicate = IndirectUniquePredicateExecObject<KeyArrayType>;
210 
211  vtkm::cont::Algorithm::Unique(device, indices, UniquePredicate(keys));
212  }
213 
218  template <typename KeyType, typename Storage>
220  IndexArrayType& indices)
221  {
222  StableSortIndices::Unique(vtkm::cont::DeviceAdapterTagAny(), keys, indices);
223  }
224 };
225 }
226 } // end namespace vtkm::worklet
227 
228 #endif // vtk_m_worklet_SortAndUniqueIndices_h
vtkm::cont::ArrayHandle::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle< vtkm::Id >
ArrayHandle.h
vtkm::worklet::StableSortIndices::IndirectSortPredicateExecObject::KeyArray
const KeyArrayType KeyArray
Definition: StableSortIndices.h:71
VTKM_EXEC
#define VTKM_EXEC
Definition: ExportMacros.h:51
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
vtkm::worklet::StableSortIndices::IndirectUniquePredicateExecObject::KeyArray
const KeyArrayType KeyArray
Definition: StableSortIndices.h:111
vtkm::worklet::StableSortIndices::IndirectUniquePredicateExecObject
Definition: StableSortIndices.h:109
vtkm::worklet::StableSortIndices::IndirectUniquePredicate::KeyPortal
const KeyPortalType KeyPortal
Definition: StableSortIndices.h:92
vtkm::cont::Algorithm::Sort
static VTKM_CONT void Sort(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle< T, Storage > &values)
Definition: Algorithm.h:965
vtkm::cont::Algorithm::Copy
static VTKM_CONT bool Copy(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, vtkm::cont::ArrayHandle< U, COut > &output)
Definition: Algorithm.h:410
vtkm::worklet::StableSortIndices::Sort
static VTKM_CONT IndexArrayType Sort(vtkm::cont::DeviceAdapterId device, const vtkm::cont::ArrayHandle< KeyType, Storage > &keys)
Returns an index array that maps the keys array into a stable sorted ordering.
Definition: StableSortIndices.h:174
vtkm::worklet::StableSortIndices::Unique
static VTKM_CONT void Unique(vtkm::cont::DeviceAdapterId device, const vtkm::cont::ArrayHandle< KeyType, Storage > &keys, IndexArrayType &indices)
Reduces the array returned by Sort so that the mapped keys are unique.
Definition: StableSortIndices.h:204
vtkm::worklet::StableSortIndices::IndirectUniquePredicateExecObject::IndirectUniquePredicateExecObject
VTKM_CONT IndirectUniquePredicateExecObject(const KeyArrayType &keyArray)
Definition: StableSortIndices.h:113
vtkm::worklet::StableSortIndices::IndirectSortPredicate::KeyPortal
const KeyPortalType KeyPortal
Definition: StableSortIndices.h:37
vtkm::worklet::StableSortIndices::Sort
static VTKM_CONT void Sort(const vtkm::cont::ArrayHandle< KeyType, Storage > &keys, IndexArrayType &indices)
Permutes the indices array so that it will map keys into a stable sorted order.
Definition: StableSortIndices.h:163
vtkm::worklet::StableSortIndices::IndirectUniquePredicate::operator()
VTKM_EXEC bool operator()(const IndexType &a, const IndexType &b) const
Definition: StableSortIndices.h:101
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::cont::Algorithm::Unique
static VTKM_CONT void Unique(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle< T, Storage > &values)
Definition: Algorithm.h:1063
vtkm::worklet::StableSortIndices::IndirectSortPredicateExecObject
Definition: StableSortIndices.h:69
Algorithm.h
vtkm::worklet::StableSortIndices::IndirectSortPredicateExecObject::IndirectSortPredicateExecObject
VTKM_CONT IndirectSortPredicateExecObject(const KeyArrayType &keyArray)
Definition: StableSortIndices.h:73
ArrayHandleIndex.h
vtkm::worklet::StableSortIndices::IndirectSortPredicate::operator()
VTKM_EXEC bool operator()(const IndexType &a, const IndexType &b) const
Definition: StableSortIndices.h:46
vtkm::worklet::StableSortIndices::Sort
static VTKM_CONT IndexArrayType Sort(const vtkm::cont::ArrayHandle< KeyType, Storage > &keys)
Returns an index array that maps the keys array into a stable sorted ordering.
Definition: StableSortIndices.h:194
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::worklet::StableSortIndices::IndirectSortPredicate
Definition: StableSortIndices.h:33
vtkm::worklet::StableSortIndices::IndirectSortPredicate::KeyType
typename KeyPortalType::ValueType KeyType
Definition: StableSortIndices.h:35
vtkm::worklet::StableSortIndices::Sort
static VTKM_CONT void Sort(vtkm::cont::DeviceAdapterId device, const vtkm::cont::ArrayHandle< KeyType, Storage > &keys, IndexArrayType &indices)
Permutes the indices array so that it will map keys into a stable sorted order.
Definition: StableSortIndices.h:140
vtkm::cont::ExecutionObjectBase
Base ExecutionObjectBase for execution objects to inherit from so that you can use an arbitrary objec...
Definition: ExecutionObjectBase.h:31
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::worklet::StableSortIndices::Unique
static VTKM_CONT void Unique(const vtkm::cont::ArrayHandle< KeyType, Storage > &keys, IndexArrayType &indices)
Reduces the array returned by Sort so that the mapped keys are unique.
Definition: StableSortIndices.h:219
vtkm::worklet::StableSortIndices::IndirectUniquePredicateExecObject::PrepareForExecution
IndirectUniquePredicate< typename KeyArrayType::ReadPortalType > PrepareForExecution(Device, vtkm::cont::Token &token) const
Definition: StableSortIndices.h:119
vtkm::worklet::StableSortIndices::IndirectUniquePredicate::IndirectUniquePredicate
VTKM_CONT IndirectUniquePredicate(const KeyPortalType &keyPortal)
Definition: StableSortIndices.h:95
vtkm::worklet::StableSortIndices::IndirectSortPredicate::IndirectSortPredicate
VTKM_CONT IndirectSortPredicate(const KeyPortalType &keyPortal)
Definition: StableSortIndices.h:40
vtkm::worklet::StableSortIndices
Produces an ArrayHandle<vtkm::Id> index array that stable-sorts and optionally uniquifies an input ar...
Definition: StableSortIndices.h:25
vtkm::worklet::StableSortIndices::IndirectSortPredicateExecObject::PrepareForExecution
IndirectSortPredicate< typename KeyArrayType::ReadPortalType > PrepareForExecution(Device, vtkm::cont::Token &token) const
Definition: StableSortIndices.h:79
ExecutionObjectBase.h
vtkm::cont::ArrayHandleIndex
An implicit array handle containing the its own indices.
Definition: ArrayHandleIndex.h:54
vtkm::worklet::StableSortIndices::IndirectUniquePredicate
Definition: StableSortIndices.h:90