41#include "../../expressions/lhsExpressionInterface.hpp"
42#include "../../misc/exceptions.hpp"
43#include "../../tapes/interfaces/fullTapeInterface.hpp"
44#include "../../tapes/tagging/tagTapeReverse.hpp"
45#include "../../traits/gradientTraits.hpp"
46#include "../../traits/tapeTraits.hpp"
47#include "../algorithms.hpp"
48#include "../data/jacobian.hpp"
75 template<
typename T_Type,
typename =
void>
82 using Real =
typename Type::Real;
110 template<
typename... Inputs>
112 Tape& tape = Type::getTape();
114 if (tape.isActive()) {
115 addInputRecursive(inputs...);
120 template<
typename... Inputs>
121 void start(Inputs
const&... inputs) {
122 Tape& tape = Type::getTape();
126 if (tape.isActive()) {
133 addInputRecursive(inputs...);
138 template<
typename... Outputs>
140 Tape& tape = Type::getTape();
142 if (tape.isActive()) {
143 addOutputRecursive(outputs...);
148 template<
typename... Outputs>
149 void finish(
bool const storeAdjoints, Outputs&... outputs) {
150 Tape& tape = Type::getTape();
152 if (tape.isActive()) {
153 addOutputRecursive(outputs...);
156 storeInputAdjoints();
164 restoreInputAdjoints();
173 void addInputLogic(
Type const& input) {
175 Identifier
const& identifier = input.getIdentifier();
176 if (Type::getTape().getPassiveIndex() != identifier) {
182 void addInputRecursive() {
186 template<
typename... Inputs>
187 void addInputRecursive(
Type const& input, Inputs
const&... r) {
188 addInputLogic(input);
189 addInputRecursive(r...);
192 void addOutputLogic(
Type& output) {
194 Identifier
const& identifier = output.getIdentifier();
195 if (Type::getTape().getPassiveIndex() != identifier) {
202 void addOutputRecursive() {
206 template<
typename... Outputs>
207 void addOutputRecursive(
Type& output, Outputs&... r) {
208 addOutputLogic(output);
209 addOutputRecursive(r...);
212 void storeInputAdjoints() {
213 Tape& tape = Type::getTape();
219 for (
size_t i = 0; i <
inputData.size(); ++i) {
221 Gradient& adjoint = tape.gradient(index);
227 void restoreInputAdjoints() {
228 Tape& tape = Type::getTape();
230 for (
size_t i = 0; i <
inputData.size(); ++i) {
236 void doPreaccumulation() {
238 Tape& tape = Type::getTape();
240 Position endPos = tape.getPosition();
246 tape.resizeAdjointVector();
247 tape.beginUseAdjointVector();
256 tape.endUseAdjointVector();
258 for (
size_t curOut = 0; curOut <
outputData.size(); ++curOut) {
266 Identifier lastIdentifier = value.getIdentifier();
267 bool staggeringActive =
false;
284 while (nonZerosLeft > 0) {
286 int jacobiansForStatement = nonZerosLeft;
289 if (staggeringActive) {
290 jacobiansForStatement -= 1;
293 nonZerosLeft -= jacobiansForStatement;
295 Identifier storedIdentifier = lastIdentifier;
298 tape.storeManual(value.getValue(), lastIdentifier, jacobiansForStatement + (int)staggeringActive);
299 if (staggeringActive) {
300 tape.pushJacobianManual(1.0, 0.0, storedIdentifier);
304 while (jacobiansForStatement > 0) {
307 jacobiansForStatement -= 1;
312 staggeringActive =
true;
315 value.getIdentifier() = lastIdentifier;
318 tape.destroyIdentifier(value.value(), value.getIdentifier());
324#ifndef DOXYGEN_DISABLE
330 struct PreaccumulationHelperNoOpBase {
334 template<
typename... Inputs>
335 void addInput(Inputs
const&... inputs) {
341 template<
typename... Inputs>
342 void start(Inputs
const&... inputs) {
348 template<
typename... Outputs>
349 void addOutput(Outputs&... outputs) {
355 template<
typename... Outputs>
356 void finish(
bool const storeAdjoints, Outputs&... outputs) {
363 template<
typename Type>
365 :
public PreaccumulationHelperNoOpBase {};
369 struct PreaccumulationHelper<double, void> :
public PreaccumulationHelperNoOpBase {};
378 template<
typename T_Type>
379 struct PreaccumulationHelper<
381 TagTapeReverse<typename T_Type::Real, typename T_Type::Tape::Tag>>::type> {
384 using Type =
CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
386 using Tape =
CODI_DD(
typename Type::Tape,
CODI_T(TagTapeReverse<Type, int>));
387 using Tag =
typename Tape::Tag;
391 std::vector<Type const*> inputLocations;
392 std::vector<Type*> outputLocations;
401 template<
typename... Inputs>
402 void addInput(Inputs
const&... inputs) {
403 Tape& tape = getTape();
405 if (tape.isActive() && tape.isPreaccumulationHandlingEnabled()) {
406 addInputRecursive(inputs...);
411 template<
typename... Inputs>
412 void start(Inputs
const&... inputs) {
413 Tape& tape = getTape();
415 if (tape.isActive() && tape.isPreaccumulationHandlingEnabled()) {
416 inputLocations.clear();
417 outputLocations.clear();
418 oldTag = tape.getCurTag();
419 tape.setCurTag(tape.getPreaccumulationHandlingTag());
421 addInputRecursive(inputs...);
426 template<
typename... Outputs>
428 Tape& tape = getTape();
430 if (tape.isActive() && tape.isPreaccumulationHandlingEnabled()) {
431 addOutputRecursive(outputs...);
436 template<
typename... Outputs>
437 void finish(
bool const storeAdjoints, Outputs&... outputs) {
440 Tape& tape = getTape();
442 if (tape.isActive() && tape.isPreaccumulationHandlingEnabled()) {
443 addOutputRecursive(outputs...);
445 tape.setCurTag(oldTag);
446 for (
Type const* curInput : inputLocations) {
447 tape.setTagOnVariable(*curInput);
449 for (
Type* curOutput : outputLocations) {
450 tape.setTagOnVariable(*curOutput);
458 void addInputRecursive() {
462 template<
typename... Inputs>
463 void addInputRecursive(
Type const& input, Inputs
const&... r) {
465 addInputRecursive(r...);
468 void handleInput(
Type const& input) {
469 inputLocations.push_back(&input);
470 getTape().setTagOnVariable(input);
474 void addOutputRecursive() {
478 template<
typename... Outputs>
479 void addOutputRecursive(
Type& output, Outputs&... r) {
480 handleOutput(output);
481 addOutputRecursive(r...);
484 void handleOutput(
Type& value) {
485 outputLocations.push_back(&value);
489 return Type::getTape();
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:457
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:94
#define CODI_T(...)
Abbreviation for CODI_TEMPLATE.
Definition macros.hpp:111
size_t constexpr MaxArgumentSize
Maximum number of arguments in a statement.
Definition config.h:120
typename std::enable_if< IsForwardTape< Tape >::value >::type EnableIfForwardTape
Enable if wrapper for IsForwardTape.
Definition tapeTraits.hpp:88
CoDiPack - Code Differentiation Package.
Definition codi.hpp:90
void CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:46
std::enable_if< std::is_same< T1, T2 >::value, R > enable_if_same
Enable if abbreviation for "std::is_same".
Definition enableIfHelpers.hpp:51
@ Manual
Do not perform any bounds checking, locking, or resizing.
static void computeJacobian(Tape &tape, Position const &start, Position const &end, Identifier const *input, size_t const inputSize, Identifier const *output, size_t const outputSize, Jac &jac, AdjointsManagement adjointsManagement=AdjointsManagement::Automatic)
Compute the Jacobian with multiple tape sweeps.
Definition algorithms.hpp:141
static void notifyPreaccFinishListeners(Tape &tape)
Invoke callbacks for PreaccFinish events.
Definition eventSystem.hpp:579
static void notifyPreaccAddOutputListeners(Tape &tape, Real &value, Identifier &identifier)
Invoke callbacks for PreaccAddOutput events.
Definition eventSystem.hpp:636
static void notifyPreaccAddInputListeners(Tape &tape, Real const &value, Identifier const &identifier)
Invoke callbacks for PreaccAddInput events.
Definition eventSystem.hpp:607
static void notifyPreaccStartListeners(Tape &tape)
Invoke callbacks for PreaccStart events.
Definition eventSystem.hpp:553
Adds counting of nonzero entries.
Definition jacobian.hpp:129
int & nonZerosRow(size_t const i)
Reference to the number of nonzero entries for the specified row.
Definition jacobian.hpp:167
void resize(size_t const m, size_t const n)
Resize the Jacobian.
Definition jacobian.hpp:161
size_t getM() const
Get size of rows (output variables).
Definition jacobian.hpp:78
size_t getN() const
Get size of columns (input variables).
Definition jacobian.hpp:83
Stores the Jacobian matrix for a code section.
Definition preaccumulationHelper.hpp:76
void finish(bool const storeAdjoints, Outputs &... outputs)
Finish the preaccumulation region and perform the preaccumulation. See addOutput() for outputs.
Definition preaccumulationHelper.hpp:149
std::vector< Gradient > storedAdjoints
If adjoints of inputs should be stored, before the preaccumulation.
Definition preaccumulationHelper.hpp:100
Position startPos
Starting position for the region.
Definition preaccumulationHelper.hpp:99
PreaccumulationHelper()
Constructor.
Definition preaccumulationHelper.hpp:106
typename Type::Tape Tape
See LhsExpressionInterface.
Definition preaccumulationHelper.hpp:87
void addInput(Inputs const &... inputs)
Add multiple additional inputs. Inputs need to be of type Type. Called after start().
Definition preaccumulationHelper.hpp:111
std::vector< Identifier > inputData
Definition preaccumulationHelper.hpp:90
T_Type Type
See PreaccumulationHelper.
Definition preaccumulationHelper.hpp:80
typename Tape::Position Position
See PositionalEvaluationTapeInterface.
Definition preaccumulationHelper.hpp:88
typename Type::Identifier Identifier
See LhsExpressionInterface.
Definition preaccumulationHelper.hpp:83
typename Type::Gradient Gradient
See LhsExpressionInterface.
Definition preaccumulationHelper.hpp:84
std::vector< Type * > outputValues
Definition preaccumulationHelper.hpp:94
std::vector< Identifier > outputData
Definition preaccumulationHelper.hpp:92
typename Type::Real Real
See LhsExpressionInterface.
Definition preaccumulationHelper.hpp:82
void start(Inputs const &... inputs)
Starts a preaccumulation region. Resets the internal state. See addInputs() for inputs.
Definition preaccumulationHelper.hpp:121
void addOutput(Outputs &... outputs)
Add multiple additional outputs. Outputs need to be of type Type. Called before finish().
Definition preaccumulationHelper.hpp:139
JacobianCountNonZerosRow< Real > jacobian
Jacobian for the preaccumulation.
Definition preaccumulationHelper.hpp:101