CoDiPack  2.2.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
Example 11 - External function user data

Goal: Learn how to use the external function user data structure.

Prerequisite: Tutorial 2 - Reverse mode AD

Function: Simple real valued function

Real func(const Real& x) {
return x * x * x;
}
Represents a concrete lvalue in the CoDiPack expression tree.
Definition: activeType.hpp:52

Full code:

#include <codi.hpp>
#include <iostream>
using Tape = typename Real::Tape;
using Identifier = typename Real::Identifier;
using RealBase = typename Real::Real;
Real func(const Real& x) {
return x * x * x;
}
void extFunc_rev(Tape* t, void* d, codi::VectorAccessInterface<typename Tape::Real, Identifier>* va) {
// Step 4: Get data in the same order as it was added.
Identifier t_i = data->getData<int>();
double scale = data->getData<double>();
Real t_b = va->getAdjoint(t_i, 0);
std::cout << " Reverse: t_b = " << t_b << ", scale = " << scale << std::endl;
}
void extFunc_del(Tape* t, void* d) {
// Step 5: Delete the data
delete data;
std::cout << " Reset: data is deleted." << std::endl;
}
int main(int nargs, char** args) {
Real x = 4.0;
Tape& tape = Real::getTape();
tape.setActive();
tape.registerInput(x);
Real t = func(x);
codi::ExternalFunctionUserData* data = new codi::ExternalFunctionUserData(); // Step 1: Create the data object
data->addData(t.getIdentifier()); // Step 2: Add data
data->addData(0.01);
// Step 3: Add the external function with the data
tape.pushExternalFunction(codi::ExternalFunction<Tape>::create(extFunc_rev, data, extFunc_del));
Real y = func(t);
tape.registerOutput(y);
tape.setPassive();
y.setGradient(1.0);
tape.evaluate();
std::cout << "f(f(4.0)) = " << y << std::endl;
std::cout << "d(f ○ f)/dx(4.0) = " << x.getGradient() << std::endl;
tape.reset();
return 0;
}
RealReverseGen< double > RealReverse
Definition: codi.hpp:120
Identifier & getIdentifier()
Definition: activeTypeBase.hpp:156
typename Tape::Identifier Identifier
See LhsExpressionInterface.
Definition: activeTypeBase.hpp:78
static Tape & getTape()
Get a reference to the tape which manages this expression.
Definition: activeType.hpp:99
T_Tape Tape
See ActiveType.
Definition: activeType.hpp:55
typename Tape::Real Real
See LhsExpressionInterface.
Definition: activeTypeBase.hpp:76
Ease of access structure for user-provided data on the tape for external functions....
Definition: externalFunctionUserData.hpp:59
void getData(Type &value)
Get a copy of the next data item.
Definition: externalFunctionUserData.hpp:171
size_t addData(Type const &value)
Definition: externalFunctionUserData.hpp:151
User-defined evaluation functions for the taping process.
Definition: externalFunction.hpp:102
void setGradient(Gradient const &g)
Set the gradient of this lvalue in the tape.
Definition: lhsExpressionInterface.hpp:120
Gradient getGradient() const
Get the gradient of this lvalue from the tape.
Definition: lhsExpressionInterface.hpp:115
Unified access to the adjoint vector and primal vector in a tape evaluation.
Definition: vectorAccessInterface.hpp:91
virtual Real getAdjoint(Identifier const &index, size_t dim)=0
Get the adjoint component.

The data in codi::ExternalFunctionUserData is accessed in a toroidal pattern. After all added data items have been accessed the next call will start again at the first data item. This allows for multiple reverse interpretations.