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;
85 vtkIdType endIdValues[2] = { -1, numberOfElements };
86 for (
vtkIdType batchId = beginBatchId; batchId < endBatchId; ++batchId)
88 auto& batch = this->Batches[batchId];
89 batch.BeginId = batchId * batchSizeSigned;
90 endIdValues[0] = (batchId + 1) * batchSizeSigned;
91 batch.EndId = endIdValues[batchId == lastBatchId];
102 if (numberOfBatches == 0)
108 const vtkIdType lastThreadId = numberOfThreads - 1;
109 const vtkIdType numberOfBatchesPerThread = numberOfBatches / numberOfThreads;
111 std::vector<vtkIdType> tlInterEndBatchId;
112 tlInterEndBatchId.resize(
static_cast<size_t>(numberOfThreads));
118 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
120 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
122 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
123 auto beginBatchIter = this->Batches.begin() + beginBatchId;
124 auto endBatchIter = this->Batches.begin() + endBatchId;
125 auto newEndBatchIter = std::remove_if(beginBatchIter, endBatchIter, shouldRemoveBatch);
126 tlInterEndBatchId[threadId] =
127 beginBatchId + std::distance(beginBatchIter, newEndBatchIter);
131 std::vector<vtkIdType> tlNewEndBatchId;
132 tlNewEndBatchId.resize(
static_cast<size_t>(numberOfThreads));
133 tlNewEndBatchId[0] = tlInterEndBatchId[0];
134 for (
vtkIdType threadId = 1; threadId < numberOfThreads; ++threadId)
136 const vtkIdType beginOldBatchId = threadId * numberOfBatchesPerThread;
137 const auto& prevNewEndBatchId = tlNewEndBatchId[threadId - 1];
138 const vtkIdType distance = tlInterEndBatchId[threadId] - beginOldBatchId;
139 tlNewEndBatchId[threadId] = prevNewEndBatchId + distance;
140 std::move_backward(this->Batches.begin() + beginOldBatchId,
141 this->Batches.begin() + tlInterEndBatchId[threadId],
142 this->Batches.begin() + tlNewEndBatchId[threadId]);
144 this->Batches.erase(this->Batches.begin() + tlNewEndBatchId[lastThreadId], this->Batches.end());
161 if (numberOfBatches == 0)
167 const vtkIdType lastThreadId = numberOfThreads - 1;
168 const vtkIdType numberOfBatchesPerThread = numberOfBatches / numberOfThreads;
171 std::vector<TBatchData> tlSums;
172 tlSums.resize(
static_cast<size_t>(numberOfThreads));
177 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
179 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
181 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
183 auto& threadSum = tlSums[threadId];
184 for (
vtkIdType batchId = beginBatchId; batchId < endBatchId; ++batchId)
186 threadSum += this->Batches[batchId].Data;
192 TBatchData globalSum;
193 for (
const auto& threadSum : tlSums)
195 globalSum += threadSum;
199 std::vector<TBatchData> tlOffsets;
200 tlOffsets.resize(
static_cast<size_t>(numberOfThreads));
201 for (
vtkIdType threadId = 1; threadId < numberOfThreads; ++threadId)
203 tlOffsets[threadId] = tlOffsets[threadId - 1] + tlSums[threadId - 1];
210 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
212 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
214 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
217 auto lastBatchData = this->Batches[beginBatchId].Data;
219 this->Batches[beginBatchId].Data = tlOffsets[threadId];
220 for (
vtkIdType batchId = beginBatchId + 1; batchId < endBatchId; ++batchId)
223 const auto currentBatchData = this->Batches[batchId].Data;
225 this->Batches[batchId].Data = this->Batches[batchId - 1].Data + lastBatchData;
227 lastBatchData = std::move(currentBatchData);
249 reference
operator[](size_type pos)
noexcept {
return this->Batches[pos]; }
250 const_reference
operator[](size_type pos)
const noexcept {
return this->Batches[pos]; }
251 iterator
begin() noexcept {
return this->Batches.begin(); }
252 const_iterator
begin() const noexcept {
return this->Batches.begin(); }
253 const_iterator
cbegin() const noexcept {
return this->Batches.cbegin(); }
254 iterator
end() noexcept {
return this->Batches.end(); }
255 const_iterator
end() const noexcept {
return this->Batches.end(); }
256 const_iterator
cend() const noexcept {
return this->Batches.cend(); }
261 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.