CoDiPack  3.1.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
tagTapeBase.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 "../../expressions/logic/helpers/forEachLeafLogic.hpp"
38#include "../../misc/enumBitset.hpp"
39#include "../indices/indexManagerInterface.hpp"
40#include "../interfaces/fullTapeInterface.hpp"
41#include "../misc/adjointVectorAccess.hpp"
42#include "tagData.hpp"
43
45namespace codi {
46
48 template<typename Real, typename Tag>
50 bool isActive;
51 bool hasError;
55 Real value;
56
59 : isActive(false), hasError(false), hasTagError(false), hasUseError(false), errorTag(), value() {}
60 };
61
72 template<typename T_Real, typename T_Tag, typename T_Gradient, typename T_Impl>
73 struct TagTapeBase {
74 using Real = CODI_DD(T_Real, double);
75 using Tag = CODI_DD(T_Tag, int);
76 using Gradient = CODI_DD(T_Gradient, int);
77 using Impl = CODI_DD(T_Impl, int);
78
79 using Identifier = int;
81
83 using TagPropertyErrorCallback = void (*)(Real const& currentValue, Real const& newValue, TagFlags flag,
84 void* userData);
85
87 using TagErrorCallback = void (*)(Tag const& correctTag, Tag const& wrongTag, void* userData);
88
89 static Tag constexpr PassiveTag = Tag(0);
90 static Tag constexpr InvalidTag = Tag(-1);
91
92 protected:
93
95
98
101
104
108
109 public:
110
120
122 struct ValidateTags : public ForEachLeafLogic<ValidateTags> {
123 public:
124
126 template<typename Node>
128 ActiveTypeTapeData tagData = node.getTapeData();
129 tape.verifyTag(vi, tagData.tag);
130 tape.verifyProperties(vi, node.getValue(), tagData.properties);
131 }
132 };
133
135 void swap(Impl& other) {
136 std::swap(curTag, other.curTag);
137 std::swap(tagPropertyErrorCallback, other.tagPropertyErrorCallback);
138 std::swap(tagPropertyErrorUserData, other.tagPropertyErrorUserData);
139 std::swap(tagErrorCallback, other.tagErrorCallback);
140 std::swap(tagErrorUserData, other.tagErrorUserData);
141 std::swap(preaccumulationHandling, other.preaccumulationHandling);
142 std::swap(preaccumulationTag, other.preaccumulationTag);
143 }
144
145 /*******************************************************************************/
148
151 if (data.tag != 0) {
152 return activeIdentifier;
153 } else {
154 return passiveIdentifier;
155 }
156 }
157
163
165 /*******************************************************************************/
168
169 static bool constexpr AllowJacobianOptimization = false;
170
172 template<typename Real>
174 CODI_UNUSED(value);
175 data = ActiveTypeTapeData();
176 }
177
179 template<typename Real>
181 CODI_UNUSED(value, data);
182 }
183
184 template<typename Aggregated, typename Type, typename Lhs, typename Rhs>
187 using AggregatedTraits = RealTraits::AggregatedTypeTraits<Aggregated>;
188
189 int constexpr Elements = AggregatedTraits::Elements;
190
192
193 Aggregated real = rhs.cast().getValue();
194
195 static_for<Elements>([this, &vi, &lhs, &rhs, &real](auto i) CODI_LAMBDA_INLINE {
196 ValidateTags validate;
197
198 validate.eval(ArrayAccessExpression<Aggregated, i.value, Rhs>(rhs), vi[i.value], cast());
199 checkLhsError(lhs.values[i.value], AggregatedTraits::template arrayAccess<i.value>(real));
200
201 handleError(vi[i.value]);
202 });
203
204 static_for<Elements>([this, &vi, &lhs, &real](auto i) CODI_LAMBDA_INLINE {
205 if (vi[i.value].isActive) {
206 setTag(lhs.values[i.value].getTapeData().tag);
207 } else {
208 resetTag(lhs.values[i.value].getTapeData().tag);
209 }
210 lhs.values[i.value].value() = AggregatedTraits::template arrayAccess<i.value>(real);
211 });
212 }
213
216 template<typename Aggregated, typename Type, typename Lhs, typename Rhs>
219 store<Aggregated, Type, Lhs, Rhs>(lhs, static_cast<ExpressionInterface<Aggregated, Rhs> const&>(rhs));
220 }
221
223 template<typename Lhs, typename Rhs>
225 ValidateTags validate;
227
228 validate.eval(rhs, vi, cast());
229
230 checkLhsError(lhs, rhs.cast().getValue());
231
232 handleError(vi);
233
234 if (vi.isActive) {
235 setTag(lhs.cast().getTapeData().tag);
236 } else {
237 resetTag(lhs.cast().getTapeData().tag);
238 }
239
240 lhs.cast().value() = rhs.cast().getValue();
241 }
242
244 template<typename Lhs, typename Rhs>
247 store<Lhs, Rhs>(lhs, static_cast<ExpressionInterface<Real, Rhs> const&>(rhs));
248 }
249
251 template<typename Lhs>
253 checkLhsError(lhs, rhs);
254
255 resetTag(lhs.cast().getTapeData().tag);
256
257 lhs.cast().value() = rhs;
258 }
259
261 /*******************************************************************************/
264
266 void setCurTag(const Tag& tag) {
267 this->curTag = tag;
268 }
269
272 return this->curTag;
273 }
274
276 template<typename Lhs>
278 return value.cast().getTapeData().tag;
279 }
280
282 template<typename Lhs>
284 value.cast().getTapeData().tag = this->curTag;
285 }
286
288 template<typename Lhs>
290 value.cast().getTapeData().tag = Tag();
291 }
292
294 template<typename Lhs>
296 value.cast().getTapeData().properties.reset();
297 }
298
300 template<typename Lhs>
302 value.cast().getTapeData().properties.set(flag);
303 }
304
306 template<typename Lhs>
308 return value.cast().getTapeData().properties.test(flag);
309 }
310
312 void setTagPropertyErrorCallback(TagPropertyErrorCallback const& callback, void* userData) {
313 tagPropertyErrorCallback = callback;
314 tagPropertyErrorUserData = userData;
315 }
316
318 void setTagErrorCallback(TagErrorCallback const& callback, void* userData) {
319 tagErrorCallback = callback;
320 tagErrorUserData = userData;
321 }
322
328
333
338
343
344 protected:
345
348 if (PassiveTag != tag && InvalidTag != tag) {
349 vi.isActive = true;
350 if (tag != curTag) {
351 vi.hasError = true;
352 vi.hasTagError = true;
353 vi.errorTag = tag;
354 }
355 }
356 }
357
359 CODI_INLINE void verifyTag(Tag const& tag) const {
361
362 verifyTag(vi, tag);
363 handleError(vi);
364 }
365
368 const EnumBitset<TagFlags>& properties) const {
369 if (properties.test(TagFlags::DoNotUse)) {
370 vi.hasError = true;
371 vi.hasUseError = true;
372 vi.value = value;
373 }
374 }
375
377 CODI_INLINE void verifyTagAndProperties(Tag const& tag, Real const& value,
378 const EnumBitset<TagFlags>& properties) const {
380
381 verifyTag(vi, tag);
382 verifyProperties(vi, value, properties);
383 handleError(vi);
384 }
385
387 static void defaultPropertyErrorCallback(Real const& currentValue, Real const& newValue, TagFlags flag,
388 void* userData) {
389 CODI_UNUSED(userData);
390
391 std::cerr << "Property error '" << std::to_string(flag) << "' on value. current value: " << currentValue
392 << " new value: " << newValue << "" << std::endl;
393 }
394
396 static void defaultTagErrorCallback(Tag const& correctTag, Tag const& wrongTag, void* userData) {
397 TagTapeBase& impl = *static_cast<TagTapeBase*>(userData);
398
399 // output default warning if no handle is defined.
400 std::cerr << "Use of variable with bad tag '" << wrongTag << "', should be '" << correctTag << "'.";
401 if (wrongTag == impl.preaccumulationTag) {
402 std::cerr << " The value seems to be a preaccumulation output.";
403 } else if (correctTag == impl.preaccumulationTag) {
404 std::cerr << " The value seems to be used during a preaccumulation but is not declared as an input.";
405 }
406 std::cerr << std::endl;
407 }
408
410 CODI_INLINE void checkLhsError(Real& lhsValue, ActiveTypeTapeData& lhsData, const Real& rhs) const {
411 if (lhsData.properties.test(TagFlags::DoNotChange)) {
412 if (lhsValue != rhs) {
414 }
415 } else if (lhsData.properties.test(TagFlags::DoNotWrite)) {
417 }
418 }
419
421 template<typename Lhs>
423 checkLhsError(lhs.cast().value(), lhs.cast().getTapeData(), rhs);
424 }
425
437
439 template<typename Lhs>
441 ActiveTypeTapeData const& tag) {
443
444 verifyTag(vi, tag.tag);
445 verifyProperties(vi, value.cast().getValue(), tag.properties);
446 handleError(vi);
447
448 checkLhsError(value, value.cast().getValue());
449 }
450
452 CODI_INLINE void setTag(Tag& tag) const {
453 tag = curTag;
454 }
455
457 CODI_INLINE void resetTag(Tag& tag) const {
458 tag = Tag();
459 }
460
461
462 private:
464 CODI_INLINE Impl& cast() {
465 return static_cast<Impl&>(*this);
466 }
467 };
468}
#define CODI_LAMBDA_INLINE
See codi::Config::ForcedInlines.
Definition config.h:473
#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
CoDiPack - Code Differentiation Package.
Definition codi.hpp:97
inlinevoid static_for(F func, Args &&... args)
Static for with i = 0 .. (N - 1). See CompileTimeLoop for details.
Definition compileTimeLoop.hpp:110
typename ArrayAccessExpressionImpl< Aggregated, element >::template Expression< Arg > ArrayAccessExpression
Expression that performs a[element] in a compile time context.
Definition arrayAccessExpression.hpp:98
inlineauto real(ExpressionInterface< std::complex< Real >, Arg > const &arg)
Function overload for FUNCTION.
Definition allOperators.hpp:75
inlinevoid CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:55
TagFlags
Properties for values.
Definition tagData.hpp:46
@ DoNotChange
DoNotChange: Value can be assigned, but it should not change.
Definition tagData.hpp:47
@ DoNotWrite
DoNotWrite: Value can not be assigned.
Definition tagData.hpp:48
@ DoNotUse
Definition tagData.hpp:49
InnerActiveType values[Elements]
Array representation.
Definition aggregatedActiveType.hpp:75
Represents a concrete aggregated lvalue int the CoDiPack expression tree.
Definition aggregatedActiveType.hpp:164
A bitset with enum items as flags.
Definition enumBitset.hpp:64
inlinebool test(Enum pos) const
Test if the bit for the enum is set.
Definition enumBitset.hpp:93
Base class for all CoDiPack expressions.
Definition expressionInterface.hpp:60
inlineImpl const & cast() const
Cast to the implementation.
Definition expressionInterface.hpp:76
Implement logic for leaf nodes only.
Definition forEachLeafLogic.hpp:60
ValidateTags Impl
Definition forEachLeafLogic.hpp:63
Base class for all CoDiPack lvalue expression.
Definition lhsExpressionInterface.hpp:63
inlineImpl & cast()
Cast to the implementation.
Definition lhsExpressionInterface.hpp:103
Methods that access inner values of aggregated types that contain CoDiPack active types.
Definition realTraits.hpp:233
Data for a tag.
Definition tagData.hpp:56
EnumBitset< TagFlags > properties
Current properties of the value.
Definition tagData.hpp:62
Tag tag
Current tag of the value.
Definition tagData.hpp:61
Looks at the tags for the expression.
Definition tagTapeBase.hpp:122
inlinevoid handleActive(Node const &node, ValidationIndicator< Real, Tag > &vi, Impl &tape)
Called for leaf nodes which implement LhsExpressionInterface.
Definition tagTapeBase.hpp:127
void setTagPropertyOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value, TagFlags flag)
Set properties on a CoDiPack active type.
Definition tagTapeBase.hpp:301
inlinevoid setTag(Tag &tag) const
Set tag on value.
Definition tagTapeBase.hpp:452
inlineTag getPreaccumulationHandlingTag()
The special tag for preaccumulation.
Definition tagTapeBase.hpp:340
void clearTagOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Clear tag on a CoDiPack active type.
Definition tagTapeBase.hpp:289
static bool constexpr AllowJacobianOptimization
Definition tagTapeBase.hpp:169
TagErrorCallback tagErrorCallback
Definition tagTapeBase.hpp:99
void destroyTapeData(Real &value, ActiveTypeTapeData &data)
Do nothing.
Definition tagTapeBase.hpp:180
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, ExpressionInterface< Real, Rhs > const &rhs)
Verify all tags of the rhs and the lhs properties.
Definition tagTapeBase.hpp:224
T_Impl Impl
See TagTapeBase.
Definition tagTapeBase.hpp:77
void(*)(Tag const &correctTag, Tag const &wrongTag, void *userData) TagErrorCallback
Callback for a tag error.
Definition tagTapeBase.hpp:87
inlinevoid checkLhsError(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, Real const &rhs) const
Check if the lhs value is changed.
Definition tagTapeBase.hpp:422
void setTagErrorCallback(TagErrorCallback const &callback, void *userData)
Set the callback and user data for a tag error.
Definition tagTapeBase.hpp:318
inlinevoid handleError(ValidationIndicator< Real, Tag > &vi) const
Call tag error callback.
Definition tagTapeBase.hpp:427
T_Tag Tag
See TagTapeBase.
Definition tagTapeBase.hpp:75
inlinevoid verifyTag(ValidationIndicator< Real, Tag > &vi, Tag const &tag) const
Checks if the tag is correct. Errors are set on the ValidationIndicator object.
Definition tagTapeBase.hpp:347
inlinevoid checkLhsError(Real &lhsValue, ActiveTypeTapeData &lhsData, const Real &rhs) const
Check if a property for the lhs value is triggered.
Definition tagTapeBase.hpp:410
void setTagOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > const &value)
Set tag on a CoDiPack active type.
Definition tagTapeBase.hpp:283
inlinebool isPreaccumulationHandlingEnabled()
If handling for preaccumulation is enabled.
Definition tagTapeBase.hpp:335
inlineIdentifier const & getIdentifier(ActiveTypeTapeData const &data)
Definition tagTapeBase.hpp:150
TagTapeBase()
Constructor.
Definition tagTapeBase.hpp:112
Tag getTagFromVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Get tag of a CoDiPack active type.
Definition tagTapeBase.hpp:277
inlinevoid setPreaccumulationHandlingTag(Tag tag)
Set the special tag for preaccumulation regions. See setPreaccumulationHandlingEnabled().
Definition tagTapeBase.hpp:330
static void defaultPropertyErrorCallback(Real const &currentValue, Real const &newValue, TagFlags flag, void *userData)
Definition tagTapeBase.hpp:387
inlinevoid verifyProperties(ValidationIndicator< Real, Tag > &vi, Real const &value, const EnumBitset< TagFlags > &properties) const
Checks if the tag properties are correct.
Definition tagTapeBase.hpp:367
T_Real Real
See TagTapeBase.
Definition tagTapeBase.hpp:74
inlinevoid resetTag(Tag &tag) const
Reset tag on value.
Definition tagTapeBase.hpp:457
void clearTagPropertiesOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Clear properties on a CoDiPack active type.
Definition tagTapeBase.hpp:295
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, LhsExpressionInterface< Real, Gradient, Impl, Rhs > const &rhs)
Verify all tags of the rhs and the lhs properties.
Definition tagTapeBase.hpp:245
TagPropertyErrorCallback tagPropertyErrorCallback
Definition tagTapeBase.hpp:96
inlinevoid setPreaccumulationHandlingEnabled(bool enabled)
Enable or disable specialized handling for preaccumulation. Default: true Uses a special tag to sanit...
Definition tagTapeBase.hpp:325
Identifier const activeIdentifier
Definition tagTapeBase.hpp:106
inlinevoid store(AggregatedActiveType< Aggregated, Type, Lhs > &lhs, AggregatedActiveType< Aggregated, Type, Rhs > const &rhs)
Has to be called by an AD variable every time it is assigned.
Definition tagTapeBase.hpp:217
static Tag constexpr PassiveTag
Definition tagTapeBase.hpp:89
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, Real const &rhs)
Verify the lhs properties.
Definition tagTapeBase.hpp:252
Identifier const passiveIdentifier
Definition tagTapeBase.hpp:107
void setTagPropertyErrorCallback(TagPropertyErrorCallback const &callback, void *userData)
Set the callback and user data for a property error error.
Definition tagTapeBase.hpp:312
T_Gradient Gradient
See TagTapeBase.
Definition tagTapeBase.hpp:76
int Identifier
See TapeTypesInterface.
Definition tagTapeBase.hpp:79
static void defaultTagErrorCallback(Tag const &correctTag, Tag const &wrongTag, void *userData)
Definition tagTapeBase.hpp:396
void initTapeData(Real &value, ActiveTypeTapeData &data)
Do nothing.
Definition tagTapeBase.hpp:173
inlinevoid verifyTag(Tag const &tag) const
Checks if the tag is correct and creates an error.
Definition tagTapeBase.hpp:359
static Tag constexpr InvalidTag
Definition tagTapeBase.hpp:90
Tag getCurTag()
Get the current tag of the tape.
Definition tagTapeBase.hpp:271
TagData< Tag > ActiveTypeTapeData
See TapeTypesInterface.
Definition tagTapeBase.hpp:80
inlineIdentifier & getIdentifier(ActiveTypeTapeData &data)
Definition tagTapeBase.hpp:159
bool hasTagPropertyOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value, TagFlags flag)
Check properties on a CoDiPack active type.
Definition tagTapeBase.hpp:307
void setCurTag(const Tag &tag)
Set the current tag of the tape.
Definition tagTapeBase.hpp:266
inlinevoid verifyRegisterValue(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value, ActiveTypeTapeData const &tag)
Verify tag, properties and lhs error.
Definition tagTapeBase.hpp:440
inlinevoid verifyTagAndProperties(Tag const &tag, Real const &value, const EnumBitset< TagFlags > &properties) const
Checks if the tag and the properties are correct.
Definition tagTapeBase.hpp:377
void swap(Impl &other)
Swap members.
Definition tagTapeBase.hpp:135
void(*)(Real const &currentValue, Real const &newValue, TagFlags flag, void *userData) TagPropertyErrorCallback
Callback for a change in a lhs value.
Definition tagTapeBase.hpp:83
inlinevoid node(Node const &node, Args &&... args)
Definition traversalLogic.hpp:87
Helper class for statement validation.
Definition tagTapeBase.hpp:49
bool hasError
true if an error is detected.
Definition tagTapeBase.hpp:51
Tag errorTag
Value of the wrong tag.
Definition tagTapeBase.hpp:54
ValidationIndicator()
Constructor.
Definition tagTapeBase.hpp:58
Real value
Primal value of the value with the tag error.
Definition tagTapeBase.hpp:55
bool hasUseError
true if a value is used in the wrong way.
Definition tagTapeBase.hpp:53
bool isActive
true if an active rhs is detected. tag != 0
Definition tagTapeBase.hpp:50
bool hasTagError
true if a tag not the current required tag.
Definition tagTapeBase.hpp:52