CoDiPack  3.1.1
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), RPTU University 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, RPTU University 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, RPTU University 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 "../../expressions/aggregate/aggregatedActiveType.hpp"
39#include "../../misc/enumBitset.hpp"
40#include "../indices/indexManagerInterface.hpp"
41#include "../interfaces/fullTapeInterface.hpp"
42#include "../misc/adjointVectorAccess.hpp"
43#include "tagData.hpp"
44
46namespace codi {
47
49 template<typename Real, typename Tag>
58
60 template<typename Real, typename Tag>
63 std::vector<ValidationEntry<Real, Tag>> errorEntries = {};
64
67 errorEntries.push_back(entry);
68 }
69
71 void reset() {
72 errorEntries.resize(0);
73 }
74
76 bool hasError() {
77 return !errorEntries.empty();
78 }
79 };
80
91 template<typename T_Real, typename T_Tag, typename T_Gradient, typename T_Impl>
92 struct TagTapeBase {
93 using Real = CODI_DD(T_Real, double);
94 using Tag = CODI_DD(T_Tag, int);
95 using Gradient = CODI_DD(T_Gradient, int);
96 using Impl = CODI_DD(T_Impl, TagTapeBase);
97
98 using Identifier = int;
100
102 using TagPropertyErrorCallback = void (*)(Real const& currentValue, Real const& newValue, TagFlags flag,
103 void* userData);
104
106 using TagErrorCallback = void (*)(Tag const& correctTag, Tag const& wrongTag, void* userData);
107
109 using ErrorCallback = void (*)(ValidationEntry<Real, Tag> const& data, Tag const& curTag, void* userData);
110
111 static Tag constexpr PassiveTag = Tag(0);
112 static Tag constexpr InvalidTag = Tag(-1);
113
114 protected:
115
117
120
123
126
129
133
135 bool doActivityAnalysis = true;
136
137 public:
138
150
152 struct ValidateTags : public ForEachLeafLogic<ValidateTags> {
153 public:
154
156 template<typename Node>
157 CODI_INLINE void handleActive(Node const& node, ValidationIndicator<Real, Tag>& vi, Impl& tape, bool& isActive) {
158 ActiveTypeTapeData tagData = node.getTapeData();
159
160 tape.verifyRhsAccess(node.getValue(), tagData, vi);
161
162 isActive |= tagData.tag != 0;
163 }
164 };
165
167 void swap(Impl& other) {
168 std::swap(curTag, other.curTag);
169 std::swap(tagPropertyErrorCallback, other.tagPropertyErrorCallback);
170 std::swap(tagPropertyErrorUserData, other.tagPropertyErrorUserData);
171 std::swap(tagErrorCallback, other.tagErrorCallback);
172 std::swap(tagErrorUserData, other.tagErrorUserData);
173 std::swap(preaccumulationHandling, other.preaccumulationHandling);
174 std::swap(preaccumulationTag, other.preaccumulationTag);
175 std::swap(vi, other.vi);
176 std::swap(doActivityAnalysis, other.doActivityAnalysis);
177 }
178
179 /*******************************************************************************/
182
185 if (data.tag != 0) {
186 return activeIdentifier;
187 } else {
188 return passiveIdentifier;
189 }
190 }
191
197
199 /*******************************************************************************/
202
203 static bool constexpr AllowJacobianOptimization = false;
204
206 template<typename Real>
208 CODI_UNUSED(value);
209 data = ActiveTypeTapeData();
210 }
211
213 template<typename Real>
215 CODI_UNUSED(value, data);
216 }
217
219 template<typename Aggregated, typename Type, typename Lhs, typename Rhs>
222 using AggregatedTraits = RealTraits::AggregatedTypeTraits<Aggregated>;
223
224 int constexpr Elements = AggregatedTraits::Elements;
225
226 std::array<bool, Elements> isActive = {};
227
228 Aggregated real = rhs.cast().getValue();
229
230 static_for<Elements>([this, &isActive, &lhs, &rhs, &real](auto i) CODI_LAMBDA_INLINE {
231 ValidateTags validate;
232
233 validate.eval(ArrayAccessExpression<Aggregated, i.value, Rhs>(rhs), vi, cast(), isActive[i.value]);
234 verifyLhsWrite(lhs.values[i.value].getValue(), lhs.values[i.value].getTapeData(), AggregatedTraits::template arrayAccess<i.value>(real), vi);
235
237 });
238
239 static_for<Elements>([this, &isActive, &lhs, &real](auto i) CODI_LAMBDA_INLINE {
240 updateLhsTagData(lhs.values[i.value].getTapeData(), isActive[i.value]);
241 lhs.values[i.value].value() = AggregatedTraits::template arrayAccess<i.value>(real);
242 });
243 }
244
247 template<typename Aggregated, typename Type, typename Lhs, typename Rhs>
252
254 template<typename Lhs, typename Rhs>
256 ValidateTags validate;
257 bool isActive = false;
258 validate.eval(rhs, vi, cast(), isActive);
259
260 verifyLhsWrite(lhs.cast().getValue(), lhs.cast().getTapeData(), rhs.cast().getValue(), vi);
261
263
264 updateLhsTagData(lhs.cast().getTapeData(), isActive);
265 lhs.cast().value() = rhs.cast().getValue();
266 }
267
269 template<typename Lhs, typename Rhs>
274
276 template<typename Lhs>
278 verifyLhsWrite(lhs.cast().getValue(), lhs.cast().getTapeData(), rhs, vi);
280
281 updateLhsTagData(lhs.cast().getTapeData(), false);
282 lhs.cast().value() = rhs;
283 }
284
286 /*******************************************************************************/
289
291 void setDoActivityAnalysis(bool active) {
292 doActivityAnalysis = active;
293 }
294
296 void setCurTag(const Tag& tag) {
297 this->curTag = tag;
298 }
299
302 return this->curTag;
303 }
304
306 template<typename Lhs>
308 return value.cast().getTapeData().tag;
309 }
310
312 template<typename Lhs>
314 value.cast().getTapeData().tag = this->curTag;
315 }
316
318 template<typename Lhs>
320 value.cast().getTapeData().tag = Tag();
321 }
322
324 template<typename Lhs>
326 value.cast().getTapeData().properties.reset();
327 }
328
330 template<typename Lhs>
332 value.cast().getTapeData().properties.set(flag);
333 }
334
336 template<typename Lhs>
338 return value.cast().getTapeData().properties.test(flag);
339 }
340
342 void setTagPropertyErrorCallback(TagPropertyErrorCallback const& callback, void* userData) {
343 tagPropertyErrorCallback = callback;
344 tagPropertyErrorUserData = userData;
345 }
346
348 void setTagErrorCallback(TagErrorCallback const& callback, void* userData) {
349 tagErrorCallback = callback;
350 tagErrorUserData = userData;
351 }
352
355 void setErrorCallback(ErrorCallback const& callback, void* userData) {
356 errorCallback = callback;
357 errorUserData = userData;
358 }
359
365
370
375
380
381 protected:
382
385 return {true, false, tag, TagFlags::MaxElement, value, Real()};
386 }
387
389 ValidationEntry<Real, Tag> makeProeprtyError(TagFlags flag, Real const* value, Real newValue = {}) {
390 return {false, true, 0, flag, value, newValue};
391 }
392
394 void updateLhsTagData(ActiveTypeTapeData& lhsData, bool isActive) const {
395 if (!doActivityAnalysis || isActive) {
396 setTag(lhsData.tag);
397 } else {
398 resetTag(lhsData.tag);
399 }
400 lhsData.properties.reset(TagFlags::DoNotUse);
401 }
402
405 verifyRhsAccessForTag(value, data, vi);
406 verifyRhsAccessForProperty(value, data, vi);
407 }
408
411 if (PassiveTag != data.tag && InvalidTag != data.tag) {
412 if (data.tag != curTag) {
413 vi.addEntry(makeTagError(data.tag, &value));
414 }
415 }
416 }
417
420 if (data.properties.test(TagFlags::DoNotUse)) {
421 vi.addEntry(makeProeprtyError(TagFlags::DoNotUse, &value));
422 }
423 }
424
426 CODI_INLINE void verifyLhsWrite(Real const& lhsValue, ActiveTypeTapeData const& lhsData, Real const& rhsValue, ValidationIndicator<Real, Tag>& vi) {
427 if (lhsData.properties.test(TagFlags::DoNotChange)) {
428 if (lhsValue != rhsValue) {
429 vi.addEntry(makeProeprtyError(TagFlags::DoNotChange, &lhsValue, rhsValue));
430 }
431 } else if (lhsData.properties.test(TagFlags::DoNotWrite)) {
432 vi.addEntry(makeProeprtyError(TagFlags::DoNotWrite, &lhsValue));
433 }
434 }
435
437 template<typename Lhs>
439 verifyRhsAccess(value.cast().getValue(), value.cast().getTapeData(), vi);
440 verifyLhsWrite(value.cast().getValue(), value.cast().getTapeData(), value.cast().getValue(), vi);
441
443 }
444
446 static void defaultPropertyErrorCallback(Real const& currentValue, Real const& newValue, TagFlags flag,
447 void* userData) {
448 CODI_UNUSED(userData);
449
450 std::cerr << "Property error '" << std::to_string(flag) << "' on value. current value: " << currentValue
451 << " new value: " << newValue << "" << std::endl;
452 }
453
455 static void defaultTagErrorCallback(Tag const& correctTag, Tag const& wrongTag, void* userData) {
456 TagTapeBase& impl = *static_cast<TagTapeBase*>(userData);
457
458 // output default warning if no handle is defined.
459 std::cerr << "Use of variable with bad tag '" << wrongTag << "', should be '" << correctTag << "'.";
460 if (wrongTag == impl.preaccumulationTag) {
461 std::cerr << " The value seems to be a preaccumulation output.";
462 } else if (correctTag == impl.preaccumulationTag) {
463 std::cerr << " The value seems to be used during a preaccumulation but is not declared as an input.";
464 }
465 std::cerr << std::endl;
466 }
467
469 static void defaultErrorCallback(ValidationEntry<Real, Tag> const& data, Tag const& curTag, void* userData) {
470 if (data.isTagError) {
471 defaultTagErrorCallback(curTag, data.tagError, userData);
472 }
473 if (data.isPropertyError) {
474 defaultPropertyErrorCallback(*data.value, data.newValue, data.propertyError, userData);
475 }
476 }
477
480 if (vi.hasError()) {
481 for(ValidationEntry<Real, Tag> const& entry : vi.errorEntries) {
482 if(nullptr != errorCallback) {
484 } else {
485 if (entry.isTagError) {
487 }
488 if (entry.isPropertyError) {
490 }
491 }
492 }
493 }
494
495 vi.reset();
496 }
497
499 CODI_INLINE void setTag(Tag& tag) const {
500 tag = curTag;
501 }
502
504 CODI_INLINE void resetTag(Tag& tag) const {
505 tag = Tag();
506 }
507
508
509 private:
511 CODI_INLINE Impl& cast() {
512 return static_cast<Impl&>(*this);
513 }
514 };
515}
#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:98
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
@ MaxElement
Maximum number of elements.
Definition tagData.hpp:51
InnerActiveType values[Elements]
Array representation.
Definition aggregatedActiveType.hpp:75
Represents a concrete aggregated lvalue int the CoDiPack expression tree.
Definition aggregatedActiveType.hpp:164
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
Tag tag
Current tag of the value.
Definition tagData.hpp:61
Looks at the tags for the expression.
Definition tagTapeBase.hpp:152
inlinevoid handleActive(Node const &node, ValidationIndicator< Real, Tag > &vi, Impl &tape, bool &isActive)
Called for leaf nodes which implement LhsExpressionInterface.
Definition tagTapeBase.hpp:157
void setTagPropertyOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value, TagFlags flag)
Set properties on a CoDiPack active type.
Definition tagTapeBase.hpp:331
inlinevoid setTag(Tag &tag) const
Set tag on value.
Definition tagTapeBase.hpp:499
inlineTag getPreaccumulationHandlingTag()
The special tag for preaccumulation.
Definition tagTapeBase.hpp:377
ValidationEntry< Real, Tag > makeProeprtyError(TagFlags flag, Real const *value, Real newValue={})
Create a property error entry.
Definition tagTapeBase.hpp:389
void clearTagOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Clear tag on a CoDiPack active type.
Definition tagTapeBase.hpp:319
static bool constexpr AllowJacobianOptimization
Definition tagTapeBase.hpp:203
ValidationIndicator< Real, Tag > vi
Definition tagTapeBase.hpp:134
static void defaultErrorCallback(ValidationEntry< Real, Tag > const &data, Tag const &curTag, void *userData)
Default callback for ErrorCallback. (Currently not used)
Definition tagTapeBase.hpp:469
TagErrorCallback tagErrorCallback
Definition tagTapeBase.hpp:121
void destroyTapeData(Real &value, ActiveTypeTapeData &data)
Do nothing.
Definition tagTapeBase.hpp:214
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, ExpressionInterface< Real, Rhs > const &rhs)
Verify all tags of the rhs and properties from the lhs and rhs.
Definition tagTapeBase.hpp:255
T_Impl Impl
See TagTapeBase.
Definition tagTapeBase.hpp:96
void(*)(Tag const &correctTag, Tag const &wrongTag, void *userData) TagErrorCallback
Callback for a tag error.
Definition tagTapeBase.hpp:106
Tag curTag
Current tag for new values.
Definition tagTapeBase.hpp:116
void(*)(ValidationEntry< Real, Tag > const &data, Tag const &curTag, void *userData) ErrorCallback
Callback for all errors.
Definition tagTapeBase.hpp:109
void setTagErrorCallback(TagErrorCallback const &callback, void *userData)
Set the callback and user data for a tag error.
Definition tagTapeBase.hpp:348
inlinevoid handleError(ValidationIndicator< Real, Tag > &vi) const
Call tag error callback.
Definition tagTapeBase.hpp:479
T_Tag Tag
See TagTapeBase.
Definition tagTapeBase.hpp:94
void setTagOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > const &value)
Set tag on a CoDiPack active type.
Definition tagTapeBase.hpp:313
inlinevoid verifyRegisterValue(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Verify tag, properties and lhs error.
Definition tagTapeBase.hpp:438
inlinebool isPreaccumulationHandlingEnabled()
If handling for preaccumulation is enabled.
Definition tagTapeBase.hpp:372
inlineIdentifier const & getIdentifier(ActiveTypeTapeData const &data)
Definition tagTapeBase.hpp:184
TagTapeBase()
Constructor.
Definition tagTapeBase.hpp:140
Tag getTagFromVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Get tag of a CoDiPack active type.
Definition tagTapeBase.hpp:307
inlinevoid setPreaccumulationHandlingTag(Tag tag)
Set the special tag for preaccumulation regions. See setPreaccumulationHandlingEnabled().
Definition tagTapeBase.hpp:367
static void defaultPropertyErrorCallback(Real const &currentValue, Real const &newValue, TagFlags flag, void *userData)
Definition tagTapeBase.hpp:446
T_Real Real
See TagTapeBase.
Definition tagTapeBase.hpp:93
inlinevoid resetTag(Tag &tag) const
Reset tag on value.
Definition tagTapeBase.hpp:504
void clearTagPropertiesOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Clear properties on a CoDiPack active type.
Definition tagTapeBase.hpp:325
ValidationEntry< Real, Tag > makeTagError(Tag tag, Real const *value)
Create a tag error entry.
Definition tagTapeBase.hpp:384
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:270
TagPropertyErrorCallback tagPropertyErrorCallback
Definition tagTapeBase.hpp:118
void verifyRhsAccessForTag(Real const &value, ActiveTypeTapeData const &data, ValidationIndicator< Real, Tag > &vi)
Check tag errors. Raises an error for tags that are not equal to the current tag. Ignores passive tag...
Definition tagTapeBase.hpp:410
inlinevoid setPreaccumulationHandlingEnabled(bool enabled)
Enable or disable specialized handling for preaccumulation. Default: true Uses a special tag to sanit...
Definition tagTapeBase.hpp:362
Identifier const activeIdentifier
Definition tagTapeBase.hpp:131
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:248
static Tag constexpr PassiveTag
Definition tagTapeBase.hpp:111
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, Real const &rhs)
Verify the lhs properties.
Definition tagTapeBase.hpp:277
Identifier const passiveIdentifier
Definition tagTapeBase.hpp:132
void setTagPropertyErrorCallback(TagPropertyErrorCallback const &callback, void *userData)
Set the callback and user data for a property error error.
Definition tagTapeBase.hpp:342
T_Gradient Gradient
See TagTapeBase.
Definition tagTapeBase.hpp:95
ErrorCallback errorCallback
Definition tagTapeBase.hpp:124
int Identifier
See TapeTypesInterface.
Definition tagTapeBase.hpp:98
static void defaultTagErrorCallback(Tag const &correctTag, Tag const &wrongTag, void *userData)
Definition tagTapeBase.hpp:455
void setErrorCallback(ErrorCallback const &callback, void *userData)
Definition tagTapeBase.hpp:355
void setDoActivityAnalysis(bool active)
Enable or disable the activity analysis for the tags. Disabling will mark all active types with the c...
Definition tagTapeBase.hpp:291
void initTapeData(Real &value, ActiveTypeTapeData &data)
Do nothing.
Definition tagTapeBase.hpp:207
void verifyRhsAccessForProperty(Real const &value, ActiveTypeTapeData const &data, ValidationIndicator< Real, Tag > &vi)
Check properties for rhs values. Validates the 'DoNotUse' property.
Definition tagTapeBase.hpp:419
static Tag constexpr InvalidTag
Definition tagTapeBase.hpp:112
Tag getCurTag()
Get the current tag of the tape.
Definition tagTapeBase.hpp:301
TagData< Tag > ActiveTypeTapeData
See TapeTypesInterface.
Definition tagTapeBase.hpp:99
inlineIdentifier & getIdentifier(ActiveTypeTapeData &data)
Definition tagTapeBase.hpp:193
bool hasTagPropertyOnVariable(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value, TagFlags flag)
Check properties on a CoDiPack active type.
Definition tagTapeBase.hpp:337
void updateLhsTagData(ActiveTypeTapeData &lhsData, bool isActive) const
Update the tag data for a lhs write. Updates the properties and sets the tag based on the activity.
Definition tagTapeBase.hpp:394
inlinevoid store(AggregatedActiveType< Aggregated, Type, Lhs > &lhs, ExpressionInterface< Aggregated, Rhs > const &rhs)
Verify all tags of the rhs and properties from the lhs and rhs.
Definition tagTapeBase.hpp:220
void setCurTag(const Tag &tag)
Set the current tag of the tape.
Definition tagTapeBase.hpp:296
inlinevoid verifyLhsWrite(Real const &lhsValue, ActiveTypeTapeData const &lhsData, Real const &rhsValue, ValidationIndicator< Real, Tag > &vi)
Validates the lhs properties.
Definition tagTapeBase.hpp:426
void verifyRhsAccess(Real const &value, ActiveTypeTapeData const &data, ValidationIndicator< Real, Tag > &vi)
Check tag and property errors.
Definition tagTapeBase.hpp:404
void swap(Impl &other)
Swap members.
Definition tagTapeBase.hpp:167
void(*)(Real const &currentValue, Real const &newValue, TagFlags flag, void *userData) TagPropertyErrorCallback
Callback for a change in a lhs value.
Definition tagTapeBase.hpp:102
inlinevoid node(Node const &node, Args &&... args)
Definition traversalLogic.hpp:87
Helper class for statement validation.
Definition tagTapeBase.hpp:50
TagFlags propertyError
Wrong property.
Definition tagTapeBase.hpp:54
Real newValue
New value for property errors.
Definition tagTapeBase.hpp:56
Tag tagError
Wrong tag.
Definition tagTapeBase.hpp:53
Real const * value
Address of the offending value.
Definition tagTapeBase.hpp:55
bool isTagError
true if the tag on the value is wrong.
Definition tagTapeBase.hpp:51
bool isPropertyError
true if a property on the value is wrong.
Definition tagTapeBase.hpp:52
Helper class for statement validation.
Definition tagTapeBase.hpp:61
bool hasError()
Test if there is an error.
Definition tagTapeBase.hpp:76
void reset()
Clear all errors.
Definition tagTapeBase.hpp:71
std::vector< ValidationEntry< Real, Tag > > errorEntries
Stores all problematic entries.
Definition tagTapeBase.hpp:63
void addEntry(ValidationEntry< Real, Tag > const &entry)
Add a new entry.
Definition tagTapeBase.hpp:66