29#include "vtkCommonCoreModule.h"
37VTK_ABI_NAMESPACE_BEGIN
39template <
typename TBatchData>
51template <
typename TBatchData>
56 using vector = std::vector<vtkTBatch>;
57 using size_type =
typename vector::size_type;
58 using reference =
typename vector::reference;
59 using const_reference =
typename vector::const_reference;
60 using iterator =
typename vector::iterator;
61 using const_iterator =
typename vector::const_iterator;
75 this->BatchSize = batchSize;
77 const auto batchSizeSigned =
static_cast<vtkIdType>(batchSize);
78 const auto numberOfBatches = ((numberOfElements - 1) / batchSizeSigned) + 1;
79 this->Batches.resize(
static_cast<size_t>(numberOfBatches));
80 const auto lastBatchId = numberOfBatches - 1;
83 vtkIdType endIdValues[2] = { -1, numberOfElements };
84 for (
vtkIdType batchId = beginBatchId; batchId < endBatchId; ++batchId)
86 auto& batch = this->Batches[batchId];
87 batch.BeginId = batchId * batchSizeSigned;
88 endIdValues[0] = (batchId + 1) * batchSizeSigned;
89 batch.EndId = endIdValues[batchId == lastBatchId];
100 if (numberOfBatches == 0)
106 const vtkIdType lastThreadId = numberOfThreads - 1;
107 const vtkIdType numberOfBatchesPerThread = numberOfBatches / numberOfThreads;
109 std::vector<vtkIdType> tlInterEndBatchId;
110 tlInterEndBatchId.resize(
static_cast<size_t>(numberOfThreads));
114 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
116 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
118 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
119 auto beginBatchIter = this->Batches.begin() + beginBatchId;
120 auto endBatchIter = this->Batches.begin() + endBatchId;
121 auto newEndBatchIter = std::remove_if(beginBatchIter, endBatchIter, shouldRemoveBatch);
122 tlInterEndBatchId[threadId] = beginBatchId + std::distance(beginBatchIter, newEndBatchIter);
126 std::vector<vtkIdType> tlNewEndBatchId;
127 tlNewEndBatchId.resize(
static_cast<size_t>(numberOfThreads));
128 tlNewEndBatchId[0] = tlInterEndBatchId[0];
129 for (
vtkIdType threadId = 1; threadId < numberOfThreads; ++threadId)
131 const vtkIdType beginOldBatchId = threadId * numberOfBatchesPerThread;
132 const auto& prevNewEndBatchId = tlNewEndBatchId[threadId - 1];
133 const vtkIdType distance = tlInterEndBatchId[threadId] - beginOldBatchId;
134 tlNewEndBatchId[threadId] = prevNewEndBatchId + distance;
135 std::move_backward(this->Batches.begin() + beginOldBatchId,
136 this->Batches.begin() + tlInterEndBatchId[threadId],
137 this->Batches.begin() + tlNewEndBatchId[threadId]);
139 this->Batches.erase(this->Batches.begin() + tlNewEndBatchId[lastThreadId], this->Batches.end());
156 if (numberOfBatches == 0)
162 const vtkIdType lastThreadId = numberOfThreads - 1;
163 const vtkIdType numberOfBatchesPerThread = numberOfBatches / numberOfThreads;
166 std::vector<TBatchData> tlSums;
167 tlSums.resize(
static_cast<size_t>(numberOfThreads));
170 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
172 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
174 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
176 auto& threadSum = tlSums[threadId];
177 for (
vtkIdType batchId = beginBatchId; batchId < endBatchId; ++batchId)
179 threadSum += this->Batches[batchId].Data;
185 TBatchData globalSum;
186 for (
const auto& threadSum : tlSums)
188 globalSum += threadSum;
192 std::vector<TBatchData> tlOffsets;
193 tlOffsets.resize(
static_cast<size_t>(numberOfThreads));
194 for (
vtkIdType threadId = 1; threadId < numberOfThreads; ++threadId)
196 tlOffsets[threadId] = tlOffsets[threadId - 1] + tlSums[threadId - 1];
201 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
203 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
205 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
208 auto lastBatchData = this->Batches[beginBatchId].Data;
210 this->Batches[beginBatchId].Data = tlOffsets[threadId];
211 for (
vtkIdType batchId = beginBatchId + 1; batchId < endBatchId; ++batchId)
214 const auto currentBatchData = this->Batches[batchId].Data;
216 this->Batches[batchId].Data = this->Batches[batchId - 1].Data + lastBatchData;
218 lastBatchData = std::move(currentBatchData);
240 reference
operator[](size_type pos)
noexcept {
return this->Batches[pos]; }
241 const_reference
operator[](size_type pos)
const noexcept {
return this->Batches[pos]; }
242 iterator
begin() noexcept {
return this->Batches.begin(); }
243 const_iterator
begin() const noexcept {
return this->Batches.begin(); }
244 const_iterator
cbegin() const noexcept {
return this->Batches.cbegin(); }
245 iterator
end() noexcept {
return this->Batches.end(); }
246 const_iterator
end() const noexcept {
return this->Batches.end(); }
247 const_iterator
cend() const noexcept {
return this->Batches.cend(); }
252 unsigned int BatchSize;
const_reference operator[](size_type pos) const noexcept
The following methods expose the underlying vector.
vtkIdType GetNumberOfBatches() const
Get the number of batches.
const_iterator begin() const noexcept
The following methods expose the underlying vector.
unsigned int GetBatchSize() const
Get the batch size.
iterator begin() noexcept
The following methods expose the underlying vector.
void TrimBatches(const std::function< bool(const vtkTBatch &)> shouldRemoveBatch)
Remove batches that should be skipped.
iterator end() noexcept
The following methods expose the underlying vector.
const_iterator end() const noexcept
The following methods expose the underlying vector.
TBatchData BuildOffsetsAndGetGlobalSum()
Build offsets in place and returns the Global sum for a vtkBatch with Compact Batch Data.
const_iterator cbegin() const noexcept
The following methods expose the underlying vector.
const_iterator cend() const noexcept
The following methods expose the underlying vector.
void Initialize(vtkIdType numberOfElements, unsigned int batchSize=1000)
Initialize the batches.
reference operator[](size_type pos) noexcept
The following methods expose the underlying vector.
vtkBatch is a simple structure that holds a begin and end id.