CoDiPack  2.2.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
jacobianBaseTape.hpp
1/*
2 * CoDiPack, a Code Differentiation Package
3 *
4 * Copyright (C) 2015-2024 Chair for Scientific Computing (SciComp), University of Kaiserslautern-Landau
5 * Homepage: http://www.scicomp.uni-kl.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://www.scicomp.uni-kl.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 <cmath>
39#include <type_traits>
40
41#include "../config.h"
42#include "../expressions/lhsExpressionInterface.hpp"
43#include "../expressions/logic/compileTimeTraversalLogic.hpp"
44#include "../expressions/logic/helpers/forEachLeafLogic.hpp"
45#include "../expressions/logic/helpers/jacobianComputationLogic.hpp"
46#include "../expressions/logic/traversalLogic.hpp"
47#include "../expressions/referenceActiveType.hpp"
48#include "../misc/macros.hpp"
49#include "../misc/mathUtility.hpp"
50#include "../misc/memberStore.hpp"
51#include "../traits/computationTraits.hpp"
52#include "../traits/expressionTraits.hpp"
53#include "commonTapeImplementation.hpp"
54#include "data/chunk.hpp"
55#include "data/chunkedData.hpp"
56#include "indices/indexManagerInterface.hpp"
57#include "misc/adjointVectorAccess.hpp"
58#include "misc/duplicateJacobianRemover.hpp"
59#include "misc/localAdjoints.hpp"
60
62namespace codi {
63
73 template<typename T_Real, typename T_Gradient, typename T_IndexManager, template<typename, typename> class T_Data,
74 template<typename, typename, typename> class T_Adjoints = LocalAdjoints>
76 public:
77
78 using Real = CODI_DD(T_Real, double);
79 using Gradient = CODI_DD(T_Gradient, double);
81 template<typename Chunk, typename Nested>
82 using Data = CODI_DD(CODI_T(T_Data<Chunk, Nested>),
84
85 using Identifier = typename IndexManager::Index;
86
88 template<typename Impl>
89 using Adjoints = CODI_DD(CODI_T(T_Adjoints<Gradient, Identifier, Impl>),
91
92 static bool constexpr IsLinearIndexHandler = IndexManager::IsLinear;
93 static bool constexpr IsStaticIndexHandler =
94 IndexManager::NeedsStaticStorage;
95
98 using StatementChunk = typename std::conditional<IsLinearIndexHandler, Chunk1<Config::ArgumentSize>,
101
104
106 };
107
124 template<typename T_TapeTypes, typename T_Impl>
125 struct JacobianBaseTape : public CommonTapeImplementation<T_TapeTypes, T_Impl> {
126 public:
127
131 using Impl = CODI_DD(T_Impl, CODI_DEFAULT_TAPE);
132
134 friend Base;
135
136 using Real = typename TapeTypes::Real;
137 using Gradient = typename TapeTypes::Gradient;
138 using IndexManager = typename TapeTypes::IndexManager;
139 using Identifier = typename TapeTypes::Identifier;
140
141 using StatementData = typename TapeTypes::StatementData;
142 using JacobianData = typename TapeTypes::JacobianData;
143
144 using Adjoints = typename TapeTypes::template Adjoints<Impl>;
145
147
148 using NestedPosition = typename JacobianData::Position;
149 using Position = typename Base::Position;
150
151 template<typename Adjoint>
154
155 static bool constexpr AllowJacobianOptimization = true;
156 static bool constexpr HasPrimalValues = false;
157
158 static bool constexpr LinearIndexHandling =
159 TapeTypes::IsLinearIndexHandler;
160 static bool constexpr RequiresPrimalRestore = false;
161
162 protected:
163
164#if CODI_RemoveDuplicateJacobianArguments
167#endif
168
172
174
175 private:
176
177 CODI_INLINE Impl const& cast() const {
178 return static_cast<Impl const&>(*this);
179 }
180
181 CODI_INLINE Impl& cast() {
182 return static_cast<Impl&>(*this);
183 }
184
185 protected:
186
187 /*******************************************************************************/
190
192 template<typename... Args>
193 static void internalEvaluateForward_EvalStatements(Args&&... args);
194
196 template<typename... Args>
197 static void internalEvaluateReverse_EvalStatements(Args&&... args);
198
200 void pushStmtData(Identifier const& index, Config::ArgumentSize const& numberOfArguments);
201
203
204 public:
205
208 : Base(),
210 jacobianSorter(),
211#endif
212 indexManager(0), // Reserve the zero index.
213 statementData(Config::ChunkSize),
214 jacobianData(std::max(Config::ChunkSize, Config::MaxArgumentSize)), // Chunk must be large enough to store
215 // data for all arguments of one
216 // statement.
217 adjoints(1) // Ensure that adjoint[0] exists, see its use in gradient() const.
218
219 {
220 statementData.setNested(&indexManager.get());
221 jacobianData.setNested(&statementData);
222
224
229 }
230
231 /*******************************************************************************/
234
238 if (AdjointsManagement::Automatic == adjointsManagement) {
239 checkAdjointSize(identifier);
240 }
241
242 codiAssert(identifier < (Identifier)adjoints.size());
243
244 return adjoints[identifier];
245 }
246
249 Identifier const& identifier, AdjointsManagement adjointsManagement = AdjointsManagement::Automatic) const {
250 codiAssert(identifier < (Identifier)adjoints.size());
251
252 if (AdjointsManagement::Automatic == adjointsManagement && identifier >= (Identifier)adjoints.size()) {
253 return adjoints[0];
254 } else {
255 return adjoints[identifier];
256 }
257 }
258
260 /*******************************************************************************/
263
265 template<typename Real>
266 CODI_INLINE void initIdentifier(Real& value, Identifier& identifier) {
267 CODI_UNUSED(value);
268
269 identifier = IndexManager::InactiveIndex;
270 }
271
273 template<typename Real>
274 CODI_INLINE void destroyIdentifier(Real& value, Identifier& identifier) {
275 CODI_UNUSED(value);
276
277 indexManager.get().template freeIndex<Impl>(identifier);
278 }
279
281
282 protected:
283
285 struct PushJacobianLogic : public JacobianComputationLogic<PushJacobianLogic> {
286 public:
288 template<typename Node, typename Jacobian, typename DataVector>
289 CODI_INLINE void handleJacobianOnActive(Node const& node, Jacobian jacobianExpr, DataVector& dataVector) {
290 Real jacobian = ComputationTraits::adjointConversion<Real>(jacobianExpr);
291
292 if (CODI_ENABLE_CHECK(Config::CheckZeroIndex, 0 != node.getIdentifier())) {
295 dataVector.pushData(jacobian, node.getIdentifier());
296 }
297 }
298 }
299 }
300
302 template<typename Type, typename Jacobian, typename DataVector>
304 DataVector& dataVector) {
305 CODI_UNUSED(dataVector);
306
307 Real jacobian = ComputationTraits::adjointConversion<Real>(jacobianExpr);
308
310 // Do a delayed push for these leaf nodes, accumulate the jacobian in the local member.
311 node.jacobian += jacobian;
312 }
313 }
314 };
315
317 struct PushDelayedJacobianLogic : public ForEachLeafLogic<PushDelayedJacobianLogic> {
318 public:
319
321 template<typename Type, typename DataVector>
322 CODI_INLINE void handleActive(ReferenceActiveType<Type> const& node, DataVector& dataVector) {
323 if (CODI_ENABLE_CHECK(Config::CheckZeroIndex, 0 != node.getIdentifier())) {
325 dataVector.pushData(node.jacobian, node.getIdentifier());
326
327 // Reset the jacobian here such that it is not pushed multiple times and ready for the next store.
328 node.jacobian = Real();
329 }
330 }
331 }
332
334 };
335
337 template<typename Rhs>
339 PushJacobianLogic pushJacobianLogic;
340 PushDelayedJacobianLogic pushDelayedJacobianLogic;
341
342#if CODI_RemoveDuplicateJacobianArguments
343 auto& insertVector = jacobianSorter;
344#else
345 auto& insertVector = jacobianData;
346#endif
347
348 pushJacobianLogic.eval(rhs.cast(), Real(1.0), insertVector);
349 pushDelayedJacobianLogic.eval(rhs.cast(), insertVector);
350
351#if CODI_RemoveDuplicateJacobianArguments
352 jacobianSorter.storeData(jacobianData);
353#endif
354 }
355
356 public:
357
359
361 template<typename Lhs, typename Rhs>
366
368
369 statementData.reserveItems(1);
370 typename JacobianData::InternalPosHandle jacobianStart = jacobianData.reserveItems(MaxArgs);
371
372 pushJacobians(rhs);
373
374 size_t numberOfArguments = jacobianData.getPushedDataCount(jacobianStart);
375 if (CODI_ENABLE_CHECK(Config::CheckEmptyStatements, 0 != numberOfArguments)) {
376 indexManager.get().template assignIndex<Impl>(lhs.cast().getIdentifier());
377 cast().pushStmtData(lhs.cast().getIdentifier(), (Config::ArgumentSize)numberOfArguments);
378
380 Real* jacobians;
381 Identifier* rhsIdentifiers;
382 jacobianData.getDataPointers(jacobians, rhsIdentifiers);
383 jacobians -= numberOfArguments;
384 rhsIdentifiers -= numberOfArguments;
385
387 rhs.cast().getValue(), numberOfArguments,
388 rhsIdentifiers, jacobians);
389 }
390 } else {
391 indexManager.get().template freeIndex<Impl>(lhs.cast().getIdentifier());
392 }
393 } else {
394 indexManager.get().template freeIndex<Impl>(lhs.cast().getIdentifier());
395 }
396
397 lhs.cast().value() = rhs.cast().getValue();
398 }
399
402 template<typename Lhs, typename Rhs>
406 if (IndexManager::CopyNeedsStatement || !Config::CopyOptimization) {
407 store<Lhs, Rhs>(lhs, static_cast<ExpressionInterface<Real, Rhs> const&>(rhs));
408 return;
409 } else {
410 indexManager.get().template copyIndex<Impl>(lhs.cast().getIdentifier(), rhs.cast().getIdentifier());
411 }
412 } else {
413 indexManager.get().template freeIndex<Impl>(lhs.cast().getIdentifier());
414 }
415
416 lhs.cast().value() = rhs.cast().getValue();
417 }
418
421 template<typename Lhs>
423 indexManager.get().template freeIndex<Impl>(lhs.cast().getIdentifier());
424
425 lhs.cast().value() = rhs;
426 }
427
429 /*******************************************************************************
430 * Protected helper function for ReverseTapeInterface
431 */
432
433 protected:
434
436 template<typename Lhs>
438 bool unusedIndex) {
439 if (TapeTypes::IsLinearIndexHandler) {
440 statementData.reserveItems(1);
441 }
442
443 if (unusedIndex) {
444 indexManager.get().template assignUnusedIndex<Impl>(value.cast().getIdentifier());
445 } else {
446 indexManager.get().template assignIndex<Impl>(value.cast().getIdentifier());
447 }
448
449 if (TapeTypes::IsLinearIndexHandler) {
450 cast().pushStmtData(value.cast().getIdentifier(), Config::StatementInputTag);
451 }
452 }
453
454 public:
455
456 /*******************************************************************************/
459
461 template<typename Lhs>
463 cast().internalRegisterInput(value, true);
464 EventSystem<Impl>::notifyTapeRegisterInputListeners(cast(), value.cast().value(), value.cast().getIdentifier());
465 }
466
469 if (AdjointsManagement::Automatic == adjointsManagement) {
470 adjoints.beginUse();
471 }
472
473 adjoints.zeroAll();
474
475 if (AdjointsManagement::Automatic == adjointsManagement) {
476 adjoints.endUse();
477 }
478 }
479
481
482 protected:
483
486 std::string name;
487 if (TapeTypes::IsLinearIndexHandler) {
488 name = "CoDi Tape Statistics ( JacobianLinearTape )";
489 } else {
490 name = "CoDi Tape Statistics ( JacobianReuseTape )";
491 }
492 TapeValues values = TapeValues(name);
493
494 size_t nAdjoints = indexManager.get().getLargestCreatedIndex();
495 double memoryAdjoints = static_cast<double>(nAdjoints) * static_cast<double>(sizeof(Gradient));
496
497 values.addSection("Adjoint vector");
498 values.addUnsignedLongEntry("Number of adjoints", nAdjoints);
499 values.addDoubleEntry("Memory allocated", memoryAdjoints, true, true);
500
501 values.addSection("Index manager");
502 indexManager.get().addToTapeValues(values);
503
504 values.addSection("Statement entries");
505 statementData.addToTapeValues(values);
506 values.addSection("Jacobian entries");
507 jacobianData.addToTapeValues(values);
508
509 return values;
510 }
511
512 /******************************************************************************
513 * Protected helper function for CustomAdjointVectorEvaluationTapeInterface
514 */
515
516 protected:
517
519 template<typename Adjoint>
520 CODI_INLINE static void incrementAdjoints(Adjoint* adjointVector, Adjoint const& lhsAdjoint,
521 Config::ArgumentSize const& numberOfArguments, size_t& curJacobianPos,
522 Real const* const rhsJacobians,
523 Identifier const* const rhsIdentifiers) {
524 size_t endJacobianPos = curJacobianPos - numberOfArguments;
525
527 while (endJacobianPos < curJacobianPos) CODI_Likely {
528 curJacobianPos -= 1;
529 adjointVector[rhsIdentifiers[curJacobianPos]] += rhsJacobians[curJacobianPos] * lhsAdjoint;
530 }
531 } else CODI_Unlikely {
532 curJacobianPos = endJacobianPos;
533 }
534 }
535
537 CODI_WRAP_FUNCTION_TEMPLATE(Wrap_internalEvaluateReverse_EvalStatements,
539
541 template<typename Adjoint>
542 CODI_INLINE static void incrementTangents(Adjoint const* const adjointVector, Adjoint& lhsAdjoint,
543 Config::ArgumentSize const& numberOfArguments, size_t& curJacobianPos,
544 Real const* const rhsJacobians,
545 Identifier const* const rhsIdentifiers) {
546 size_t endJacobianPos = curJacobianPos + numberOfArguments;
547
548 while (curJacobianPos < endJacobianPos) CODI_Likely {
549 lhsAdjoint += rhsJacobians[curJacobianPos] * adjointVector[rhsIdentifiers[curJacobianPos]];
550 curJacobianPos += 1;
551 }
552 }
553
555 CODI_WRAP_FUNCTION_TEMPLATE(Wrap_internalEvaluateForward_EvalStatements,
557
558 public:
559
562
563 using Base::evaluate;
564
566 template<typename Adjoint>
567 CODI_NO_INLINE void evaluate(Position const& start, Position const& end, Adjoint* data) {
568 VectorAccess<Adjoint> adjointWrapper(data);
569
571 cast(), start, end, &adjointWrapper, EventHints::EvaluationKind::Reverse, EventHints::Endpoint::Begin);
572
574 Base::llfByteData.evaluateReverse(start, end, evalFunc, cast(), data);
575
576 EventSystem<Impl>::notifyTapeEvaluateListeners(cast(), start, end, &adjointWrapper,
577 EventHints::EvaluationKind::Reverse, EventHints::Endpoint::End);
578 }
579
581 template<typename Adjoint>
582 CODI_NO_INLINE void evaluateForward(Position const& start, Position const& end, Adjoint* data) {
583 VectorAccess<Adjoint> adjointWrapper(data);
584
586 cast(), start, end, &adjointWrapper, EventHints::EvaluationKind::Forward, EventHints::Endpoint::Begin);
587
589 Base::llfByteData.evaluateForward(start, end, evalFunc, cast(), data);
590
591 EventSystem<Impl>::notifyTapeEvaluateListeners(cast(), start, end, &adjointWrapper,
592 EventHints::EvaluationKind::Forward, EventHints::Endpoint::End);
593 }
594
596 /*******************************************************************************/
599
601 CODI_INLINE void swap(Impl& other) {
602 // Index manager does not need to be swapped, it is either static or swapped with the vector data.
603 // Vectors are swapped recursively in the base class.
604
605 adjoints.swap(other.adjoints);
606
607 Base::swap(other);
608 }
609
612 adjoints.resize(1);
613 }
614
617 checkAdjointSize(indexManager.get().getLargestCreatedIndex());
618 }
619
622 adjoints.beginUse();
623 }
624
627 adjoints.endUse();
628 }
629
631 size_t getParameter(TapeParameters parameter) const {
632 switch (parameter) {
634 return adjoints.size();
635 break;
637 return jacobianData.getDataSize();
638 break;
640 return indexManager.get().getLargestCreatedIndex();
641 break;
643 return statementData.getDataSize();
644 default:
645 return Base::getParameter(parameter);
646 break;
647 }
648 }
649
651 void setParameter(TapeParameters parameter, size_t value) {
652 switch (parameter) {
654 adjoints.resize(value);
655 break;
657 jacobianData.resize(value);
658 break;
660 CODI_EXCEPTION("Tried to set a get only parameter.");
661 break;
663 statementData.resize(value);
664 break;
665 default:
666 Base::setParameter(parameter, value);
667 break;
668 }
669 }
670
674 }
675
677 template<typename Adjoint>
679 return new VectorAccess<Adjoint>(data);
680 }
681
684 delete access;
685 }
686
688 /*******************************************************************************/
691
693 template<typename Lhs>
695 cast().internalRegisterInput(value, false);
696
697 return Real();
698 }
699
701 /*******************************************************************************/
704
706
708 void evaluateForward(Position const& start, Position const& end,
710 if (AdjointsManagement::Automatic == adjointsManagement) {
711 checkAdjointSize(indexManager.get().getLargestCreatedIndex());
712 adjoints.beginUse();
713 }
714
715 codiAssert(indexManager.get().getLargestCreatedIndex() < (Identifier)adjoints.size());
716
717 cast().evaluateForward(start, end, adjoints.data());
718
719 if (AdjointsManagement::Automatic == adjointsManagement) {
720 adjoints.endUse();
721 }
722 }
723
725 /*******************************************************************************/
728
730 void pushJacobianManual(Real const& jacobian, Real const& value, Identifier const& index) {
731 CODI_UNUSED(value);
732
733 cast().incrementManualPushCounter();
734
735 jacobianData.pushData(jacobian, index);
736
738 if (this->manualPushCounter == this->manualPushGoal) {
739 // emit statement event
740 Real* jacobians;
741 Identifier* rhsIdentifiers;
742 jacobianData.getDataPointers(jacobians, rhsIdentifiers);
743 jacobians -= this->manualPushGoal;
744 rhsIdentifiers -= this->manualPushGoal;
745
748 rhsIdentifiers, jacobians);
749 }
750 }
751 }
752
754 void storeManual(Real const& lhsValue, Identifier& lhsIndex, Config::ArgumentSize const& size) {
755 CODI_UNUSED(lhsValue);
756
758
759 statementData.reserveItems(1);
760 jacobianData.reserveItems(size);
761
762 indexManager.get().template assignIndex<Impl>(lhsIndex);
763 cast().pushStmtData(lhsIndex, (Config::ArgumentSize)size);
764
765 cast().initializeManualPushData(lhsValue, lhsIndex, size);
766 }
767
769 /*******************************************************************************/
772
775 statementData.reserveItems(1);
776
777 Base::internalStoreLowLevelFunction(token, size, data);
778
779 Identifier lhsIndex = Identifier();
781 indexManager.get().template assignIndex<Impl>(lhsIndex);
782 }
783 cast().pushStmtData(lhsIndex, Config::StatementLowLevelFunctionTag);
784 }
785
787 /*******************************************************************************/
790
792 CODI_INLINE void evaluate(Position const& start, Position const& end,
794 if (AdjointsManagement::Automatic == adjointsManagement) {
795 checkAdjointSize(indexManager.get().getLargestCreatedIndex());
796 adjoints.beginUse();
797 }
798
799 codiAssert(indexManager.get().getLargestCreatedIndex() < (Identifier)adjoints.size());
800
801 evaluate(start, end, adjoints.data());
802
803 if (AdjointsManagement::Automatic == adjointsManagement) {
804 adjoints.endUse();
805 }
806 }
807
809 /*******************************************************************************/
812
814 void evaluateKeepState(Position const& start, Position const& end,
816 evaluate(start, end, adjointsManagement);
817 }
818
820 void evaluateForwardKeepState(Position const& start, Position const& end,
822 evaluateForward(start, end, adjointsManagement);
823 }
824
826 /*******************************************************************************/
829
831
833 void evaluatePrimal(Position const& start, Position const& end) {
834 CODI_UNUSED(start, end);
835
836 CODI_EXCEPTION("Accessing primal evaluation of an Jacobian tape.");
837 }
838
840 Real& primal(Identifier const& identifier) {
841 CODI_UNUSED(identifier);
842
843 CODI_EXCEPTION("Accessing primal vector of an Jacobian tape.");
844
845 static Real temp;
846 return temp;
847 }
848
850 Real primal(Identifier const& identifier) const {
851 CODI_UNUSED(identifier);
852
853 CODI_EXCEPTION("Accessing primal vector of an Jacobian tape.");
854
855 return Real();
856 }
857
859
860 private:
861
862 CODI_INLINE void checkAdjointSize(Identifier const& identifier) {
863 if (identifier >= (Identifier)adjoints.size()) {
864 internalResizeAdjointsVector();
865 }
866 }
867
868 CODI_NO_INLINE void internalResizeAdjointsVector() {
869 // overallocate as next multiple of Config::ChunkSize
870 adjoints.resize(getNextMultiple((size_t)indexManager.get().getLargestCreatedIndex() + 1, Config::ChunkSize));
871 }
872 };
873}
#define CODI_Unlikely
Declare unlikely evaluation of an execution path.
Definition: config.h:399
#define CODI_NO_INLINE
See codi::Config::AvoidedInlines.
Definition: config.h:417
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition: config.h:457
#define CODI_Likely
Declare likely evaluation of an execution path.
Definition: config.h:397
#define CODI_RemoveDuplicateJacobianArguments
See codi::Config::RemoveDuplicateJacobianArguments.
Definition: config.h:229
#define codiAssert(x)
See codi::Config::EnableAssert.
Definition: config.h:432
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition: macros.hpp:94
#define CODI_ENABLE_CHECK(option, condition)
Definition: macros.hpp:53
#define CODI_WRAP_FUNCTION_TEMPLATE(NAME, FUNC)
Wrap a function in a function object. Used for performance optimizations.
Definition: macros.hpp:167
#define CODI_T(...)
Abbreviation for CODI_TEMPLATE.
Definition: macros.hpp:111
const bool CheckEmptyStatements
Tapes push statements only if at least one Jacobian was pushed.
Definition: config.h:154
uint16_t LowLevelFunctionToken
Token type for low level functions in the tapes.
Definition: config.h:108
size_t constexpr ChunkSize
Default size of chunks (ChunkBase) used in ChunkedData in reverse tape implementations.
Definition: config.h:94
bool constexpr CheckZeroIndex
Ignore active types that are not dependent on any input value in Jacobian tapes.
Definition: config.h:178
bool constexpr IgnoreInvalidJacobians
Ignore invalid Jacobians like NaN or Inf.
Definition: config.h:240
bool constexpr CheckTapeActivity
Makes it possible to ignore certain code parts. If turned of everything will be recorded.
Definition: config.h:170
size_t constexpr StatementLowLevelFunctionTag
Statement tag for low level functions.
Definition: config.h:126
bool constexpr CheckJacobianIsZero
Ignore Jacobians that are zero in Jacobian based tapes.
Definition: config.h:162
size_t constexpr MaxArgumentSize
Maximum number of arguments in a statement.
Definition: config.h:120
bool constexpr StatementEvents
Enable statement events. Disabled by default.
Definition: config.h:319
bool constexpr CopyOptimization
Do not store copy statements like a = b; if the identity handler allows it.
Definition: config.h:186
size_t constexpr StatementInputTag
Tag for statements that are inputs. Used in linear index management context.
Definition: config.h:123
bool constexpr SkipZeroAdjointEvaluation
Do not perform a reverse evaluation of a statement if the seeding adjoint is zero.
Definition: config.h:256
uint8_t ArgumentSize
Type for the number of arguments in statements.
Definition: config.h:117
typename TraitsImplementation< Type >::PassiveReal PassiveReal
The original computation type, that was used in the application.
Definition: realTraits.hpp:117
bool isTotalFinite(Type const &v)
Function for checking if all values of the type are finite.
Definition: realTraits.hpp:133
bool isTotalZero(Type const &v)
Function for checking if the value of the type is completely zero.
Definition: realTraits.hpp:139
CoDiPack - Code Differentiation Package.
Definition: codi.hpp:90
void CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition: macros.hpp:46
IntegralType getNextMultiple(IntegralType const &targetSize, IntegralType const &chunkSize)
Helper function for overallocation in multiples of a given chunk size.
Definition: mathUtility.hpp:49
TapeParameters
Configuration options for a tape.
Definition: tapeParameters.hpp:52
@ LargestIdentifier
[A: R] Largest identifier distributed by the index manger.
@ JacobianSize
[A: RW] Allocated number of entries in the argument Jacobian vector in Jacobian tapes.
@ StatementSize
[A: RW] Allocated number of entries in the statement vector in all tapes.
AdjointsManagement
Policies for management of the tape's interal adjoints.
Definition: tapeParameters.hpp:98
@ Automatic
Manage internal adjoints automatically, including locking, bounds checking, and resizing.
Implementation of VectorAccessInterface for adjoint vectors.
Definition: adjointVectorAccess.hpp:59
Definition: byteDataView.hpp:51
Definition: chunk.hpp:283
Data is stored chunk-wise in this DataInterface implementation. If a chunk runs out of space,...
Definition: chunkedData.hpp:64
Implementation of all common tape functionality.
Definition: commonTapeImplementation.hpp:130
Real manualPushLhsValue
For storeManual, remember the value assigned to the lhs.
Definition: commonTapeImplementation.hpp:157
void setParameter(TapeParameters parameter, size_t value)
See Parameters functions.
Definition: commonTapeImplementation.hpp:458
void evaluateForward(AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Perform a forward evaluation of a part of the tape. It has to hold start <= end.
Definition: commonTapeImplementation.hpp:591
size_t manualPushCounter
Count the pushes after storeManual, to identify the last push.
Definition: commonTapeImplementation.hpp:160
Identifier manualPushLhsIdentifier
For storeManual, remember the identifier assigned to the lhs.
Definition: commonTapeImplementation.hpp:158
bool isActive() const
Check if the tape is recording.
Definition: commonTapeImplementation.hpp:319
size_t manualPushGoal
Store the number of expected pushes after a storeManual call.
Definition: commonTapeImplementation.hpp:159
void init(typename ImplTapeTypes::NestedData *nested)
Initialize the base class.
Definition: commonTapeImplementation.hpp:715
std::set< TapeParameters > options
All options.
Definition: commonTapeImplementation.hpp:152
void evaluate(AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Perform a full reverse evaluation of the tape.
Definition: commonTapeImplementation.hpp:292
void swap(Impl &other)
Swap all data with an other tape.
Definition: commonTapeImplementation.hpp:367
typename CommonTapeTypes< ImplTapeTypes >::Position Position
See TapeTypesInterface.
Definition: commonTapeImplementation.hpp:144
LowLevelFunctionByteData llfByteData
Byte data for low level functions.
Definition: commonTapeImplementation.hpp:155
size_t getParameter(TapeParameters parameter) const
See Parameters functions.
Definition: commonTapeImplementation.hpp:430
void evaluatePrimal()
Perform a full (forward) reevaluation of the primals in the tape.
Definition: commonTapeImplementation.hpp:690
void internalStoreLowLevelFunction(Config::LowLevelFunctionToken token, size_t size, ByteDataView &dataView)
Called by the implementing tapes to store a low level function. The size is reserved and allocated....
Definition: commonTapeImplementation.hpp:493
Data stream interface for tape data. Encapsulates data that is written e.g. for each statement or arg...
Definition: dataInterface.hpp:149
Combines entries of Jacobians with the same identifier.
Definition: duplicateJacobianRemover.hpp:58
void storeData(Vec &vec)
Definition: duplicateJacobianRemover.hpp:98
static void notifyStatementStoreOnTapeListeners(Tape &tape, Identifier const &lhsIdentifier, Real const &newValue, size_t numActiveVariables, Identifier const *rhsIdentifiers, Real const *jacobians)
Invoke callbacks for StatementStoreOnTape events.
Definition: eventSystem.hpp:676
static void notifyTapeEvaluateListeners(Tape &tape, Position const &start, Position const &end, VectorAccess *adjoint, EventHints::EvaluationKind evalKind, EventHints::Endpoint endpoint)
Invoke callbacks for TapeEvaluate events.
Definition: eventSystem.hpp:486
static void notifyTapeRegisterInputListeners(Tape &tape, Real &value, Identifier &identifier)
Invoke callbacks for TapeRegisterInput events.
Definition: eventSystem.hpp:424
Base class for all CoDiPack expressions.
Definition: expressionInterface.hpp:59
Impl const & cast() const
Cast to the implementation.
Definition: expressionInterface.hpp:75
Counts the number of nodes that inherit from LhsExpressionInterface in the expression.
Definition: expressionTraits.hpp:184
Implement logic for leaf nodes only.
Definition: forEachLeafLogic.hpp:60
Indices enable the mapping of primal values to their adjoint counterparts.
Definition: indexManagerInterface.hpp:78
Abstracts the internal set of adjoint variables provided as part of the tape.
Definition: internalAdjointsInterface.hpp:80
Pushes all delayed Jacobians.
Definition: jacobianBaseTape.hpp:317
void handleActive(ReferenceActiveType< Type > const &node, DataVector &dataVector)
Specialization for ReferenceActiveType nodes. Pushes the delayed Jacobian.
Definition: jacobianBaseTape.hpp:322
Pushes Jacobians and indices to the tape.
Definition: jacobianBaseTape.hpp:285
void handleJacobianOnActive(Node const &node, Jacobian jacobianExpr, DataVector &dataVector)
General implementation. Checks for invalid and passive values/Jacobians.
Definition: jacobianBaseTape.hpp:289
void handleJacobianOnActive(ReferenceActiveType< Type > const &node, Jacobian jacobianExpr, DataVector &dataVector)
Specialization for ReferenceActiveType nodes. Delays Jacobian push.
Definition: jacobianBaseTape.hpp:303
Wrapper helper for improved compiler optimizations.
Definition: jacobianBaseTape.hpp:556
Wrapper helper for improved compiler optimizations.
Definition: jacobianBaseTape.hpp:538
Base class for all standard Jacobian tape implementations.
Definition: jacobianBaseTape.hpp:125
void evaluateKeepState(Position const &start, Position const &end, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Perform a tape evaluation but restore the state afterwards such that it is the same as when the evalu...
Definition: jacobianBaseTape.hpp:814
void pushJacobians(ExpressionInterface< Real, Rhs > const &rhs)
Push Jacobians and delayed Jacobians to the tape.
Definition: jacobianBaseTape.hpp:338
JacobianData jacobianData
Data stream for argument specific data.
Definition: jacobianBaseTape.hpp:171
typename Base::Position Position
See TapeTypesInterface.
Definition: jacobianBaseTape.hpp:149
VectorAccess< Gradient > * createVectorAccess()
See Adjoint vector access.
Definition: jacobianBaseTape.hpp:672
size_t getParameter(TapeParameters parameter) const
See Parameters functions.
Definition: jacobianBaseTape.hpp:631
typename TapeTypes::Gradient Gradient
See TapeTypesInterface.
Definition: jacobianBaseTape.hpp:137
typename TapeTypes::JacobianData JacobianData
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:142
static void internalEvaluateReverse_EvalStatements(Args &&... args)
Perform a reverse evaluation of the tape. Arguments are from the recursive eval methods of the DataIn...
void resizeAdjointVector()
Explicitly trigger resizing of the adjoint vector. See Adjoint vector management.
Definition: jacobianBaseTape.hpp:616
Gradient const & gradient(Identifier const &identifier, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic) const
Constant reference access to gradient.
Definition: jacobianBaseTape.hpp:248
StatementData statementData
Data stream for statement specific data.
Definition: jacobianBaseTape.hpp:170
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, LhsExpressionInterface< Real, Gradient, Impl, Rhs > const &rhs)
Has to be called by an AD variable every time it is assigned.
Definition: jacobianBaseTape.hpp:403
Adjoints adjoints
Evaluation vector for AD.
Definition: jacobianBaseTape.hpp:173
void beginUseAdjointVector()
Declare that the adjoint vector is being used. See Adjoint vector management.
Definition: jacobianBaseTape.hpp:621
T_TapeTypes TapeTypes
See JacobianBaseTape.
Definition: jacobianBaseTape.hpp:130
void pushStmtData(Identifier const &index, Config::ArgumentSize const &numberOfArguments)
Add statement specific data to the data streams.
TapeValues internalGetTapeValues() const
Adds data from all streams, the size of the adjoint vector and index manager data.
Definition: jacobianBaseTape.hpp:485
void evaluate(Position const &start, Position const &end, Adjoint *data)
Perform a reverse evaluation for a part of the tape. It hast to hold start >= end.
Definition: jacobianBaseTape.hpp:567
typename TapeTypes::IndexManager IndexManager
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:138
friend Base
Allow the base class to call protected and private methods.
Definition: jacobianBaseTape.hpp:134
void clearAdjoints(AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Clear all adjoint values, that is, set them to zero.
Definition: jacobianBaseTape.hpp:468
static void incrementAdjoints(Adjoint *adjointVector, Adjoint const &lhsAdjoint, Config::ArgumentSize const &numberOfArguments, size_t &curJacobianPos, Real const *const rhsJacobians, Identifier const *const rhsIdentifiers)
Performs the AD reverse equation for a statement.
Definition: jacobianBaseTape.hpp:520
typename TapeTypes::template Adjoints< Impl > Adjoints
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:144
void pushLowLevelFunction(Config::LowLevelFunctionToken token, size_t size, ByteDataView &data)
Push a low level function to the tape.
Definition: jacobianBaseTape.hpp:774
static void incrementTangents(Adjoint const *const adjointVector, Adjoint &lhsAdjoint, Config::ArgumentSize const &numberOfArguments, size_t &curJacobianPos, Real const *const rhsJacobians, Identifier const *const rhsIdentifiers)
Performs the AD forward equation for a statement.
Definition: jacobianBaseTape.hpp:542
void endUseAdjointVector()
Declare that the adjoint vector is no longer used. See Adjoint vector management.
Definition: jacobianBaseTape.hpp:626
static void internalEvaluateForward_EvalStatements(Args &&... args)
Perform a forward evaluation of the tape. Arguments are from the recursive eval methods of the DataIn...
void evaluateForward(Position const &start, Position const &end, Adjoint *data)
Perform a reverse evaluation for a part of the tape. It hast to hold start >= end.
Definition: jacobianBaseTape.hpp:582
void deleteAdjointVector()
Delete the adjoint vector. See Adjoint vector management.
Definition: jacobianBaseTape.hpp:611
void swap(Impl &other)
Swap all data with an other tape.
Definition: jacobianBaseTape.hpp:601
void evaluateForward(Position const &start, Position const &end, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Perform a forward evaluation of a part of the tape. It has to hold start <= end.
Definition: jacobianBaseTape.hpp:708
typename TapeTypes::Real Real
See TapeTypesInterface.
Definition: jacobianBaseTape.hpp:136
typename TapeTypes::StatementData StatementData
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:141
Real & primal(Identifier const &identifier)
Not implemented, raises an exception.
Definition: jacobianBaseTape.hpp:840
JacobianBaseTape()
Constructor.
Definition: jacobianBaseTape.hpp:207
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, Real const &rhs)
Has to be called by an AD variable every time it is assigned.
Definition: jacobianBaseTape.hpp:422
void store(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &lhs, ExpressionInterface< Real, Rhs > const &rhs)
Has to be called by an AD variable every time it is assigned.
Definition: jacobianBaseTape.hpp:362
void setParameter(TapeParameters parameter, size_t value)
See Parameters functions.
Definition: jacobianBaseTape.hpp:651
VectorAccess< Adjoint > * createVectorAccessCustomAdjoints(Adjoint *data)
See Adjoint vector access.
Definition: jacobianBaseTape.hpp:678
typename JacobianData::Position NestedPosition
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:148
static bool constexpr HasPrimalValues
See PrimalEvaluationTapeInterface.
Definition: jacobianBaseTape.hpp:156
static bool constexpr RequiresPrimalRestore
See PrimalEvaluationTapeInterface.
Definition: jacobianBaseTape.hpp:160
void evaluateForwardKeepState(Position const &start, Position const &end, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Perform a tape evaluation but restore the state afterwards such that it is the same as when the evalu...
Definition: jacobianBaseTape.hpp:820
void registerInput(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Definition: jacobianBaseTape.hpp:462
static bool constexpr AllowJacobianOptimization
See InternalStatementRecordingTapeInterface.
Definition: jacobianBaseTape.hpp:155
void storeManual(Real const &lhsValue, Identifier &lhsIndex, Config::ArgumentSize const &size)
Definition: jacobianBaseTape.hpp:754
void evaluate(Position const &start, Position const &end, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Perform a reverse evaluation for a part of the tape. It hast to hold start >= end.
Definition: jacobianBaseTape.hpp:792
void initIdentifier(Real &value, Identifier &identifier)
Definition: jacobianBaseTape.hpp:266
void pushJacobianManual(Real const &jacobian, Real const &value, Identifier const &index)
Definition: jacobianBaseTape.hpp:730
void evaluatePrimal(Position const &start, Position const &end)
Not implemented, raises an exception.
Definition: jacobianBaseTape.hpp:833
static bool constexpr LinearIndexHandling
See IdentifierInformationTapeInterface.
Definition: jacobianBaseTape.hpp:158
Real registerExternalFunctionOutput(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value)
Definition: jacobianBaseTape.hpp:694
void destroyIdentifier(Real &value, Identifier &identifier)
Has to be called for each identifier, before it is deallocated.
Definition: jacobianBaseTape.hpp:274
Gradient & gradient(Identifier const &identifier, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Reference access to gradient.
Definition: jacobianBaseTape.hpp:236
RealTraits::PassiveReal< Real > PassiveReal
Basic computation type.
Definition: jacobianBaseTape.hpp:146
MemberStore< IndexManager, Impl, TapeTypes::IsStaticIndexHandler > indexManager
Index manager.
Definition: jacobianBaseTape.hpp:169
typename TapeTypes::Identifier Identifier
See TapeTypesInterface.
Definition: jacobianBaseTape.hpp:139
T_Impl Impl
See JacobianBaseTape.
Definition: jacobianBaseTape.hpp:131
void deleteVectorAccess(VectorAccessInterface< Real, Identifier > *access)
See Adjoint vector access.
Definition: jacobianBaseTape.hpp:683
Real primal(Identifier const &identifier) const
Not implemented, raises an exception.
Definition: jacobianBaseTape.hpp:850
void internalRegisterInput(LhsExpressionInterface< Real, Gradient, Impl, Lhs > &value, bool unusedIndex)
Add a new input to the tape.
Definition: jacobianBaseTape.hpp:437
Definition: jacobianComputationLogic.hpp:53
Type definitions for the Jacobian tapes.
Definition: jacobianBaseTape.hpp:75
T_IndexManager IndexManager
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:80
T_Gradient Gradient
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:79
typename std::conditional< IsLinearIndexHandler, Chunk1< Config::ArgumentSize >, Chunk2< Identifier, Config::ArgumentSize > >::type StatementChunk
Definition: jacobianBaseTape.hpp:99
T_Data< Chunk, Nested > Data
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:83
Data< JacobianChunk, StatementData > JacobianData
Jacobian data vector.
Definition: jacobianBaseTape.hpp:103
Data< StatementChunk, IndexManager > StatementData
Statement data vector.
Definition: jacobianBaseTape.hpp:100
static bool constexpr IsLinearIndexHandler
True if the index manager is linear.
Definition: jacobianBaseTape.hpp:92
T_Adjoints< Gradient, Identifier, Impl > Adjoints
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:90
T_Real Real
See JacobianTapeTypes.
Definition: jacobianBaseTape.hpp:78
typename IndexManager::Index Identifier
See IndexManagerInterface.
Definition: jacobianBaseTape.hpp:85
JacobianData NestedData
See TapeTypesInterface.
Definition: jacobianBaseTape.hpp:105
static bool constexpr IsStaticIndexHandler
True if the index manager must be stored statically in the tape.
Definition: jacobianBaseTape.hpp:93
Default implementation of the Jacobian interface.
Definition: jacobian.hpp:60
Base class for all CoDiPack lvalue expression.
Definition: lhsExpressionInterface.hpp:63
Impl & cast()
Cast to the implementation.
Definition: lhsExpressionInterface.hpp:99
Defines a member that can either be static or local to the struct.
Definition: memberStore.hpp:56
Type & get()
Get a reference to the actual member.
Definition: memberStore.hpp:76
Holds a reference to an ActiveType for manual optimization of common arguments.
Definition: referenceActiveType.hpp:59
Interface for the definition of tape types.
Definition: commonTapeImplementation.hpp:63
Tape information that can be printed in a pretty print format or a table format.
Definition: tapeValues.hpp:73
void addDoubleEntry(std::string const &name, double const &value, bool usedMem=false, bool allocatedMem=false)
Add double entry. If it is a memory entry, it should be in bytes.
Definition: tapeValues.hpp:126
void addUnsignedLongEntry(std::string const &name, unsigned long const &value)
Add unsigned long entry.
Definition: tapeValues.hpp:150
void addSection(std::string const &name)
Add section. All further entries are added under this section.
Definition: tapeValues.hpp:145
void eval(NodeInterface< Node > const &node, Args &&... args)
Start the evaluation of the logic on the given expression.
Definition: traversalLogic.hpp:70
void node(Node const &node, Args &&... args)
Called for each node in the expression.
Definition: traversalLogic.hpp:86
Unified access to the adjoint vector and primal vector in a tape evaluation.
Definition: vectorAccessInterface.hpp:91