CoDiPack  3.0.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
reuseIndexManagerBase.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2025 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://scicomp.rptu.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://scicomp.rptu.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <algorithm>
38#include <vector>
39
40#include "../../config.h"
41#include "../../misc/macros.hpp"
42#include "../../misc/mathUtility.hpp"
43#include "../data/emptyData.hpp"
44#include "indexManagerInterface.hpp"
46namespace codi {
47
65 template<typename T_Index, typename T_Impl>
66 struct ReuseIndexManagerBase : public IndexManagerInterface<T_Index>, public EmptyData {
67 public:
68
69 using Index = CODI_DD(T_Index, int);
70 using Impl = CODI_DD(T_Impl, CODI_IMPLEMENTATION);
72
74
75 /*******************************************************************************/
78
79 static bool constexpr CopyNeedsStatement = true;
80 static bool constexpr IsLinear = false;
81 static bool constexpr NeedsStaticStorage = true;
82
84
85 protected:
86
87 std::vector<Index> usedIndices;
89
90 std::vector<Index> unusedIndices;
92
94
95 bool valid;
96
97 private:
98 /*******************************************************************************/
101
103 CODI_INLINE Impl& cast() {
104 return static_cast<Impl&>(*this);
105 }
106
108 CODI_INLINE Impl const& cast() const {
109 return static_cast<Impl const&>(*this);
110 }
111
113 CODI_NO_INLINE void generateNewIndices() {
114 cast().generateNewIndices();
115 }
116
118
119 public:
120
124 : usedIndices(),
128 indexSizeIncrement(Config::SmallChunkSize),
129 valid(true) {
130 increaseIndicesSize(unusedIndices);
131 }
132
135 valid = false;
136 }
137
138 /*******************************************************************************/
141
143 template<typename Tape>
145 bool generatedNewIndex = false;
146
147 if (Base::InactiveIndex == index) {
148 if (0 == usedIndicesPos) {
149 if (0 == unusedIndicesPos) {
150 generateNewIndices();
151 generatedNewIndex = true;
152 }
153
154 unusedIndicesPos -= 1;
156 } else {
157 usedIndicesPos -= 1;
159 }
160 }
161
163
164 return generatedNewIndex;
165 }
166
168 template<typename Tape>
170 freeIndex<Tape>(index); // Zero check is performed inside.
171
172 bool generatedNewIndex = false;
173 if (0 == unusedIndicesPos) {
174 generateNewIndices();
175 generatedNewIndex = true;
176 }
177
178 unusedIndicesPos -= 1;
180
182
183 return generatedNewIndex;
184 }
185
187 template<typename Tape>
188 CODI_INLINE void copyIndex(Index& lhs, Index const& rhs) {
189 if (Base::InactiveIndex == rhs) {
190 freeIndex<Tape>(lhs);
191 } else {
193 }
194 }
195
197 template<typename Tape>
199 if (valid && Base::InactiveIndex != index) { // Do not free the zero index.
200 codiAssert(index <= cast().getLargestCreatedIndex());
201
203
204 if (usedIndicesPos == usedIndices.size()) {
205 increaseIndicesSize(usedIndices);
206 }
207
209 usedIndicesPos += 1;
210
211 index = Base::InactiveIndex;
212 }
213 }
214
217 /* This method calculates the number of new indices that needs to be added to the unusedIndices vector.
218 The length of the unusedIndices vector is adjusted in multiples of indexSizeIncrement.
219 This is done by recursively calling by generateNewIndices. */
220 if (index > cast().getLargestCreatedIndex()) {
221 Index needToGenerate = index - cast().getLargestCreatedIndex();
222 size_t newUnusedIndexSize = this->unusedIndicesPos + needToGenerate;
223
224 // Round up newUnusedIndexSize to a multiple of indexSizeIncrement and then resize.
225 newUnusedIndexSize = getNextMultiple(newUnusedIndexSize, this->indexSizeIncrement);
226 this->unusedIndices.resize(newUnusedIndexSize);
227
228 // Generate the new unusedIndices in steps of indexSizeIncrement.
229 while (index > cast().getLargestCreatedIndex()) {
230 generateNewIndices();
231 }
232 }
233 }
234
237 size_t totalSize = usedIndicesPos + unusedIndicesPos;
238 if (totalSize > unusedIndices.size()) {
239 increaseIndicesSizeTo(unusedIndices, totalSize);
240 }
241
242 for (size_t pos = 0; pos < usedIndicesPos; ++pos) {
244 }
245 unusedIndicesPos = totalSize;
246 usedIndicesPos = 0;
247
249 if (totalSize == unusedIndices.size()) {
250 std::sort(unusedIndices.begin(), unusedIndices.end());
251 } else {
253 }
254 }
255 }
256
259 void addToTapeValues(TapeValues& values) const {
260 unsigned long storedIndices = this->usedIndicesPos + this->unusedIndicesPos;
261 unsigned long allocatedIndices = this->usedIndices.size() + this->unusedIndices.size();
262
263 double memoryStoredIndices = (double)storedIndices * (double)(sizeof(Index));
264 double memoryAllocatedIndices = (double)allocatedIndices * (double)(sizeof(Index));
265
266 TapeValues::LocalReductionOperation constexpr operation = Impl::NeedsStaticStorage
267 ? TapeValues::LocalReductionOperation::Max
268 : TapeValues::LocalReductionOperation::Sum;
269
270 values.addUnsignedLongEntry("Indices stored", storedIndices, operation);
271 values.addDoubleEntry("Memory used", memoryStoredIndices, operation, true, false);
272 values.addDoubleEntry("Memory allocated", memoryAllocatedIndices, operation, false, true);
273 }
274
276
277 private:
278
279 CODI_NO_INLINE void increaseIndicesSize(std::vector<Index>& v) {
280 v.resize(v.size() + indexSizeIncrement);
281 }
282
283 CODI_NO_INLINE void increaseIndicesSizeTo(std::vector<Index>& v, size_t minimalSize) {
284 codiAssert(v.size() < minimalSize);
285
286 size_t increaseMul = (minimalSize - v.size()) / indexSizeIncrement + 1; // +1 always rounds up.
287 v.resize(v.size() + increaseMul * indexSizeIncrement);
288 }
289 };
290}
#define CODI_NO_INLINE
See codi::Config::AvoidedInlines.
Definition config.h:426
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:469
#define codiAssert(x)
See codi::Config::EnableAssert.
Definition config.h:441
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:96
#define CODI_IMPLEMENTATION
Used in interface declarations to indicate the type of the implementing class.
Definition macros.hpp:110
Configuration options for CoDiPack.
Definition config.h:65
bool constexpr SortIndicesOnReset
Reuse index tapes will sort their indices on a reset.
Definition config.h:273
CoDiPack - Code Differentiation Package.
Definition codi.hpp:94
IntegralType getNextMultiple(IntegralType const &targetSize, IntegralType const &chunkSize)
Helper function for overallocation in multiples of a given chunk size.
Definition mathUtility.hpp:49
No data is stored in this DataInterface implementation. It is used to terminate the recursive nature ...
Definition emptyData.hpp:54
EmptyPosition Position
No positional data.
Definition emptyData.hpp:59
static inlinevoid notifyIndexAssignListeners(Index const &index)
Invoke callbacks for IndexAssign events.
Definition eventSystem.hpp:778
static inlinevoid notifyIndexFreeListeners(Index const &index)
Invoke callbacks for IndexFree events.
Definition eventSystem.hpp:806
Indices enable the mapping of primal values to their adjoint counterparts.
Definition indexManagerInterface.hpp:78
static Index constexpr InactiveIndex
Definition indexManagerInterface.hpp:86
Index getLargestCreatedIndex() const
Returns the largest created index.
static bool constexpr NeedsStaticStorage
< See ReuseIndexManagerBase.
Definition parallelReuseIndexManager.hpp:84
static bool constexpr IsLinear
Definition reuseIndexManagerBase.hpp:80
bool valid
Definition reuseIndexManagerBase.hpp:95
~ReuseIndexManagerBase()
Destructor.
Definition reuseIndexManagerBase.hpp:134
inlinevoid reset()
Reset for a new recording.
Definition reuseIndexManagerBase.hpp:236
inlinevoid copyIndex(Index &lhs, Index const &rhs)
Call on copy of a primal value, e.g. w = a.
Definition reuseIndexManagerBase.hpp:188
inlinebool assignUnusedIndex(Index &index)
Call on registering input values.
Definition reuseIndexManagerBase.hpp:169
ParallelReuseIndexManager Impl
Definition reuseIndexManagerBase.hpp:70
ReuseIndexManagerBase()
Definition reuseIndexManagerBase.hpp:123
EmptyData::Position Position
Definition reuseIndexManagerBase.hpp:73
std::vector< Index > unusedIndices
Definition reuseIndexManagerBase.hpp:90
std::vector< Index > usedIndices
Definition reuseIndexManagerBase.hpp:87
static bool constexpr CopyNeedsStatement
Definition reuseIndexManagerBase.hpp:79
inlinebool assignIndex(Index &index)
Call on assignment of a primal value, e.g. on w for w = a + b.
Definition reuseIndexManagerBase.hpp:144
void addToTapeValues(TapeValues &values) const
Add storage and other information to the tape values.
Definition reuseIndexManagerBase.hpp:259
static bool constexpr NeedsStaticStorage
Definition reuseIndexManagerBase.hpp:81
Index Index
Definition reuseIndexManagerBase.hpp:69
size_t indexSizeIncrement
Definition reuseIndexManagerBase.hpp:93
IndexManagerInterface< Index > Base
Definition reuseIndexManagerBase.hpp:71
size_t unusedIndicesPos
Definition reuseIndexManagerBase.hpp:91
inlinevoid freeIndex(Index &index)
Call on destruction of a primal value. Usually called from the destructor.
Definition reuseIndexManagerBase.hpp:198
size_t usedIndicesPos
Definition reuseIndexManagerBase.hpp:88
void updateLargestCreatedIndex(Index const &index)
Update the largest generated index.
Definition reuseIndexManagerBase.hpp:216
Tape information that can be printed in a pretty print format or a table format.
Definition tapeValues.hpp:75
void addUnsignedLongEntry(std::string const &name, unsigned long const &value, LocalReductionOperation operation=LocalReductionOperation::Sum)
Add unsigned long entry.
Definition tapeValues.hpp:163
void addDoubleEntry(std::string const &name, double const &value, LocalReductionOperation operation=LocalReductionOperation::Sum, bool usedMem=false, bool allocatedMem=false)
Add double entry. If it is a memory entry, it should be in bytes.
Definition tapeValues.hpp:137