29#include "vtkCommonCoreModule.h"
37VTK_ABI_NAMESPACE_BEGIN
39template <
typename TBatchData>
48template <
typename TBatchData>
53 using vector = std::vector<vtkTBatch>;
54 using size_type =
typename vector::size_type;
55 using reference =
typename vector::reference;
56 using const_reference =
typename vector::const_reference;
57 using iterator =
typename vector::iterator;
58 using const_iterator =
typename vector::const_iterator;
72 this->BatchSize = batchSize;
74 const auto batchSizeSigned =
static_cast<vtkIdType>(batchSize);
75 const auto numberOfBatches = ((numberOfElements - 1) / batchSizeSigned) + 1;
76 this->Batches.resize(
static_cast<size_t>(numberOfBatches));
77 const auto lastBatchId = numberOfBatches - 1;
82 vtkIdType endIdValues[2] = { -1, numberOfElements };
83 for (
vtkIdType batchId = beginBatchId; batchId < endBatchId; ++batchId)
85 auto& batch = this->Batches[batchId];
86 batch.BeginId = batchId * batchSizeSigned;
87 endIdValues[0] = (batchId + 1) * batchSizeSigned;
88 batch.EndId = endIdValues[batchId == lastBatchId];
96 void TrimBatches(
const std::function<
bool(
const vtkTBatch&)> shouldRemoveBatch)
99 if (numberOfBatches == 0)
105 const vtkIdType lastThreadId = numberOfThreads - 1;
106 const vtkIdType numberOfBatchesPerThread = numberOfBatches / numberOfThreads;
108 std::vector<vtkIdType> tlInterEndBatchId;
109 tlInterEndBatchId.resize(
static_cast<size_t>(numberOfThreads));
115 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
117 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
119 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
120 auto beginBatchIter = this->Batches.begin() + beginBatchId;
121 auto endBatchIter = this->Batches.begin() + endBatchId;
122 auto newEndBatchIter = std::remove_if(beginBatchIter, endBatchIter, shouldRemoveBatch);
123 tlInterEndBatchId[threadId] =
124 beginBatchId + std::distance(beginBatchIter, newEndBatchIter);
128 std::vector<vtkIdType> tlNewEndBatchId;
129 tlNewEndBatchId.resize(
static_cast<size_t>(numberOfThreads));
130 tlNewEndBatchId[0] = tlInterEndBatchId[0];
131 for (
vtkIdType threadId = 1; threadId < numberOfThreads; ++threadId)
133 const vtkIdType beginOldBatchId = threadId * numberOfBatchesPerThread;
134 const auto& prevNewEndBatchId = tlNewEndBatchId[threadId - 1];
135 const vtkIdType distance = tlInterEndBatchId[threadId] - beginOldBatchId;
136 tlNewEndBatchId[threadId] = prevNewEndBatchId + distance;
138 if (prevNewEndBatchId != beginOldBatchId)
140 std::move(this->Batches.begin() + beginOldBatchId,
141 this->Batches.begin() + tlInterEndBatchId[threadId],
142 this->Batches.begin() + prevNewEndBatchId);
145 this->Batches.erase(this->Batches.begin() + tlNewEndBatchId[lastThreadId], this->Batches.end());
162 if (numberOfBatches == 0)
168 const vtkIdType lastThreadId = numberOfThreads - 1;
169 const vtkIdType numberOfBatchesPerThread = numberOfBatches / numberOfThreads;
172 std::vector<TBatchData> tlSums;
173 tlSums.resize(
static_cast<size_t>(numberOfThreads));
178 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
180 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
182 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
184 auto& threadSum = tlSums[threadId];
185 for (
vtkIdType batchId = beginBatchId; batchId < endBatchId; ++batchId)
187 threadSum += this->Batches[batchId].Data;
193 TBatchData globalSum;
194 for (
const auto& threadSum : tlSums)
196 globalSum += threadSum;
200 std::vector<TBatchData> tlOffsets;
201 tlOffsets.resize(
static_cast<size_t>(numberOfThreads));
202 for (
vtkIdType threadId = 1; threadId < numberOfThreads; ++threadId)
204 tlOffsets[threadId] = tlOffsets[threadId - 1] + tlSums[threadId - 1];
211 for (
vtkIdType threadId = beginThreadId; threadId < endThreadId; ++threadId)
213 const vtkIdType beginBatchId = threadId * numberOfBatchesPerThread;
215 threadId != lastThreadId ? (threadId + 1) * numberOfBatchesPerThread : numberOfBatches;
218 auto lastBatchData = this->Batches[beginBatchId].Data;
220 this->Batches[beginBatchId].Data = tlOffsets[threadId];
221 for (
vtkIdType batchId = beginBatchId + 1; batchId < endBatchId; ++batchId)
224 const auto currentBatchData = this->Batches[batchId].Data;
226 const auto newData = this->Batches[batchId - 1].Data + lastBatchData;
228 this->Batches[batchId].Data = newData;
230 lastBatchData = std::move(currentBatchData);
252 reference
operator[](size_type pos)
noexcept {
return this->Batches[pos]; }
253 const_reference
operator[](size_type pos)
const noexcept {
return this->Batches[pos]; }
254 iterator
begin() noexcept {
return this->Batches.begin(); }
255 const_iterator
begin() const noexcept {
return this->Batches.begin(); }
256 const_iterator
cbegin() const noexcept {
return this->Batches.cbegin(); }
257 iterator
end() noexcept {
return this->Batches.end(); }
258 const_iterator
end() const noexcept {
return this->Batches.end(); }
259 const_iterator
cend() const noexcept {
return this->Batches.cend(); }
264 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.