CoDiPack  3.1.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
debugMultiUseIndexManager.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 <cstdint>
38#include <vector>
39
40#include "../../config.h"
41#include "../../misc/eventSystem.hpp"
42#include "../../misc/macros.hpp"
43#include "../../misc/mathUtility.hpp"
44#include "../data/emptyData.hpp"
45#include "indexManagerInterface.hpp"
46
48namespace codi {
49
54 template<typename T_Index, typename T_Tag>
55 struct IndexTagPair {
56 using Index = CODI_DD(T_Index, int);
57 using Tag = CODI_DD(T_Tag, int);
58
61
64 return id == o.id && tag == o.tag;
65 }
66
69 return id != o.id || tag != o.tag;
70 }
71 };
72
88 template<typename T_Index>
90 public:
91
92 using Index = CODI_DD(T_Index, int);
93 using Tag = std::uint8_t;
94
97
98 private:
99
100 static size_t constexpr TAG_BITS = sizeof(std::uint8_t) * 8;
101 static Index constexpr TAG_SIZE = 1 << TAG_BITS;
102 static Index constexpr TAG_MASK = TAG_SIZE - 1;
103
104 public:
105
106 /*******************************************************************************/
109
111 static bool constexpr IsLinear = false;
112 static bool constexpr NeedsStaticStorage = true;
113
115
116 private:
117
118 bool valid;
119 Index reservedIndices;
120 Index nextNewIdentifier;
121 std::uint8_t curTag = 1; // Do not use the zero tag.
122 std::vector<std::vector<Index>> indexUse;
123
124 public:
125
127 DebugMultiUseIndexManager(Index const& reservedIndices)
128 : valid(true),
129 reservedIndices(reservedIndices),
130 nextNewIdentifier(reservedIndices + 1),
131 indexUse(2, std::vector<Index>(Config::SmallChunkSize)) {
132 resizeVectors();
133 }
134
137 valid = false;
138 }
139
140 /*******************************************************************************/
143
146 void addToTapeValues(TapeValues& values) const {
147 double memoryindexUseVector = 0;
148 for (std::vector<Index> const& cur : indexUse) {
149 memoryindexUseVector += (double)indexUse.size() * (double)(sizeof(Index));
150 }
151
152 TapeValues::LocalReductionOperation constexpr operation =
153 NeedsStaticStorage ? TapeValues::LocalReductionOperation::Max : TapeValues::LocalReductionOperation::Sum;
154
155 values.addDoubleEntry("Memory: index use vector", memoryindexUseVector, operation, true, true);
156 }
157
159 template<typename Tape>
161 if (Base::InactiveIndex != data.id) {
162 freeIndex<Tape>(data);
163 }
164
165 Index index = nextNewIdentifier;
166 nextNewIdentifier += 1;
167
168 if (getLargestCreatedIndex() < 0) {
169 CODI_EXCEPTION("Overfow of identifiers.");
170 }
171
172 resizeVectors();
173
174 data = {index, curTag};
175 indexUse[curTag][index] = 1;
176
177 return true;
178 }
179
181 template<typename Tape>
185
187 template<typename Tape>
189 validateIdentifier(lhs);
190 validateIdentifier(rhs, false);
192 // Skip the logic if the indices are the same.
193 // This also prevents the bug that if &lhs == &rhs, the left hand side will always be deactivated.
194 if (lhs != rhs) {
195 freeIndex<Tape>(lhs);
196
197 if (Base::InactiveIndex != rhs.id) { // Do not handle the zero index.
199
200 indexUse[curTag][rhs.id] += 1;
201 lhs = rhs;
202 }
203 }
204 } else {
205 // Path if copy optimizations are disabled.
207 }
208 }
209
211 template<typename Tape>
213 validateIdentifier(data);
214
215 if (valid && Base::InactiveIndex != data.id) { // Do not free the zero index.
216 indexUse[data.tag][data.id] -= 1;
217
218 if (indexUse[data.tag][data.id] == 0) { // Only free the index if it is not used any longer.
220 }
221 }
222
223 data = {Base::InactiveIndex, 0};
224 }
225
230
233 nextNewIdentifier = 1 + reservedIndices;
234
235 nextTag();
236 }
237
240 validateIdentifier(data, false);
241 }
242
245 return data.id;
246 }
247
250 return data.id;
251 }
252
255 return nextNewIdentifier - 1;
256 }
257
259
260 private:
261
262 CODI_INLINE void nextTag() {
263 // Switch to next tag
264 curTag += 1;
265 curTag = curTag % TAG_SIZE;
266
267 if (curTag == 0) {
268 curTag += 1;
269 }
270
271 // Clear append index use vector for the tag
272 if (indexUse.size() <= curTag) {
273 indexUse.push_back(std::vector<Index>(Config::SmallChunkSize));
274 } else {
275 indexUse[curTag].clear();
276 resizeVectors();
277 }
278 }
279
280 CODI_NO_INLINE void resizeVectors() {
281 indexUse[curTag].resize(nextNewIdentifier);
282 }
283
284 CODI_INLINE void validateIdentifier(ActiveTypeIndexData const& data, bool isLhs = true) const {
285 if (Base::InactiveIndex != data.id) {
286 // Check validity of the tag.
287 if (data.tag == 0 || data.tag >= indexUse.size()) {
288 CODI_EXCEPTION("Invalid tag '%d' with index '%d'.", (int)data.tag, (int)data.id);
289 }
290
291 if (indexUse[data.tag][data.id] <= 0) {
292 if (data.tag == curTag) {
293 CODI_EXCEPTION("Index '%d(%d)' is used after it was finally deleted.", (int)data.id, (int)data.tag);
294 } else {
295 CODI_EXCEPTION("Deleted index '%d(%d)' from old iteration is used.", (int)data.id, (int)data.tag);
296 }
297 }
298
299 if (data.tag != curTag) {
300 if (!isLhs) {
301 CODI_EXCEPTION("Index '%d' from an old iteration '%d' is used, current tag is %d.", (int)data.id,
302 (int)data.tag, (int)curTag);
303 }
304 }
305 }
306 }
307 };
308}
#define CODI_NO_INLINE
See codi::Config::AvoidedInlines.
Definition config.h:426
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:469
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:97
Configuration options for CoDiPack.
Definition config.h:65
size_t constexpr SmallChunkSize
Default smaller size of chunks (ChunkBase) used in ChunkedData in reverse tape implementations.
Definition config.h:133
bool constexpr CopyOptimization
Do not store copy statements like a = b; if the identity handler allows it.
Definition config.h:186
CoDiPack - Code Differentiation Package.
Definition codi.hpp:97
IndexManagerInterface< T_Index > Base
Abbreviation for the base class.
Definition debugMultiUseIndexManager.hpp:96
static bool constexpr NeedsStaticStorage
See IndexManagerInterface.
Definition debugMultiUseIndexManager.hpp:112
~DebugMultiUseIndexManager()
Destructor.
Definition debugMultiUseIndexManager.hpp:136
inlinebool assignUnusedIndex(ActiveTypeIndexData &index)
Call on registering input values.
Definition debugMultiUseIndexManager.hpp:182
inlinevoid reset()
Reset for a new recording.
Definition debugMultiUseIndexManager.hpp:232
static bool constexpr CopyNeedsStatement
See IndexManagerInterface.
Definition debugMultiUseIndexManager.hpp:110
inlinebool assignIndex(ActiveTypeIndexData &data)
Call on assignment of a primal value, e.g. on w for w = a + b.
Definition debugMultiUseIndexManager.hpp:160
static bool constexpr IsLinear
See IndexManagerInterface.
Definition debugMultiUseIndexManager.hpp:111
inlineIndex getLargestCreatedIndex() const
Returns the largest created index.
Definition debugMultiUseIndexManager.hpp:254
void addToTapeValues(TapeValues &values) const
Add storage and other information to the tape values.
Definition debugMultiUseIndexManager.hpp:146
inlinevoid validateRhsIndex(ActiveTypeIndexData const &data) const
Check if the rhs index is valid.
Definition debugMultiUseIndexManager.hpp:239
inlineIndex & getIndex(ActiveTypeIndexData &data)
Extract index from data stored in active type.
Definition debugMultiUseIndexManager.hpp:249
inlinevoid initIndex(ActiveTypeIndexData &index)
Initialize the index data. Usually zero everything.
Definition debugMultiUseIndexManager.hpp:227
DebugMultiUseIndexManager(Index const &reservedIndices)
Constructor.
Definition debugMultiUseIndexManager.hpp:127
T_Index Index
See DebugMultiUseIndexManager.
Definition debugMultiUseIndexManager.hpp:92
IndexTagPair< Index, Tag > ActiveTypeIndexData
See IndexManagerInterface.
Definition debugMultiUseIndexManager.hpp:95
inlinevoid copyIndex(ActiveTypeIndexData &lhs, ActiveTypeIndexData const &rhs)
Call on copy of a primal value, e.g. w = a.
Definition debugMultiUseIndexManager.hpp:188
inlinevoid freeIndex(ActiveTypeIndexData &data)
Definition debugMultiUseIndexManager.hpp:212
std::uint8_t Tag
Tag used for the recording live time management.
Definition debugMultiUseIndexManager.hpp:93
inlineIndex const & getIndex(ActiveTypeIndexData const &data)
Extract index from data stored in active type.
Definition debugMultiUseIndexManager.hpp:244
No data is stored in this DataInterface implementation. It is used to terminate the recursive nature ...
Definition emptyData.hpp:54
static inlinevoid notifyIndexCopyListeners(Index const &index)
Invoke callbacks for IndexCopy events.
Definition eventSystem.hpp:833
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
Default inactive index for all index managers.
Definition indexManagerInterface.hpp:87
Definition debugMultiUseIndexManager.hpp:55
T_Index Index
See IndexTagPair.
Definition debugMultiUseIndexManager.hpp:56
inlinebool operator!=(IndexTagPair const &o)
Not equal comparison.
Definition debugMultiUseIndexManager.hpp:68
inlinebool operator==(IndexTagPair const &o)
Equal comparison.
Definition debugMultiUseIndexManager.hpp:63
Index id
Definition debugMultiUseIndexManager.hpp:59
T_Tag Tag
See IndexTagPair.
Definition debugMultiUseIndexManager.hpp:57
Tag tag
Definition debugMultiUseIndexManager.hpp:60
Tape information that can be printed in a pretty print format or a table format.
Definition tapeValues.hpp:75
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