CoDiPack  2.2.0
A Code Differentiation Package
SciComp TU Kaiserslautern
Loading...
Searching...
No Matches
Features

Direct data access (Identifier management)

CoDiPack allows the user to have direct access to the tape and therefore also to the adjoint values. This design decision makes it at some places a little bit more complicated to work with CoDiPack but it allows the user to use their own data structures for handling the adjoint and tangent values.

Each variable that uses a reverse CoDiPack type (e.g. codi::RealReverse) has an associated identifier which is in the default configuration an integer. This identifier can be obtained by calling the function getIdentifier. It can then be used in the tape functions to get the adjoint value (e.g. getGradient).

In CoDiPack the identifier for a variable can change. Each time the variable is assigned a new value, the variable will get a new identifier (under special circumstances, the identifier can stay the same but this is not the default). The identifier of the variable will therefore only represent the last assignment and not all values (and therefore also derivatives) that have been assigned to this variable. This also means that if a variable is overwritten during the computation and the derivative with respect to the original value is required, then the identifier for this value needs to be stored.

An example is:

using Tape = typename Real::Tape;
using Identifier = typename Tape::Identifier;
Tape& tape = Real::getTape();
Identifier x_in;
Identifier x_out;
{
Real x = 10.0;
tape.setActive();
tape.registerInput(x);
x_in = x.getIdentifier(); // Identifier of x when it is defined as an input
// Do some heavy computation
x = 42.0 * x * x;
tape.registerOutput(x);
x_out = x.getIdentifier(); // Identifier of x when it is defined as an output
tape.setPassive();
}
tape.setGradient(x_out, 1.0); // Use this interface to set the gradient of x when it was defined as an output
tape.evaluate();
std::cout << "Gradient of df/dx: " << tape.getGradient(x_in) << std::endl;
RealReverseGen< double > RealReverse
Definition: codi.hpp:120
Identifier & getIdentifier()
Definition: activeTypeBase.hpp:156
Represents a concrete lvalue in the CoDiPack expression tree.
Definition: activeType.hpp:52
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

In this case x is used both as an input and output variable.

Statement level recording (Expression templates)

See Expressions.

Online activity analysis

The taping process in CoDiPack is organized such that it can automatically detect the dependency relation with respect to the input variable. Computations that do not depend on the input variables are not recorded. This is done by giving a special role to the zero index. This index is used to identify all passive variables. This means that all values with an nonzero index are active variables.

The initial state of the program is that all variables have a zero index. A call to registerInput will tell CoDiPack that this variable is an input and it will receive a nonzero index. The variable is now active. When storing a statement, CoDiPack inspects all arguments and checks if there is a least one that has a nonzero index. If this is the case, then the result of the statement is also active, receives a nonzero index, and the statement is recorded. Otherwise, the computation in the statement does not depend on the input variables and the result will be passive, that is, it receives the zero index and the statement is not recorded.

With this tracking technique, only the active parts of the computations are recorded.