Goal: Vector mode with the forward and reverse mode AD CoDiPack types.
Prerequisite: Tutorial 1 - Forward mode AD, Tutorial 2 - Reverse mode AD
Function: Simple vector valued function
Full code:
The vector mode of AD is introduced by using matrices for the adjoint values and tangent values
With CoDiPack, the vector mode is enabled by exchanging the type used for the gradient computation. A fixed size vector is implemented in the Direction class. The codi::Real*Vec
types use this class to provide the vector mode. Only the vector dimension needs to be provided by the user, e.g. codi::RealReverseVec<5>
.
This is nearly the only change one has to make when switching to the vector mode in CoDiPack. In order to access the elements of the vector mode, the Direction class offers array access operators. Gradients can also be initialized with initializer lists that are also supported by the Direction class.
The code example above highlights the necessary changes for the vector mode with the comments Step 1 to Step 3. In step 1, the CoDiPack type is defined as a vector type. Step 2 shows the seeding for the vector directions. In step 3, the Jacobian matrix is extracted.
CoDiPack offers only a fixed size vector mode that has to be defined at compile time. This decision against providing a vector mode that can be defined at run time was made deliberately. In the forward mode, all operations have to check if the vectors have the correct size and need to allocate new memory accordingly. This reduces the performance of a forward vector mode. In addition, if the vector size is known a priori, the compiler can optimize the forward and reverse vector mode even further by using e.g. SIMD instructions.
In the reverse mode, it is possible to introduce a run time decision on the vector size by using the custom evaluation methods described in Example 8 - Generalized adjoint vector interface and Example 2 - Custom adjoint vector evaluation