CoDiPack  3.1.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-2026 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:
69 using Index = CODI_DD(T_Index, int);
71 using Impl = CODI_DD(T_Impl, CODI_IMPLEMENTATION);
73
75
76 /*******************************************************************************/
79
80 static bool constexpr CopyNeedsStatement = true;
81 static bool constexpr IsLinear = false;
82 static bool constexpr NeedsStaticStorage = true;
83
85
86 protected:
87
88 std::vector<Index> usedIndices;
90
91 std::vector<Index> unusedIndices;
93
95
96 bool valid;
97
98 private:
99 /*******************************************************************************/
102
104 CODI_INLINE Impl& cast() {
105 return static_cast<Impl&>(*this);
106 }
107
109 CODI_INLINE Impl const& cast() const {
110 return static_cast<Impl const&>(*this);
111 }
112
114 CODI_NO_INLINE void generateNewIndices() {
115 cast().generateNewIndices();
116 }
117
119
120 public:
121
125 : usedIndices(),
129 indexSizeIncrement(Config::SmallChunkSize),
130 valid(true) {
131 increaseIndicesSize(unusedIndices);
132 }
133
136 valid = false;
137 }
138
139 /*******************************************************************************/
142
144 template<typename Tape>
146 bool generatedNewIndex = false;
147
148 if (Base::InactiveIndex == index) {
149 if (0 == usedIndicesPos) {
150 if (0 == unusedIndicesPos) {
151 generateNewIndices();
152 generatedNewIndex = true;
153 }
154
155 unusedIndicesPos -= 1;
157 } else {
158 usedIndicesPos -= 1;
160 }
161 }
162
164
165 return generatedNewIndex;
166 }
167
169 template<typename Tape>
171 freeIndex<Tape>(index); // Zero check is performed inside.
172
173 bool generatedNewIndex = false;
174 if (0 == unusedIndicesPos) {
175 generateNewIndices();
176 generatedNewIndex = true;
177 }
178
179 unusedIndicesPos -= 1;
181
183
184 return generatedNewIndex;
185 }
186
188 template<typename Tape>
189 CODI_INLINE void copyIndex(Index& lhs, Index const& rhs) {
190 if (Base::InactiveIndex == rhs) {
191 freeIndex<Tape>(lhs);
192 } else {
194 }
195 }
196
198 template<typename Tape>
200 if (valid && Base::InactiveIndex != index) { // Do not free the zero index.
201 codiAssert(index <= cast().getLargestCreatedIndex());
202
204
205 if (usedIndicesPos == usedIndices.size()) {
206 increaseIndicesSize(usedIndices);
207 }
208
210 usedIndicesPos += 1;
211
212 index = Base::InactiveIndex;
213 }
214 }
215
218 index = Index();
219 }
220
223 /* This method calculates the number of new indices that needs to be added to the unusedIndices vector.
224 The length of the unusedIndices vector is adjusted in multiples of indexSizeIncrement.
225 This is done by recursively calling by generateNewIndices. */
226 if (index > cast().getLargestCreatedIndex()) {
227 Index needToGenerate = index - cast().getLargestCreatedIndex();
228 size_t newUnusedIndexSize = this->unusedIndicesPos + needToGenerate;
229
230 // Round up newUnusedIndexSize to a multiple of indexSizeIncrement and then resize.
231 newUnusedIndexSize = getNextMultiple(newUnusedIndexSize, this->indexSizeIncrement);
232 this->unusedIndices.resize(newUnusedIndexSize);
233
234 // Generate the new unusedIndices in steps of indexSizeIncrement.
235 while (index > cast().getLargestCreatedIndex()) {
236 generateNewIndices();
237 }
238 }
239 }
240
243 size_t totalSize = usedIndicesPos + unusedIndicesPos;
244 if (totalSize > unusedIndices.size()) {
245 increaseIndicesSizeTo(unusedIndices, totalSize);
246 }
247
248 for (size_t pos = 0; pos < usedIndicesPos; ++pos) {
250 }
251 unusedIndicesPos = totalSize;
252 usedIndicesPos = 0;
253
255 if (totalSize == unusedIndices.size()) {
256 std::sort(unusedIndices.begin(), unusedIndices.end());
257 } else {
259 }
260 }
261 }
262
265 void addToTapeValues(TapeValues& values) const {
266 unsigned long storedIndices = this->usedIndicesPos + this->unusedIndicesPos;
267 unsigned long allocatedIndices = this->usedIndices.size() + this->unusedIndices.size();
268
269 double memoryStoredIndices = (double)storedIndices * (double)(sizeof(Index));
270 double memoryAllocatedIndices = (double)allocatedIndices * (double)(sizeof(Index));
271
272 TapeValues::LocalReductionOperation constexpr operation = Impl::NeedsStaticStorage
273 ? TapeValues::LocalReductionOperation::Max
274 : TapeValues::LocalReductionOperation::Sum;
275
276 values.addUnsignedLongEntry("Indices stored", storedIndices, operation);
277 values.addDoubleEntry("Memory used", memoryStoredIndices, operation, true, false);
278 values.addDoubleEntry("Memory allocated", memoryAllocatedIndices, operation, false, true);
279 }
280
282 void validateRhsIndex(ActiveTypeIndexData const& data) const {
283 CODI_UNUSED(data);
284
285 codiAssert(data <= cast().getLargestCreatedIndex());
286 }
287
289 CODI_INLINE Index const& getIndex(Index const& data) {
290 return data;
291 }
292
295 return data;
296 }
297
299
300 private:
301
302 CODI_NO_INLINE void increaseIndicesSize(std::vector<Index>& v) {
303 v.resize(v.size() + indexSizeIncrement);
304 }
305
306 CODI_NO_INLINE void increaseIndicesSizeTo(std::vector<Index>& v, size_t minimalSize) {
307 codiAssert(v.size() < minimalSize);
308
309 size_t increaseMul = (minimalSize - v.size()) / indexSizeIncrement + 1; // +1 always rounds up.
310 v.resize(v.size() + increaseMul * indexSizeIncrement);
311 }
312 };
313}
#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:97
#define CODI_IMPLEMENTATION
Used in interface declarations to indicate the type of the implementing class.
Definition macros.hpp:111
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:97
IntegralType getNextMultiple(IntegralType const &targetSize, IntegralType const &chunkSize)
Helper function for overallocation in multiples of a given chunk size.
Definition mathUtility.hpp:49
inlinevoid CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:55
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:87
Index getLargestCreatedIndex() const
Returns the largest created index.
static bool constexpr NeedsStaticStorage
< See ReuseIndexManagerBase.
Definition parallelReuseIndexManager.hpp:85
static bool constexpr IsLinear
Definition reuseIndexManagerBase.hpp:81
Index ActiveTypeIndexData
Definition reuseIndexManagerBase.hpp:70
bool valid
Definition reuseIndexManagerBase.hpp:96
~ReuseIndexManagerBase()
Destructor.
Definition reuseIndexManagerBase.hpp:135
inlinevoid reset()
Reset for a new recording.
Definition reuseIndexManagerBase.hpp:242
inlinevoid copyIndex(Index &lhs, Index const &rhs)
Call on copy of a primal value, e.g. w = a.
Definition reuseIndexManagerBase.hpp:189
inlinebool assignUnusedIndex(Index &index)
Call on registering input values.
Definition reuseIndexManagerBase.hpp:170
inlineIndex & getIndex(Index &data)
Extract index from data stored in active type.
Definition reuseIndexManagerBase.hpp:294
ParallelReuseIndexManager Impl
Definition reuseIndexManagerBase.hpp:71
ReuseIndexManagerBase()
Definition reuseIndexManagerBase.hpp:124
void validateRhsIndex(ActiveTypeIndexData const &data) const
Check if the rhs index is valid.
Definition reuseIndexManagerBase.hpp:282
EmptyData::Position Position
Definition reuseIndexManagerBase.hpp:74
std::vector< Index > unusedIndices
Definition reuseIndexManagerBase.hpp:91
std::vector< Index > usedIndices
Definition reuseIndexManagerBase.hpp:88
static bool constexpr CopyNeedsStatement
Definition reuseIndexManagerBase.hpp:80
inlinebool assignIndex(Index &index)
Call on assignment of a primal value, e.g. on w for w = a + b.
Definition reuseIndexManagerBase.hpp:145
inlineIndex const & getIndex(Index const &data)
Extract index from data stored in active type.
Definition reuseIndexManagerBase.hpp:289
void addToTapeValues(TapeValues &values) const
Add storage and other information to the tape values.
Definition reuseIndexManagerBase.hpp:265
static bool constexpr NeedsStaticStorage
Definition reuseIndexManagerBase.hpp:82
Index Index
Definition reuseIndexManagerBase.hpp:69
size_t indexSizeIncrement
Definition reuseIndexManagerBase.hpp:94
IndexManagerInterface< Index > Base
Definition reuseIndexManagerBase.hpp:72
size_t unusedIndicesPos
Definition reuseIndexManagerBase.hpp:92
inlinevoid freeIndex(Index &index)
Definition reuseIndexManagerBase.hpp:199
size_t usedIndicesPos
Definition reuseIndexManagerBase.hpp:89
inlinevoid initIndex(Index &index)
Initialize the index data. Usually zero everything.
Definition reuseIndexManagerBase.hpp:217
void updateLargestCreatedIndex(Index const &index)
Update the largest generated index.
Definition reuseIndexManagerBase.hpp:222
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