VTK  9.7.20261031
vtkKeys.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
56
57#ifndef vtkKeys_h
58#define vtkKeys_h
59
60#include "vtkABINamespace.h"
61#include "vtkKeysTraits.h" // For the checks of the concepts
62#include "vtkType.h" // For vtkIdType
63
64#include <cstdint>
65#include <memory>
66#include <type_traits>
67
68//------------------------------------------------------------------------------
69// Concepts, checked at compile time, see vtkKeysTraits.h.
70//
71// Input: records that are the elements (1-1).
72// RecordIdType GetNumberOfRecords() const;
73// KeyType GetKey(RecordIdType record) const; // called concurrently
74// // Optional, otherwise the type of GetKey() and RecordIdType.
75// using KeyType = ...;
76// using ElementIdType = ...;
77//
78// InputMapper: records mapped to several elements (1-M), e.g., cells to their faces.
79// using KeyType = ...;
80// using ElementIdType = ...; // must hold the number of elements
81// RecordIdType GetNumberOfRecords() const;
82// // The number of elements of record beginRecord + i, to counts[i].
83// void CountElements(RecordIdType beginRecord, RecordIdType endRecord,
84// ElementIdType* counts) const;
85// // The keys of the elements of every record, to keys[offsets[record]], ..., in order.
86// void WriteKeys(RecordIdType beginRecord, RecordIdType endRecord,
87// const ElementIdType* offsets, KeyType* keys) const;
88// The methods are called concurrently on disjoint ranges of records, so that they can set up
89// their scratch data once per range.
90//
91// Output: the scattered elements, in one array or in several (a structure of arrays).
92// void SetNumberOfElements(ElementIdType numberOfElements); // 0 first, to release
93// // Called concurrently, at distinct positions, with the record of an Input, or the record
94// // and the index of the element in its record of an InputMapper, from which the Output reads
95// // what it needs, as Viskores's ExternalFaces worklet does.
96// void SetElement(ElementIdType position, RecordIdType record);
97// void SetElement(ElementIdType position, RecordIdType record, ElementIdType index);
98// // For Compact() only, as vtkDataSetAttributes::CopyData().
99// void CopyData(const Output& source, ElementIdType destinationStart, ElementIdType count,
100// ElementIdType sourceStart);
101//
102// KeyType: an integer type for ScatterDense(); for ScatterSparse(), any type that is default
103// constructible, copy assignable and ordered by operator<, e.g., std::pair<vtkIdType, vtkIdType>.
104//
105// Element: an element of an array, copy assignable, with
106// KeyType GetKey() const; // equal elements have the same key
107// and, for SortUnique and SortGroup, operator<, operator== and operator!=. The ElementIdType of
108// an array is the type of its number of elements.
109//
110// Keys: the result of ScatterDense() or ScatterSparse(), a DenseKeys or a SparseKeys, or their
111// reductions, which derive from KeysBase, all that the operations use.
112//
113// Functors of ForEachKeyRange(), Reduce() and Group(): callables on a range of key ids of the
114// Output, called concurrently on disjoint ranges, see ForEachKeyRange():
115// // Reduce functor: keep the survivors of key id k at its front, their number to counts[k].
116// void operator()(Output& output, KeyIdType beginKeyId, KeyIdType endKeyId,
117// const ElementIdType* offsets, ElementIdType* counts);
118// // Group functor: make the equal elements of every key contiguous, and set groupStarts[i] to 1
119// // for every element i that differs from the previous one.
120// void operator()(Output& output, KeyIdType beginKeyId, KeyIdType endKeyId,
121// const ElementIdType* offsets, uint8_t* groupStarts);
122// As vtkSMPTools functors, they can have an Initialize() and a Reduce(), to keep their scratch
123// data or their results per thread.
124namespace vtk
125{
126namespace keys
127{
128namespace detail
129{
130VTK_ABI_NAMESPACE_BEGIN
131
132// The writers of the results, defined in vtkKeys.txx.
133struct DenseScatterer;
134struct SparseScatterer;
135struct Reducer;
136struct Grouper;
137
138VTK_ABI_NAMESPACE_END
139} // namespace detail
140
141VTK_ABI_NAMESPACE_BEGIN
142
148template <typename TKey, typename TElementId, typename TKeyId>
150{
151public:
152 using KeyType = TKey;
153 using ElementIdType = TElementId;
154 using KeyIdType = TKeyId;
155
156 static_assert(std::is_integral_v<ElementIdType>, "ElementIdType must be an integer type");
157
160 KeyIdType GetNumberOfKeys() const { return this->NumberOfKeys; }
161
165 ElementIdType GetOffset(KeyIdType keyId) const { return this->Offsets[keyId]; }
166
170 const ElementIdType* GetOffsets() const { return this->Offsets.get(); }
171
173 {
174 return this->Offsets[keyId + 1] - this->Offsets[keyId];
175 }
176
177protected:
179 {
180 this->NumberOfRecords = this->NumberOfElements = 0;
181 this->NumberOfKeys = 0;
182 this->Offsets.reset();
183 }
184
185 // The records and the keys of other keys, e.g., of a reduction, without their offsets.
186 void CopyBaseFrom(const KeysBase& other)
187 {
188 this->NumberOfRecords = other.NumberOfRecords;
189 this->NumberOfKeys = other.NumberOfKeys;
190 }
191
195 std::unique_ptr<ElementIdType[]> Offsets; // NumberOfKeys + 1
196};
197
203template <typename TKey = vtkIdType, typename TElementId = vtkIdType>
204class DenseKeys : public KeysBase<TKey, TElementId, TKey>
205{
206public:
207 using KeyType = TKey;
208 using KeyIdType = TKey;
209
210 static_assert(std::is_integral_v<KeyType> && !std::is_same_v<KeyType, bool>,
211 "The KeyType of DenseKeys must be an integer type: a key id is its difference with the "
212 "minimum key");
213
214 KeyType GetMinKey() const { return this->MinKey; }
215 KeyType GetMaxKey() const { return this->MaxKey; }
216
220 KeyType GetKey(KeyIdType keyId) const { return this->MinKey + keyId; }
221 KeyIdType GetKeyId(KeyType key) const { return DenseKeys::GetKeyId(key, this->MinKey); }
222
226 void Reset()
227 {
228 this->ResetBase();
229 this->MinKey = this->MaxKey = 0;
230 }
231
232private:
233 friend struct detail::DenseScatterer;
234 friend struct detail::Reducer;
235 friend struct detail::Grouper;
236
237 // The key id of a key given the minimum key, kept in a register by the loops of ScatterDense().
238 static KeyIdType GetKeyId(KeyType key, KeyType minKey) { return key - minKey; }
239
240 // The keys of other keys of this type, e.g., of a reduction.
241 void CopyKeysFrom(const DenseKeys& other)
242 {
243 this->CopyBaseFrom(other);
244 this->MinKey = other.MinKey;
245 this->MaxKey = other.MaxKey;
246 }
247
248 KeyType MinKey = 0;
249 KeyType MaxKey = 0;
250};
251
258template <typename TKey = vtkIdType, typename TElementId = vtkIdType>
259class SparseKeys : public KeysBase<TKey, TElementId, TElementId>
260{
261public:
262 using KeyType = TKey;
263 using KeyIdType = TElementId;
264
265 static_assert(std::is_signed_v<TElementId>, "ElementIdType must be signed, see FindKeyId()");
266
270 KeyType GetKey(KeyIdType keyId) const { return this->Keys[keyId]; }
272
276 void Reset()
277 {
278 this->ResetBase();
279 this->Keys.reset();
280 }
281
282private:
283 friend struct detail::SparseScatterer;
284 friend struct detail::Reducer;
285 friend struct detail::Grouper;
286
287 // The keys of other keys of this type, e.g., of a reduction, which share the distinct keys.
288 void CopyKeysFrom(const SparseKeys& other)
289 {
290 this->CopyBaseFrom(other);
291 this->Keys = other.Keys;
292 }
293
294 std::shared_ptr<KeyType[]> Keys; // NumberOfKeys
295};
296
300template <typename Input>
302template <typename Input>
304template <typename Element, typename ElementIdType>
306template <typename Element, typename ElementIdType>
308
309//------------------------------------------------------------------------------
310// ScatterDense() and ScatterSparse(): the elements are moved to the Output in key order.
311
316template <typename InputMapper>
317vtkIdType CountElements(const InputMapper& mapper);
318
326template <typename Input, typename Output>
327DenseKeysOf<Input> ScatterDense(const Input& input, Output& output);
328template <typename Input, typename Output>
330 detail::KeyTypeOfT<Input> maxKey, Output& output);
331
337template <typename Element, typename ElementIdType>
339 const Element* elements, ElementIdType numberOfElements, Element* scattered);
340template <typename Element, typename ElementIdType>
342 ElementIdType numberOfElements, detail::ElementKeyOf<Element> minKey,
343 detail::ElementKeyOf<Element> maxKey, Element* scattered);
344
352template <typename Input, typename Output>
353SparseKeysOf<Input> ScatterSparse(const Input& input, Output& output);
354template <typename Element, typename ElementIdType>
356 const Element* elements, ElementIdType numberOfElements, Element* scattered);
357
358//------------------------------------------------------------------------------
359// ForEachKeyRange(), Reduce() and Group(): the elements of every key are processed.
360
367template <typename TKeys, typename Output, typename Functor, typename... Args>
368void ForEachKeyRange(const TKeys& keys, Output&& output, Functor& functor, Args... args);
369
370//------------------------------------------------------------------------------
371// Reduce(): the surviving elements of every key, e.g., the faces used once.
372
380template <typename TKeys>
381class ReducedKeys : public TKeys
382{
383};
384
391template <typename TKeys, typename Output, typename Functor>
392ReducedKeys<TKeys> Reduce(const TKeys& keys, Output&& output, Functor&& functor);
393
400template <typename TKeys, typename Output, typename = std::enable_if_t<!std::is_pointer_v<Output>>>
401typename TKeys::ElementIdType Compact(
402 const TKeys& keys, const ReducedKeys<TKeys>& reduced, const Output& input, Output& output);
403template <typename TKeys, typename Element>
404typename TKeys::ElementIdType Compact(
405 const TKeys& keys, const ReducedKeys<TKeys>& reduced, const Element* input, Element* output);
406
412{
413 template <typename Element, typename KeyIdType, typename ElementIdType>
414 void operator()(Element* elements, KeyIdType beginKeyId, KeyIdType endKeyId,
415 const ElementIdType* offsets, ElementIdType* counts) const;
416};
417
418//------------------------------------------------------------------------------
419// Group(): the groups of equal elements of every key, e.g., the faces shared by cells.
420
425template <typename TKeys>
427{
428public:
429 using ElementIdType = typename TKeys::ElementIdType;
430
431 ElementIdType GetNumberOfGroups() const { return this->NumberOfGroups; }
432
436 ElementIdType GetGroupOffset(ElementIdType group) const { return this->GroupOffsets[group]; }
437
441 const ElementIdType* GetGroupOffsets() const { return this->GroupOffsets.get(); }
442
444 {
445 return this->GroupOffsets[group + 1] - this->GroupOffsets[group];
446 }
447
451 void Reset()
452 {
453 this->NumberOfGroups = 0;
454 this->GroupOffsets.reset();
455 }
456
457private:
458 friend struct detail::Grouper;
459
460 ElementIdType NumberOfGroups = 0;
461 std::unique_ptr<ElementIdType[]> GroupOffsets; // NumberOfGroups + 1
462};
463
475template <typename TKeys>
481
490template <typename TKeys, typename Output, typename Functor>
491Grouping<TKeys> Group(const TKeys& keys, Output&& output, Functor&& functor);
492
499template <typename TKeys, typename Output, typename = std::enable_if_t<!std::is_pointer_v<Output>>>
500typename TKeys::ElementIdType Compact(
501 const GroupedElements<TKeys>& groups, const Output& input, Output& output);
502template <typename TKeys, typename Element>
503typename TKeys::ElementIdType Compact(
504 const GroupedElements<TKeys>& groups, const Element* input, Element* output);
505
511{
512 template <typename Element, typename KeyIdType, typename ElementIdType>
513 void operator()(Element* elements, KeyIdType beginKeyId, KeyIdType endKeyId,
514 const ElementIdType* offsets, uint8_t* groupStarts) const;
515};
516
517VTK_ABI_NAMESPACE_END
518} // namespace keys
519} // namespace vtk
520
521#include "vtkKeys.txx"
522
523#endif
524// VTK-HeaderTest-Exclude: vtkKeys.h
The dense keys of the elements, returned by ScatterDense(): every key of the key range [GetMinKey(),...
Definition vtkKeys.h:205
KeyType GetMinKey() const
Definition vtkKeys.h:214
KeyType GetKey(KeyIdType keyId) const
The key of a key id, and the key id of a key of [GetMinKey(), GetMaxKey()].
Definition vtkKeys.h:220
void Reset()
Release the memory.
Definition vtkKeys.h:226
KeyType GetMaxKey() const
Definition vtkKeys.h:215
KeyIdType GetKeyId(KeyType key) const
Definition vtkKeys.h:221
The groups of equal elements of Group(), ordered by key: the elements of group g are at [GetGroupOffs...
Definition vtkKeys.h:427
ElementIdType GetGroupOffset(ElementIdType group) const
The first element of a group, 0 <= group <= GetNumberOfGroups().
Definition vtkKeys.h:436
const ElementIdType * GetGroupOffsets() const
The first element of every group, GetNumberOfGroups() + 1 values, nullptr without grouping.
Definition vtkKeys.h:441
ElementIdType GetNumberOfGroups() const
Definition vtkKeys.h:431
typename TKeys::ElementIdType ElementIdType
Definition vtkKeys.h:429
ElementIdType GetGroupSize(ElementIdType group) const
Definition vtkKeys.h:443
void Reset()
Release the memory.
Definition vtkKeys.h:451
What DenseKeys and SparseKeys share, and all that Reduce(), Group(), Compact() and ForEachKeyRange() ...
Definition vtkKeys.h:150
ElementIdType GetOffset(KeyIdType keyId) const
The first element of a key id, 0 <= keyId <= GetNumberOfKeys().
Definition vtkKeys.h:165
KeyIdType NumberOfKeys
Definition vtkKeys.h:194
vtkIdType GetNumberOfRecords() const
Definition vtkKeys.h:158
vtkIdType NumberOfRecords
Definition vtkKeys.h:192
TElementId ElementIdType
Definition vtkKeys.h:153
KeyIdType GetNumberOfKeys() const
Definition vtkKeys.h:160
void CopyBaseFrom(const KeysBase &other)
Definition vtkKeys.h:186
const ElementIdType * GetOffsets() const
The first element of every key id, GetNumberOfKeys() + 1 values, nullptr without element.
Definition vtkKeys.h:170
ElementIdType GetNumberOfElementsOfKey(KeyIdType keyId) const
Definition vtkKeys.h:172
vtkIdType GetNumberOfElements() const
Definition vtkKeys.h:159
vtkIdType NumberOfElements
Definition vtkKeys.h:193
std::unique_ptr< ElementIdType[]> Offsets
Definition vtkKeys.h:195
The keys of the surviving elements of Reduce(), or of the groups of Group(): the keys of the scattere...
Definition vtkKeys.h:382
The sparse keys of the elements, returned by ScatterSparse(): the distinct keys, in increasing order ...
Definition vtkKeys.h:260
void Reset()
Release the memory, the distinct keys once no reduction shares them.
Definition vtkKeys.h:276
KeyIdType FindKeyId(KeyType key) const
TElementId KeyIdType
Definition vtkKeys.h:263
KeyType GetKey(KeyIdType keyId) const
The key of a key id, and the key id of a key, -1 if absent, by a binary search.
Definition vtkKeys.h:270
typename ElementIdTypeOf< In >::type ElementIdTypeOfT
std::decay_t< decltype(std::declval< const T & >().GetKey())> ElementKeyOf
typename KeyTypeOf< In >::type KeyTypeOfT
SparseKeys< detail::ElementKeyOf< Element >, ElementIdType > SparseArrayKeys
Definition vtkKeys.h:307
SparseKeys< detail::KeyTypeOfT< Input >, detail::ElementIdTypeOfT< Input > > SparseKeysOf
Definition vtkKeys.h:303
vtkIdType CountElements(const InputMapper &mapper)
The number of elements of an InputMapper, without storing them, e.g., to choose its ElementIdType.
DenseKeysOf< Input > ScatterDense(const Input &input, Output &output)
Scatter the elements of an Input or an InputMapper to an Output by a counting sort over the key range...
Grouping< TKeys > Group(const TKeys &keys, Output &&output, Functor &&functor)
Group the equal elements of every key of the Output with a group functor called as functor(output,...
SparseKeysOf< Input > ScatterSparse(const Input &input, Output &output)
Scatter the elements of an Input or an InputMapper, or an array of elements, to an Output by a parall...
TKeys::ElementIdType Compact(const TKeys &keys, const ReducedKeys< TKeys > &reduced, const Output &input, Output &output)
Copy the survivors of the reduced Output input contiguously into output, another Output that implemen...
ReducedKeys< TKeys > Reduce(const TKeys &keys, Output &&output, Functor &&functor)
Keep the surviving elements of every key of the Output at its front with a reduce functor called as f...
DenseKeys< detail::KeyTypeOfT< Input >, detail::ElementIdTypeOfT< Input > > DenseKeysOf
The keys of the scatters of an input, with its KeyType and ElementIdType, and of an array.
Definition vtkKeys.h:301
DenseKeys< detail::ElementKeyOf< Element >, ElementIdType > DenseArrayKeys
Definition vtkKeys.h:305
void ForEachKeyRange(const TKeys &keys, Output &&output, Functor &functor, Args... args)
Call functor(output, beginKeyId, endKeyId, offsets, args...) on disjoint ranges of key ids,...
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
The result of Group(): the groups, and the keys of the groups, i.e., the groups of key id k are [Keys...
Definition vtkKeys.h:477
GroupedElements< TKeys > Groups
Definition vtkKeys.h:478
ReducedKeys< TKeys > Keys
Definition vtkKeys.h:479
The group functor of an array of elements, with operator< and operator!=: it sorts the elements of ev...
Definition vtkKeys.h:511
void operator()(Element *elements, KeyIdType beginKeyId, KeyIdType endKeyId, const ElementIdType *offsets, uint8_t *groupStarts) const
The reduce functor of an array of elements that keeps one element of every set of equal ones,...
Definition vtkKeys.h:412
void operator()(Element *elements, KeyIdType beginKeyId, KeyIdType endKeyId, const ElementIdType *offsets, ElementIdType *counts) const
the traits and checks of the concepts of vtk::keys, see vtkKeys.h
int vtkIdType
Definition vtkType.h:363