CoDiPack  2.3.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
jacobianLinearTape.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://scicomp.rptu.de
6 * Contact: Prof. Nicolas R. Gauger (codi@scicomp.uni-kl.de)
7 *
8 * Lead developers: Max Sagebaum, Johannes Blühdorn (SciComp, University of Kaiserslautern-Landau)
9 *
10 * This file is part of CoDiPack (http://scicomp.rptu.de/software/codi).
11 *
12 * CoDiPack is free software: you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * CoDiPack is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty
19 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * See the GNU General Public License for more details.
22 * You should have received a copy of the GNU
23 * General Public License along with CoDiPack.
24 * If not, see <http://www.gnu.org/licenses/>.
25 *
26 * For other licensing options please contact us.
27 *
28 * Authors:
29 * - SciComp, University of Kaiserslautern-Landau:
30 * - Max Sagebaum
31 * - Johannes Blühdorn
32 * - Former members:
33 * - Tim Albring
34 */
35#pragma once
36
37#include <algorithm>
38#include <type_traits>
39
40#include "../config.h"
41#include "../expressions/lhsExpressionInterface.hpp"
42#include "../expressions/logic/compileTimeTraversalLogic.hpp"
43#include "../expressions/logic/traversalLogic.hpp"
44#include "../misc/macros.hpp"
45#include "../traits/adjointVectorTraits.hpp"
46#include "../traits/expressionTraits.hpp"
47#include "data/chunk.hpp"
48#include "indices/linearIndexManager.hpp"
49#include "interfaces/reverseTapeInterface.hpp"
50#include "jacobianBaseTape.hpp"
51
53namespace codi {
54
62 template<typename T_TapeTypes>
63 struct JacobianLinearTape : public JacobianBaseTape<T_TapeTypes, JacobianLinearTape<T_TapeTypes>> {
64 public:
65
66 using TapeTypes = CODI_DD(T_TapeTypes,
69
71 friend Base;
72
73 using Real = typename TapeTypes::Real;
74 using Gradient = typename TapeTypes::Gradient;
75 using IndexManager = typename TapeTypes::IndexManager;
76 using Identifier = typename TapeTypes::Identifier;
77 using Position = typename Base::Position;
78
79 CODI_STATIC_ASSERT(IndexManager::IsLinear, "This class requires an index manager with a linear scheme.");
80
83
85
87 void clearAdjoints(Position const& start, Position const& end,
89 if (AdjointsManagement::Automatic == adjointsManagement) {
90 this->adjoints.beginUse();
91 }
92
93 using IndexPosition = CODI_DD(typename IndexManager::Position, int);
94 IndexPosition startIndex = this->llfByteData.template extractPosition<IndexPosition>(start);
95 IndexPosition endIndex = this->llfByteData.template extractPosition<IndexPosition>(end);
96
97 startIndex = std::min(startIndex, (IndexPosition)this->adjoints.size() - 1);
98 endIndex = std::min(endIndex, (IndexPosition)this->adjoints.size() - 1);
99
100 for (IndexPosition curPos = endIndex + 1; curPos <= startIndex; curPos += 1) {
101 this->adjoints[curPos] = Gradient();
102 }
103
104 if (AdjointsManagement::Automatic == adjointsManagement) {
105 this->adjoints.endUse();
106 }
107 }
108
110 template<typename AdjointVector>
111 void clearCustomAdjoints(Position const& start, Position const& end, AdjointVector&& data) {
112 using IndexPosition = CODI_DD(typename IndexManager::Position, int);
113 IndexPosition startIndex = this->llfByteData.template extractPosition<IndexPosition>(start);
114 IndexPosition endIndex = this->llfByteData.template extractPosition<IndexPosition>(end);
115
116 for (IndexPosition curPos = endIndex + 1; curPos <= startIndex; curPos += 1) {
118 }
119 }
120
121 protected:
122
125 CODI_INLINE void pushStmtData(Identifier const& index, Config::ArgumentSize const& numberOfArguments) {
126 CODI_UNUSED(index);
127
128 this->statementData.pushData(numberOfArguments);
129 }
130
132 template<typename AdjointVector>
134 /* data from call */
135 JacobianLinearTape& tape, AdjointVector&& adjointVector,
136 /* data from low level function byte data vector */
137 size_t& curLLFByteDataPos, size_t const& endLLFByteDataPos, char* dataPtr,
138 /* data from low level function info data vector */
139 size_t& curLLFInfoDataPos, size_t const& endLLFInfoDataPos, Config::LowLevelFunctionToken* const tokenPtr,
140 Config::LowLevelFunctionDataSize* const dataSizePtr,
141 /* data from jacobian vector */
142 size_t& curJacobianPos, size_t const& endJacobianPos, Real const* const rhsJacobians,
143 Identifier const* const rhsIdentifiers,
144 /* data from statement vector */
145 size_t& curStmtPos, size_t const& endStmtPos, Config::ArgumentSize const* const numberOfJacobians,
146 /* data from index handler */
147 size_t const& startAdjointPos, size_t const& endAdjointPos) {
148 CODI_UNUSED(endJacobianPos, endStmtPos, endLLFByteDataPos, endLLFInfoDataPos);
149
151
152 typename Base::template VectorAccess<AdjointVector> vectorAccess(adjointVector);
153
154 size_t curAdjointPos = startAdjointPos;
155
156 while (curAdjointPos < endAdjointPos) CODI_Likely {
157 curAdjointPos += 1;
158
159 Config::ArgumentSize const argsSize = numberOfJacobians[curStmtPos];
160
162 Base::template callLowLevelFunction<LowLevelFunctionEntryCallKind::Forward>(
163 tape, true, curLLFByteDataPos, dataPtr, curLLFInfoDataPos, tokenPtr, dataSizePtr, &vectorAccess);
164 } else if (Config::StatementInputTag == argsSize) CODI_Unlikely {
165 // Do nothing.
166 } else CODI_Likely {
167 Adjoint lhsAdjoint = Adjoint();
168 Base::incrementTangents(adjointVector, lhsAdjoint, argsSize, curJacobianPos, rhsJacobians, rhsIdentifiers);
169 adjointVector[curAdjointPos] = lhsAdjoint;
170
172 tape, curAdjointPos, GradientTraits::dim<Adjoint>(), GradientTraits::toArray(lhsAdjoint).data());
173 }
174
175 curStmtPos += 1;
176 }
177 }
178
180 template<typename AdjointVector>
182 /* data from call */
183 JacobianLinearTape& tape, AdjointVector&& adjointVector,
184 /* data from low level function byte data vector */
185 size_t& curLLFByteDataPos, size_t const& endLLFByteDataPos, char* dataPtr,
186 /* data from low level function info data vector */
187 size_t& curLLFInfoDataPos, size_t const& endLLFInfoDataPos, Config::LowLevelFunctionToken* const tokenPtr,
188 Config::LowLevelFunctionDataSize* const dataSizePtr,
189 /* data from jacobianData */
190 size_t& curJacobianPos, size_t const& endJacobianPos, Real const* const rhsJacobians,
191 Identifier const* const rhsIdentifiers,
192 /* data from statementData */
193 size_t& curStmtPos, size_t const& endStmtPos, Config::ArgumentSize const* const numberOfJacobians,
194 /* data from index handler */
195 size_t const& startAdjointPos, size_t const& endAdjointPos) {
196 CODI_UNUSED(endJacobianPos, endStmtPos, endLLFByteDataPos, endLLFInfoDataPos);
197
199
200 typename Base::template VectorAccess<AdjointVector> vectorAccess(adjointVector);
201
202 size_t curAdjointPos = startAdjointPos;
203
204 while (curAdjointPos > endAdjointPos) CODI_Likely {
205 curStmtPos -= 1;
206 Config::ArgumentSize const argsSize = numberOfJacobians[curStmtPos];
207
209 Base::template callLowLevelFunction<LowLevelFunctionEntryCallKind::Reverse>(
210 tape, false, curLLFByteDataPos, dataPtr, curLLFInfoDataPos, tokenPtr, dataSizePtr, &vectorAccess);
211 } else if (Config::StatementInputTag == argsSize) CODI_Unlikely {
212 // Do nothing.
213 } else CODI_Likely {
214 // No input value, perform regular statement evaluation.
215
216 Adjoint const lhsAdjoint = adjointVector[curAdjointPos]; // We do not use the zero index, decrement of
217 // curAdjointPos at the end of the loop.
218
220 tape, (Identifier)curAdjointPos, GradientTraits::dim<Adjoint>(),
221 GradientTraits::toArray(lhsAdjoint).data());
222
224 adjointVector[curAdjointPos] = Adjoint();
225 }
226
227 Base::incrementAdjoints(adjointVector, lhsAdjoint, argsSize, curJacobianPos, rhsJacobians, rhsIdentifiers);
228 }
229
230 curAdjointPos -= 1;
231 }
232 }
233
235 template<typename Real>
237 /* file interface pointer*/
239 /* data from low level function byte data vector */
240 size_t& curLLFByteDataPos, size_t const& endLLFByteDataPos, char* dataPtr,
241 /* data from low level function info data vector */
242 size_t& curLLFInfoDataPos, size_t const& endLLFInfoDataPos, Config::LowLevelFunctionToken* const tokenPtr,
243 Config::LowLevelFunctionDataSize* const dataSizePtr,
244 /* data from jacobianData */
245 size_t& curJacobianPos, size_t const& endJacobianPos, typename Real::Real const* const rhsJacobians,
246 typename Real::Identifier const* const rhsIdentifiers,
247 /* data from statementData */
248 size_t& curStmtPos, size_t const& endStmtPos, Config::ArgumentSize const* const numberOfJacobians,
249 /* data from index handler */
250 size_t const& startAdjointPos, size_t const& endAdjointPos) {
251 CODI_UNUSED(endLLFByteDataPos, endLLFInfoDataPos, endJacobianPos, endStmtPos);
252
253 typename Real::Identifier curLhsIdentifier;
254 Config::ArgumentSize argsSize;
255 size_t curAdjointPos = startAdjointPos;
256 while (curAdjointPos < endAdjointPos) CODI_Likely {
257 curAdjointPos += 1;
258 curLhsIdentifier = curAdjointPos;
259 argsSize = numberOfJacobians[curStmtPos];
261 writer->writeLowLevelFunction(curLLFByteDataPos, dataPtr, curLLFInfoDataPos, tokenPtr, dataSizePtr);
262 } else if (Config::StatementInputTag == argsSize) CODI_Unlikely {
263 writer->writeStatement(curLhsIdentifier, curJacobianPos, rhsJacobians, rhsIdentifiers, argsSize);
264 } else CODI_Likely {
265 writer->writeStatement(curLhsIdentifier, curJacobianPos, rhsJacobians, rhsIdentifiers, argsSize);
266 curJacobianPos += argsSize;
267 }
268 curStmtPos += 1;
269 }
270 }
271 };
272}
#define CODI_Unlikely
Declare unlikely evaluation of an execution path.
Definition config.h:399
#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_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:94
#define CODI_STATIC_ASSERT(cond, message)
Static assert in CoDiPack.
Definition macros.hpp:123
#define CODI_T(...)
Abbreviation for CODI_TEMPLATE.
Definition macros.hpp:111
typename GradientImplementation< AdjointVector >::Gradient Gradient
Deduce the entry type from an adjoint vector type, usually identical to the gradient type of a tape.
Definition adjointVectorTraits.hpp:92
uint16_t LowLevelFunctionDataSize
Size store type for a low level function.
Definition config.h:98
uint16_t LowLevelFunctionToken
Token type for low level functions in the tapes.
Definition config.h:108
size_t constexpr StatementLowLevelFunctionTag
Statement tag for low level functions.
Definition config.h:126
bool constexpr ReversalZeroesAdjoints
With a linear index management, control if adjoints are set to zero during reversal.
Definition config.h:289
uint8_t ArgumentSize
Type for the number of arguments in statements.
Definition config.h:117
size_t constexpr StatementInputTag
Tag for statements that are inputs. Used in linear index management context.
Definition config.h:123
std::array< AtomicTraits::RemoveAtomic< typename TraitsImplementation< Gradient >::Real >, TraitsImplementation< Gradient >::dim > toArray(Gradient const &gradient)
Converts the (possibly multi-component) gradient to an array of Reals.
Definition gradientTraits.hpp:116
CoDiPack - Code Differentiation Package.
Definition codi.hpp:91
void CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:46
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.
typename Tape::Identifier Identifier
See LhsExpressionInterface.
Definition activeTypeBase.hpp:78
typename Tape::Real Real
See LhsExpressionInterface.
Definition activeTypeBase.hpp:76
Implementation of VectorAccessInterface for adjoint vectors.
Definition adjointVectorAccess.hpp:61
Data is stored chunk-wise in this DataInterface implementation. If a chunk runs out of space,...
Definition chunkedData.hpp:64
LowLevelFunctionByteData llfByteData
Byte data for low level functions.
Definition commonTapeImplementation.hpp:156
static void notifyStatementEvaluateListeners(Tape &tape, Identifier const &lhsIdentifier, size_t sizeLhsAdjoint, Real const *lhsAdjoint)
Invoke callbacks for StatementEvaluate events.
Definition eventSystem.hpp:712
Indices enable the mapping of primal values to their adjoint counterparts.
Definition indexManagerInterface.hpp:78
Base class for all standard Jacobian tape implementations.
Definition jacobianBaseTape.hpp:128
typename Base::Position Position
See TapeTypesInterface.
Definition jacobianBaseTape.hpp:152
StatementData statementData
Data stream for statement specific data.
Definition jacobianBaseTape.hpp:173
Adjoints adjoints
Evaluation vector for AD.
Definition jacobianBaseTape.hpp:176
static void incrementTangents(AdjointVector const &adjointVector, AdjointVectorTraits::Gradient< AdjointVector > &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:550
void clearAdjoints(AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Clear all adjoint values, that is, set them to zero.
Definition jacobianBaseTape.hpp:471
static void incrementAdjoints(AdjointVector &adjointVector, AdjointVectorTraits::Gradient< AdjointVector > 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:527
Final implementation for a Jacobian tape with a linear index management.
Definition jacobianLinearTape.hpp:63
typename TapeTypes::Real Real
See TapeTypesInterface.
Definition jacobianLinearTape.hpp:73
void clearCustomAdjoints(Position const &start, Position const &end, AdjointVector &&data)
Clear all adjoint values, that is, set them to zero.
Definition jacobianLinearTape.hpp:111
void clearAdjoints(Position const &start, Position const &end, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Clear all adjoints that would be set in a tape evaluation from start to end. It has to hold start >= ...
Definition jacobianLinearTape.hpp:87
typename TapeTypes::IndexManager IndexManager
See TapeTypesInterface.
Definition jacobianLinearTape.hpp:75
JacobianLinearTape()
Constructor.
Definition jacobianLinearTape.hpp:82
typename TapeTypes::Gradient Gradient
See TapeTypesInterface.
Definition jacobianLinearTape.hpp:74
static void internalEvaluateReverse_EvalStatements(JacobianLinearTape &tape, AdjointVector &&adjointVector, size_t &curLLFByteDataPos, size_t const &endLLFByteDataPos, char *dataPtr, size_t &curLLFInfoDataPos, size_t const &endLLFInfoDataPos, Config::LowLevelFunctionToken *const tokenPtr, Config::LowLevelFunctionDataSize *const dataSizePtr, size_t &curJacobianPos, size_t const &endJacobianPos, Real const *const rhsJacobians, Identifier const *const rhsIdentifiers, size_t &curStmtPos, size_t const &endStmtPos, Config::ArgumentSize const *const numberOfJacobians, size_t const &startAdjointPos, size_t const &endAdjointPos)
Perform a reverse evaluation of the tape. Arguments are from the recursive eval methods of the DataIn...
Definition jacobianLinearTape.hpp:181
T_TapeTypes TapeTypes
See JacobianLinearTape.
Definition jacobianLinearTape.hpp:66
static void internalWriteTape(codi::TapeWriterInterface< Real > *writer, size_t &curLLFByteDataPos, size_t const &endLLFByteDataPos, char *dataPtr, size_t &curLLFInfoDataPos, size_t const &endLLFInfoDataPos, Config::LowLevelFunctionToken *const tokenPtr, Config::LowLevelFunctionDataSize *const dataSizePtr, size_t &curJacobianPos, size_t const &endJacobianPos, typename Real::Real const *const rhsJacobians, typename Real::Identifier const *const rhsIdentifiers, size_t &curStmtPos, size_t const &endStmtPos, Config::ArgumentSize const *const numberOfJacobians, size_t const &startAdjointPos, size_t const &endAdjointPos)
Passes the statement to the writer.
Definition jacobianLinearTape.hpp:236
typename TapeTypes::Identifier Identifier
See TapeTypesInterface.
Definition jacobianLinearTape.hpp:76
friend Base
Allow the base class to call protected and private methods.
Definition jacobianLinearTape.hpp:71
void pushStmtData(Identifier const &index, Config::ArgumentSize const &numberOfArguments)
Add statement specific data to the data streams.
Definition jacobianLinearTape.hpp:125
typename Base::Position Position
See TapeTypesInterface.
Definition jacobianLinearTape.hpp:77
static void internalEvaluateForward_EvalStatements(JacobianLinearTape &tape, AdjointVector &&adjointVector, size_t &curLLFByteDataPos, size_t const &endLLFByteDataPos, char *dataPtr, size_t &curLLFInfoDataPos, size_t const &endLLFInfoDataPos, Config::LowLevelFunctionToken *const tokenPtr, Config::LowLevelFunctionDataSize *const dataSizePtr, size_t &curJacobianPos, size_t const &endJacobianPos, Real const *const rhsJacobians, Identifier const *const rhsIdentifiers, size_t &curStmtPos, size_t const &endStmtPos, Config::ArgumentSize const *const numberOfJacobians, size_t const &startAdjointPos, size_t const &endAdjointPos)
Perform a forward evaluation of the tape. Arguments are from the recursive eval methods of the DataIn...
Definition jacobianLinearTape.hpp:133
Type definitions for the Jacobian tapes.
Definition jacobianBaseTape.hpp:78
The interface used by all the tape writers. The tape writers are used to generate text,...
Definition tapeReaderWriterInterface.hpp:128
virtual void writeLowLevelFunction(size_t &curLLFByteDataPos, char *dataPtr, size_t &curLLFInfoDataPos, Config::LowLevelFunctionToken *const tokenPtr, Config::LowLevelFunctionDataSize *const dataSizePtr)
Used for statements that contain a low level function.
Definition tapeReaderWriterInterface.hpp:169
virtual void writeStatement(Identifier const &curLhsIdentifier, size_t &curJacobianPos, Real const *const rhsJacobians, Identifier const *const rhsIdentifiers, Config::ArgumentSize const &nJacobians)
Called for each statement. The method writes the current statement to the file. This overload is used...
Definition tapeReaderWriterInterface.hpp:149