CoDiPack  2.2.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
codi::TapeHelperBase< T_Type, T_Impl > Struct Template Referenceabstract

A helper class that allows for a simpler access and management of a CoDiPack tape. More...

#include <tapeHelper.hpp>

Inheritance diagram for codi::TapeHelperBase< T_Type, T_Impl >:

Public Types

using Gradient = typename Type::Gradient
 See LhsExpressionInterface.
 
using HessianType = Hessian< PassiveReal >
 Type of the Hessian.
 
using Identifier = typename Type::Identifier
 See LhsExpressionInterface.
 
using Impl = T_Impl
 See TapeHelperBase.
 
using JacobianType = Jacobian< PassiveReal >
 Type of the Jacobian.
 
using PassiveReal = typename RealTraits::PassiveReal< Real >
 Passive base of the CoDiPack type.
 
using Real = typename Type::Real
 See LhsExpressionInterface.
 
using Type = T_Type
 See TapeHelperBase.
 

Public Member Functions

GradientcreateGradientVectorInput ()
 Create a gradient vector that can hold the tangent/adjoint of the input variables.
 
GradientcreateGradientVectorOutput ()
 Create a gradient vector that can hold the tangent/adjoint of the output variables.
 
HessianTypecreateHessian ()
 Create a Hessian that can hold the Hessian of the recorded tape.
 
JacobianTypecreateJacobian ()
 Create a Jacobian that can hold the Jacobian of the recorded tape.
 
RealcreatePrimalVectorInput ()
 Create a primal vector that can hold the primal seeding of the input variables.
 
RealcreatePrimalVectorOutput ()
 Create a primal vector that can hold the primal result of the output variables.
 
void deleteGradientVector (Gradient *vec)
 Delete a gradient vector that was created with createGradientVectorInput or createGradientVectorOutput.
 
void deleteHessian (HessianType &hes)
 Delete the Hessian that was created with createHessian function.
 
void deleteJacobian (JacobianType &jac)
 Delete the Jacobian that was created with createJacobian function.
 
void deletePrimalVector (Real *vec)
 Delete a primal vector that was created with createPrimalVectorInput or createPrimalVectorOutput.
 
void evalForward (Gradient const *x_d, Gradient *y_d)
 Perform a forward (tangent) evaluation of the recorded tape.
 
void evalForwardAt (Real const *x, Gradient const *x_d, Gradient *y_d, Real *y=nullptr)
 Re-evaluate the tape with new input variables and compute the AD forward mode.
 
template<typename Jac = DummyJacobian>
void evalHessian (HessianType &hes, Jac &jac=StaticDummy< DummyJacobian >::dummy)
 Evaluates the full Hessian of the recorded tape.
 
template<typename Jac = DummyJacobian>
void evalHessianAt (Real const *x, HessianType &hes, Real *y=nullptr, Jac &jac=StaticDummy< DummyJacobian >::dummy)
 Re-evaluate the tape with new input variables and compute the full Hessian at the new inputs.
 
void evalJacobian (JacobianType &jac)
 Evaluates the full Jacobian of the recorded tape.
 
void evalJacobianAt (Real const *x, JacobianType &jac, Real *y=nullptr)
 Re-evaluate the tape with new input variables and compute the full Jacobian at the new inputs.
 
template<typename Jac >
void evalJacobianGen (Jac &jac)
 Evaluates the full Jacobian of the recorded tape with a custom Jacobian type chosen by the user.
 
virtual void evalPrimal (Real const *x, Real *y=nullptr)=0
 Perform a primal re-evaluation of the tape.
 
void evalReverse (Gradient const *y_b, Gradient *x_b)
 Perform a reverse (adjoint) evaluation of the recorded tape.
 
void evalReverseAt (Real const *x, Gradient const *y_b, Gradient *x_b, Real *y=nullptr)
 Re-evaluate the tape with new input variables and compute the AD forward mode.
 
size_t getInputSize ()
 
size_t getOutputSize ()
 
void registerInput (Type &value)
 Add an input variable to the tape.
 
void registerOutput (Type &value)
 Add an output variable to the tape.
 
void startRecording ()
 Start the recording process. Deletes the old tape.
 
void stopRecording ()
 Stop the recording process.
 
 TapeHelperBase ()
 Constructor.
 
virtual ~TapeHelperBase ()
 Destructor.
 

Protected Types

using Tape = typename Type::Tape
 Underlying tape type.
 

Protected Member Functions

Implcast ()
 Cast to the implementing class.
 
void changeStateToForwardEvaluation ()
 Change state.
 
void changeStateToReverseEvaluation ()
 Change state and clear the adjoints.
 

Protected Attributes

std::vector< IdentifierinputValues
 Input value identifiers.
 
std::vector< IdentifieroutputValues
 Input value identifiers.
 
Tapetape
 Reference to the global tape.
 
bool wasForwardEvaluated
 State of the last evaluation.
 

Detailed Description

template<typename T_Type, typename T_Impl>
struct codi::TapeHelperBase< T_Type, T_Impl >

A helper class that allows for a simpler access and management of a CoDiPack tape.

This class provides helper functionality to record a tape and to evaluate the forward and reverse mode of AD as well as capabilities to compute the full Jacobian and Hessian. Some functionality is only available with specific CoDiPack types. For Hessian computations, a second order primal value type is required (e.g. HessianComputationType) and for primal re-evaluations a primal value type is required (e.g. RealReversePrimalIndex).

The nomenclature and mathematical definitions for the function, the Jacobian, and the Hessian can be found in the section Mathematical naming conventions. For example, n denotes the number of inputs and m denotes the number of outputs. Function arguments in this class follow the same naming scheme as in the referenced documentation.

The general workflow for this class to record the representation of $ f $ is:

TH th; // Step 1: Create the tape helper
const size_t n = 10;
std::vector<Real> a(n);
std::vector<Real> b(n);
for(size_t i = 0; i < n; i += 1) {
a[i] = i;
b[i] = pow(-1, i);
}
th.startRecording(); // Step 2: Start the recording
for(size_t i = 0; i < n; i += 1) {
th.registerInput(a[i]); // Step 3: Register the inputs
}
for(size_t i = 0; i < n; i += 1) {
th.registerInput(b[i]);
}
// Step 4: Perform the computation
Real alpha, aNorm, bNorm;
dotWithNorms(a.data(), b.data(), n, alpha, aNorm, bNorm);
// Step 5: Register the outputs
th.registerOutput(alpha);
th.registerOutput(aNorm);
th.registerOutput(bNorm);
th.stopRecording(); // Step 6: Stop the recording
Represents a concrete lvalue in the CoDiPack expression tree.
Definition: activeType.hpp:52
See TapeHelperBase.
Definition: tapeHelper.hpp:642

The function func represents the implementation of $ f $ and before the function is called all inputs of that function need to be registered on the tape. The same is true for all outputs after the function is called. The methods startRecording() and stopRecording() define the region that will be recorded on the tape and are mandatory. They prepare the helper and the tape structure of CoDiPack for the recording and the evaluation and ensure that everything has the correct state.

The order of registerInput() and registerOutput() calls is important. It defines which variable is represented by the first entry, the second, etc. in the gradient vector, primal vector, Jacobian etc.

The computation of derivatives can then be done with the functions evalForward(), evalReverse(), evalJacobian(), and evalHessian(). For each of these functions, there is an eval...At equivalent that will first perform a primal re-evaluation of the tape on the given inputs (only for primal value tapes) and then performs the reverse evaluation.

The function evalPrimal() is used in the eval...At methods and can be used to manually re-evaluate for a different choice of input variables.

All arguments for the methods can either be created with the corresponding create method or can be created manually. The methods available for that are createGradientVectorInput(), createGradientVectorOutput(), createJacobian(), createHessian(), createPrimalVectorInput() and createPrimalVectorOutput(). Each create function has a corresponding delete function that deletes the objects.

The computation of the Hessian could be performed as follows.

TH::JacobianType& jac = th.createJacobian();
TH::HessianType& hes = th.createHessian();
if(1 == mode) {
th.evalJacobian(jac);
th.evalHessian(hes);
} else {
th.evalHessian(hes, jac);
}

A simple reverse evaluation works like this.

TH::Gradient* x_b = th.createGradientVectorInput();
TH::Gradient* y_b = th.createGradientVectorOutput();
y_b[0] = {1.0, 0.0, 0.0, 0.0};
y_b[1] = {0.0, 1.0, 0.0, 0.0};
y_b[2] = {0.0, 0.0, 1.0, 0.0};
th.evalReverse(y_b, x_b);

The tape helper can be used to record multiple different tapes. Each time startRecording() is called, the old recording is deleted and a new one is started.

For a more detailed example see Example 16 - TapeHelper.

Template Parameters
T_TypeThe CoDiPack type on which the evaluations take place.
T_ImplThe type of the implementing class for the virtual template methods.

Member Function Documentation

◆ createGradientVectorInput()

template<typename T_Type , typename T_Impl >
Gradient * codi::TapeHelperBase< T_Type, T_Impl >::createGradientVectorInput ( )
inline

Create a gradient vector that can hold the tangent/adjoint of the input variables.

Should only be called after the tape has been recorded. Needs to be deleted with deleteGradientVector.

Returns
Vector of size n.

◆ createGradientVectorOutput()

template<typename T_Type , typename T_Impl >
Gradient * codi::TapeHelperBase< T_Type, T_Impl >::createGradientVectorOutput ( )
inline

Create a gradient vector that can hold the tangent/adjoint of the output variables.

Should only be called after the tape has been recorded. Needs to be deleted with deleteGradientVector.

Returns
Vector of size m.

◆ createHessian()

template<typename T_Type , typename T_Impl >
HessianType & codi::TapeHelperBase< T_Type, T_Impl >::createHessian ( )
inline

Create a Hessian that can hold the Hessian of the recorded tape.

Should only be called after the tape has been recorded. Needs to be deleted with deleteHessian.

Returns
A Hessian with the size m,n.

◆ createJacobian()

template<typename T_Type , typename T_Impl >
JacobianType & codi::TapeHelperBase< T_Type, T_Impl >::createJacobian ( )
inline

Create a Jacobian that can hold the Jacobian of the recorded tape.

Should only be called after the tape has been recorded. Needs to be deleted with deleteJacobian.

Returns
A Jacobian with the size m,n.

◆ createPrimalVectorInput()

template<typename T_Type , typename T_Impl >
Real * codi::TapeHelperBase< T_Type, T_Impl >::createPrimalVectorInput ( )
inline

Create a primal vector that can hold the primal seeding of the input variables.

Should only be called after the tape has been recorded. Needs to be deleted with deletePrimalVector.

Returns
Vector of size n.

◆ createPrimalVectorOutput()

template<typename T_Type , typename T_Impl >
Real * codi::TapeHelperBase< T_Type, T_Impl >::createPrimalVectorOutput ( )
inline

Create a primal vector that can hold the primal result of the output variables.

Should only be called after the tape has been recorded. Needs to be deleted with deletePrimalVector.

Returns
Vector of size m.

◆ evalForward()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::evalForward ( Gradient const *  x_d,
Gradient y_d 
)
inline

Perform a forward (tangent) evaluation of the recorded tape.

Parameters
[in]x_dThe seeding vector for the input variables (independent variables). The vector should be created with createGradientVectorInput.
[out]y_dThe result vector for the output variables (dependent variables). The vector should be created with createGradientVectorOutput.

◆ evalForwardAt()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::evalForwardAt ( Real const *  x,
Gradient const *  x_d,
Gradient y_d,
Real y = nullptr 
)
inline

Re-evaluate the tape with new input variables and compute the AD forward mode.

This method is a shortcut for calling evalPrimal and evalForward in succession.

Parameters
[in]xThe new seeding vector for the primal input variables. The sequence of variables is the same as for the register input call. The vector should be created with createPrimalVectorInput.
[in]x_dThe seeding vector for the input variables (independent variables). The vector should be created with createGradientVectorInput.
[out]y_dThe result vector for the output variables (dependent variables). The vector should be created with createGradientVectorOutput.
[out]yThe result of the primal evaluation. The sequence of variables is the same as for the register output call. If the pointer is a null pointer then the result is not stored. The vector should be created with createPrimalVectorOutput.

◆ evalHessian()

template<typename T_Type , typename T_Impl >
template<typename Jac = DummyJacobian>
void codi::TapeHelperBase< T_Type, T_Impl >::evalHessian ( HessianType hes,
Jac &  jac = StaticDummyDummyJacobian >::dummy 
)

Evaluates the full Hessian of the recorded tape.

The algorithm will select the best choice for the evaluation, either a forward mode or reverse mode evaluation. It will also use the vector mode if the underlying tape was configured with such a mode.

Parameters
[out]hesThe storage for the Hessian which is evaluated. Must have the correct size and should be created with createHessian.
[out]jacIf also the Jacobian should be computed alongside the Hessian, a storage for the Jacobian can be provided. Must have the correct size and should be created with createJacobian.
Template Parameters
JacHas to implement JacobianInterface.

◆ evalHessianAt()

template<typename T_Type , typename T_Impl >
template<typename Jac = DummyJacobian>
void codi::TapeHelperBase< T_Type, T_Impl >::evalHessianAt ( Real const *  x,
HessianType hes,
Real y = nullptr,
Jac &  jac = StaticDummy<DummyJacobian>::dummy 
)
inline

Re-evaluate the tape with new input variables and compute the full Hessian at the new inputs.

This method is a shortcut for calling evalPrimal and evalHessian

Parameters
[in]xThe new seeding vector for the primal input variables. The sequence of variables is the same as for the register input call. The vector should be created with createPrimalVectorInput.
[out]hesThe storage for the Hessian which is evaluated. Needs to have the correct size and should be created with createHessian.
[out]yThe result of the primal evaluation. The sequence of variables is the same as for the register output call. If the pointer is a null pointer then the result is not stored. The vector should be created with createPrimalVectorOutput.
[out]jacIf also the Jacobian should be computed alongside the Hessian, a storage for the Jacobian can be provided. Needs to have the correct size and should be created with createJacobian.
Template Parameters
JacHas to implement JacobianInterface.

◆ evalJacobian()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::evalJacobian ( JacobianType jac)
inline

Evaluates the full Jacobian of the recorded tape.

The algorithm will select the best choice for the evaluation, either a forward mode or reverse mode evaluation. It will also use the vector mode if the underlying tape was configured with such a mode.

Parameters
[out]jacThe storage for the Jacobian which is evaluated. Must have the correct size and should be created with createJacobian.

◆ evalJacobianAt()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::evalJacobianAt ( Real const *  x,
JacobianType jac,
Real y = nullptr 
)
inline

Re-evaluate the tape with new input variables and compute the full Jacobian at the new inputs.

This method is a shortcut for calling evalPrimal and evalJacobian in succession.

Parameters
[in]xThe new seeding vector for the primal input variables. The sequence of variables is the same as for the register input call. The vector should be created with createPrimalVectorInput.
[out]jacThe storage for the Jacobian which is evaluated. Must have the correct size and should be created with createJacobian.
[out]yThe result of the primal evaluation. The sequence of variables is the same as for the register output call. If the pointer is a null pointer then the result is not stored. The vector should be created with createPrimalVectorOutput.

◆ evalJacobianGen()

template<typename T_Type , typename T_Impl >
template<typename Jac >
void codi::TapeHelperBase< T_Type, T_Impl >::evalJacobianGen ( Jac &  jac)
inline

Evaluates the full Jacobian of the recorded tape with a custom Jacobian type chosen by the user.

The algorithm will select the best choice for the evaluation, either a forward mode or reverse mode evaluation. It will also use the vector mode if the underlying tape was configured with such a mode.

Parameters
[out]jacThe storage for the Jacobian which is evaluated. Must have the correct size and should be created with createJacobian.
Template Parameters
JacHas to implement JacobianInterface.

◆ evalPrimal()

template<typename T_Type , typename T_Impl >
virtual void codi::TapeHelperBase< T_Type, T_Impl >::evalPrimal ( Real const *  x,
Real y = nullptr 
)
pure virtual

Perform a primal re-evaluation of the tape.

The re-evaluation will change the internally stored primal variables of the tape.

Parameters
[in]xThe new seeding vector for the primal input variables. The sequence of variables is the same as for the register input call. The vector should be created with createPrimalVectorInput.
[out]yThe result of the primal evaluation. The sequence of variables is the same as for the register output call. If the pointer is a null pointer then the result is not stored. The vector should be created with createPrimalVectorOutput.

Implemented in codi::TapeHelperJacobi< T_Type >, codi::TapeHelperPrimal< T_Type >, codi::TapeHelperNoImpl< T_Type >, and codi::TapeHelperNoImpl< Type >.

◆ evalReverse()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::evalReverse ( Gradient const *  y_b,
Gradient x_b 
)
inline

Perform a reverse (adjoint) evaluation of the recorded tape.

Parameters
[in]y_bThe seeding vector for the output variables (dependent variables). The vector should be created with createGradientVectorOutput.
[out]x_bThe result vector for the input variables (independent variables). The vector should be created with createGradientVectorInput.

◆ evalReverseAt()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::evalReverseAt ( Real const *  x,
Gradient const *  y_b,
Gradient x_b,
Real y = nullptr 
)
inline

Re-evaluate the tape with new input variables and compute the AD forward mode.

This method is a shortcut for calling evalPrimal and evalReverse in succession.

Parameters
[in]xThe new seeding vector for the primal input variables. The sequence of variables is the same as for the register input call. The vector should be created with createPrimalVectorInput.
[out]y_bThe seeding vector for the output variables (dependent variables). The vector should be created with createGradientVectorOutput.
[in]x_bThe result vector for the input variables (independent variables). The vector should be created with createGradientVectorInput.
[out]yThe result of the primal evaluation. The sequence of variables is the same as for the register output call. If the pointer is a null pointer then the result is not stored. The vector should be created with createPrimalVectorOutput.

◆ getInputSize()

template<typename T_Type , typename T_Impl >
size_t codi::TapeHelperBase< T_Type, T_Impl >::getInputSize ( )
inline

Get the number of registered inputs. Call after stopRecording().

Returns
n

◆ getOutputSize()

template<typename T_Type , typename T_Impl >
size_t codi::TapeHelperBase< T_Type, T_Impl >::getOutputSize ( )
inline

Get the number of registered outputs. Call after stopRecording().

Returns
m

◆ registerInput()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::registerInput ( Type value)
inline

Add an input variable to the tape.

Input variables are also known as independent variables.

The value is modified such that CoDiPack will recognize it as an active variable. For all variables registered with the method, the derivative is computed.

With this tape helper, the sequence of the registerInput calls is important. All primal and derivative vectors will use the first entry for the first value registered, the second for the second one, and so on.

◆ registerOutput()

template<typename T_Type , typename T_Impl >
void codi::TapeHelperBase< T_Type, T_Impl >::registerOutput ( Type value)
inline

Add an output variable to the tape.

Output variables are also known as dependent variables.

The value is modified such that it is safe to use the variable as an output for which the reverse seed can be set.

With this tape helper, the sequence of the registerOutput calls is important. All primal and derivative vectors will use the first entry for the first value registered, the second for the second one, and so on.


The documentation for this struct was generated from the following file: