40#include <codi/tools/lowlevelFunctions/eigenWrappers.hpp>
41#include <codi/tools/lowlevelFunctions/generationHelperCoDiPack.hpp>
42#include <codi/tools/lowlevelFunctions/lowLevelFunctionCreationUtilities.hpp>
47 template<Eigen::StorageOptions eigenStore,
typename Type>
52 using Tape =
typename Type::Tape;
64 using Trait_A =
typename LLFH::ActiveStoreTrait<Type*>;
65 using Trait_B =
typename LLFH::ActiveStoreTrait<Type*>;
66 using Trait_R =
typename LLFH::ActiveStoreTrait<Type*>;
67 using Trait_n =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
68 using Trait_k =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
69 using Trait_m =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
72 typename LLFH::ActivityStoreType activityStore = {};
73 typename Trait_A::ArgumentStore A_store = {};
74 typename Trait_B::ArgumentStore B_store = {};
75 typename Trait_R::ArgumentStore R_store = {};
76 typename Trait_n::Store n = {};
77 typename Trait_k::Store k = {};
78 typename Trait_m::Store m = {};
80 bool active_A =
false;
81 bool active_B =
false;
84 LLFH::restoreActivity(&dataStore, activityStore);
85 active_A = LLFH::getActivity(activityStore, 0);
86 active_B = LLFH::getActivity(activityStore, 1);
87 Trait_n::restore(&dataStore, allocator, 1,
true, n);
88 Trait_k::restore(&dataStore, allocator, 1,
true, k);
89 Trait_m::restore(&dataStore, allocator, 1,
true, m);
90 Trait_A::restore(&dataStore, allocator, n * k, LLFH::createRestoreActions(
true,
false, active_A, active_B),
92 Trait_B::restore(&dataStore, allocator, k * m, LLFH::createRestoreActions(
true,
false, active_B, active_A),
94 Trait_R::restore(&dataStore, allocator, n * m, LLFH::createRestoreActions(
false,
true,
false,
true), R_store);
96 if (Tape::HasPrimalValues) {
98 if (active_A && active_B) {
99 Trait_A::getPrimalsFromVector(adjoints, n * k, A_store.identifierIn(), A_store.primal());
101 if (active_B && active_A) {
102 Trait_B::getPrimalsFromVector(adjoints, k * m, B_store.identifierIn(), B_store.primal());
106 for (
size_t curDim = 0; curDim < adjoints->
getVectorSize(); curDim += 1) {
109 Trait_A::getGradients(adjoints, n * k,
false, A_store.identifierIn(), A_store.gradientIn(), curDim);
112 Trait_B::getGradients(adjoints, k * m,
false, B_store.identifierIn(), B_store.gradientIn(), curDim);
114 if (Tape::HasPrimalValues && 0 == curDim) {
115 if (!Tape::LinearIndexHandling) {
117 Trait_R::getPrimalsFromVector(adjoints, n * m, R_store.identifierOut(), R_store.oldPrimal());
121 Trait_R::setPrimalsIntoVector(adjoints, n * m, R_store.identifierOut(), R_store.primal());
125 callForward(A_store.primal(), active_A, A_store.gradientIn(), B_store.primal(), active_B,
126 B_store.gradientIn(), R_store.primal(), R_store.gradientOut(), n, k, m);
128 Trait_R::setGradients(adjoints, n * m,
false, R_store.identifierOut(), R_store.gradientOut(), curDim);
144 codi::CODI_UNUSED(A, active_A, A_d_in, B, active_B, B_d_in, R, R_d_out, n, k, m);
146 mapEigen<eigenStore>(R_d_out, n, m) += mapEigen<eigenStore>(A_d_in, n, k) * mapEigen<eigenStore>(B, k, m);
149 mapEigen<eigenStore>(R_d_out, n, m) += mapEigen<eigenStore>(A, n, k) * mapEigen<eigenStore>(B_d_in, k, m);
151 mapEigen<eigenStore>(R, n, m) = mapEigen<eigenStore>(A, n, k) * mapEigen<eigenStore>(B, k, m);
161 using Trait_A =
typename LLFH::ActiveStoreTrait<Type*>;
162 using Trait_B =
typename LLFH::ActiveStoreTrait<Type*>;
163 using Trait_R =
typename LLFH::ActiveStoreTrait<Type*>;
164 using Trait_n =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
165 using Trait_k =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
166 using Trait_m =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
169 typename LLFH::ActivityStoreType activityStore = {};
170 typename Trait_A::ArgumentStore A_store = {};
171 typename Trait_B::ArgumentStore B_store = {};
172 typename Trait_R::ArgumentStore R_store = {};
173 typename Trait_n::Store n = {};
174 typename Trait_k::Store k = {};
175 typename Trait_m::Store m = {};
177 bool active_A =
false;
178 bool active_B =
false;
181 LLFH::restoreActivity(&dataStore, activityStore);
182 active_A = LLFH::getActivity(activityStore, 0);
183 active_B = LLFH::getActivity(activityStore, 1);
184 Trait_n::restore(&dataStore, allocator, 1,
true, n);
185 Trait_k::restore(&dataStore, allocator, 1,
true, k);
186 Trait_m::restore(&dataStore, allocator, 1,
true, m);
187 Trait_A::restore(&dataStore, allocator, n * k, LLFH::createRestoreActions(
true,
false, active_A, active_B),
189 Trait_B::restore(&dataStore, allocator, k * m, LLFH::createRestoreActions(
true,
false, active_B, active_A),
191 Trait_R::restore(&dataStore, allocator, n * m, LLFH::createRestoreActions(
false,
true,
false,
true), R_store);
193 if (Tape::HasPrimalValues) {
194 if (!Tape::LinearIndexHandling) {
196 Trait_R::setPrimalsIntoVector(adjoints, n * m, R_store.identifierOut(), R_store.oldPrimal());
200 if (active_A && active_B) {
201 Trait_A::getPrimalsFromVector(adjoints, n * k, A_store.identifierIn(), A_store.primal());
203 if (active_B && active_A) {
204 Trait_B::getPrimalsFromVector(adjoints, k * m, B_store.identifierIn(), B_store.primal());
208 for (
size_t curDim = 0; curDim < adjoints->
getVectorSize(); curDim += 1) {
210 Trait_R::getGradients(adjoints, n * m,
true, R_store.identifierOut(), R_store.gradientOut(), curDim);
213 callReverse(A_store.primal(), active_A, A_store.gradientIn(), B_store.primal(), active_B,
214 B_store.gradientIn(), R_store.primal(), R_store.gradientOut(), n, k, m);
217 Trait_A::setGradients(adjoints, n * k,
true, A_store.identifierIn(), A_store.gradientIn(), curDim);
220 Trait_B::setGradients(adjoints, k * m,
true, B_store.identifierIn(), B_store.gradientIn(), curDim);
237 codi::CODI_UNUSED(A, active_A, A_b_in, B, active_B, B_b_in, R, R_b_out, n, k, m);
239 mapEigen<eigenStore>(A_b_in, n, k) =
240 mapEigen<eigenStore>(R_b_out, n, m) * mapEigen<eigenStore>(B, k, m).transpose();
243 mapEigen<eigenStore>(B_b_in, k, m) =
244 mapEigen<eigenStore>(A, n, k).transpose() * mapEigen<eigenStore>(R_b_out, n, m);
255 using Trait_A =
typename LLFH::ActiveStoreTrait<Type*>;
256 using Trait_B =
typename LLFH::ActiveStoreTrait<Type*>;
257 using Trait_R =
typename LLFH::ActiveStoreTrait<Type*>;
258 using Trait_n =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
259 using Trait_k =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
260 using Trait_m =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
263 typename LLFH::ActivityStoreType activityStore = {};
264 typename Trait_A::ArgumentStore A_store = {};
265 typename Trait_B::ArgumentStore B_store = {};
266 typename Trait_R::ArgumentStore R_store = {};
267 typename Trait_n::Store n = {};
268 typename Trait_k::Store k = {};
269 typename Trait_m::Store m = {};
271 bool active_A =
false;
272 bool active_B =
false;
275 LLFH::restoreActivity(&dataStore, activityStore);
276 active_A = LLFH::getActivity(activityStore, 0);
277 active_B = LLFH::getActivity(activityStore, 1);
278 Trait_n::restore(&dataStore, allocator, 1,
true, n);
279 Trait_k::restore(&dataStore, allocator, 1,
true, k);
280 Trait_m::restore(&dataStore, allocator, 1,
true, m);
281 Trait_A::restore(&dataStore, allocator, n * k, LLFH::createRestoreActions(
true,
false, active_A, active_B),
283 Trait_B::restore(&dataStore, allocator, k * m, LLFH::createRestoreActions(
true,
false, active_B, active_A),
285 Trait_R::restore(&dataStore, allocator, n * m, LLFH::createRestoreActions(
false,
true,
false,
true), R_store);
292 Tape& tape = Type::getTape();
297 using Trait_A =
typename LLFH::ActiveStoreTrait<Type*>;
298 using Trait_B =
typename LLFH::ActiveStoreTrait<Type*>;
299 using Trait_R =
typename LLFH::ActiveStoreTrait<Type*>;
300 using Trait_n =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
301 using Trait_k =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
302 using Trait_m =
typename LLFH::PassiveStoreTrait<int, uint8_t>;
305 typename LLFH::ActivityStoreType activityStore = {};
306 typename Trait_A::ArgumentStore A_store = {};
307 typename Trait_B::ArgumentStore B_store = {};
308 typename Trait_R::ArgumentStore R_store = {};
311 bool active_A = Trait_A::isActive(A, n * k);
312 bool active_B = Trait_B::isActive(B, k * m);
313 bool active = active_A | active_B;
320 size_t dataSize = LLFH::countActivitySize();
321 dataSize += Trait_n::countSize(n, 1,
true);
322 dataSize += Trait_k::countSize(k, 1,
true);
323 dataSize += Trait_m::countSize(m, 1,
true);
324 dataSize += Trait_A::countSize(A, n * k, LLFH::createStoreActions(active,
true,
false, active_A, active_B));
325 dataSize += Trait_B::countSize(B, k * m, LLFH::createStoreActions(active,
true,
false, active_B, active_A));
326 dataSize += Trait_R::countSize(R, n * m, LLFH::createStoreActions(active,
false,
true,
false,
true));
330 tape.pushLowLevelFunction(
ID, dataSize, dataStore);
333 LLFH::setActivity(activityStore, 0, active_A);
334 LLFH::setActivity(activityStore, 1, active_B);
335 LLFH::storeActivity(&dataStore, activityStore);
336 Trait_n::store(&dataStore, allocator, n, 1,
true);
337 Trait_k::store(&dataStore, allocator, k, 1,
true);
338 Trait_m::store(&dataStore, allocator, m, 1,
true);
339 Trait_A::store(&dataStore, allocator, A, n * k,
340 LLFH::createStoreActions(active,
true,
false, active_A, active_B), A_store);
341 Trait_B::store(&dataStore, allocator, B, k * m,
342 LLFH::createStoreActions(active,
true,
false, active_B, active_A), B_store);
343 Trait_R::store(&dataStore, allocator, R, n * m, LLFH::createStoreActions(active,
false,
true,
false,
true),
347 Trait_A::store(
nullptr, allocator, A, n * k,
348 LLFH::createStoreActions(active,
true,
false, active_A, active_B), A_store);
349 Trait_B::store(
nullptr, allocator, B, k * m,
350 LLFH::createStoreActions(active,
true,
false, active_B, active_A), B_store);
351 Trait_R::store(
nullptr, allocator, R, n * m, LLFH::createStoreActions(active,
false,
true,
false,
true),
355 callPrimal(active, A_store.primal(), active_A, A_store.identifierIn(), B_store.primal(), active_B,
356 B_store.identifierIn(), R_store.primal(), R_store.identifierOut(), n, k, m);
358 Trait_R::setExternalFunctionOutput(active, R, n * m, R_store.identifierOut(), R_store.primal(),
359 R_store.oldPrimal());
373 codi::CODI_UNUSED(active, A, active_A, A_i_in, B, active_B, B_i_in, R, R_i_out, n, k, m);
374 mapEigen<eigenStore>(R, n, m) = mapEigen<eigenStore>(A, n, k) * mapEigen<eigenStore>(B, k, m);
378 mapEigen<eigenStore>(R_i_out, n, m).setZero();
380 mapEigen<eigenStore>(R_i_out, n, m).colwise() += mapEigen<eigenStore>(A_i_in, n, k).rowwise().any();
383 mapEigen<eigenStore>(R_i_out, n, m).rowwise() += mapEigen<eigenStore>(B_i_in, k, m).colwise().any();
397 template<Eigen::StorageOptions eigenStore,
typename Type>
409 template<Eigen::StorageOptions eigenStore,
typename Type>
420 template<
typename Type>
422 matrixMatrixMultiplication<Eigen::StorageOptions::RowMajor>(A, B, R, n, k, m);
430 template<
typename Type>
432 matrixMatrixMultiplication<Eigen::StorageOptions::ColMajor>(A, B, R, n, k, m);
#define CODI_INLINE
See codi::Config::ForcedInlines.
Definition config.h:457
#define codiAssert(x)
See codi::Config::EnableAssert.
Definition config.h:432
uint16_t LowLevelFunctionToken
Token type for low level functions in the tapes.
Definition config.h:108
size_t constexpr LowLevelFunctionTokenInvalid
Invalid low level function token.
Definition config.h:114
CoDiPack - Code Differentiation Package.
Definition codi.hpp:90
void matrixMatrixMultiplicationRowMajor(Type const *A, Type const *B, Type *R, int n, int k, int m)
Definition matrixMatrixMultiplication.hpp:421
void CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:46
void matrixMatrixMultiplication(Type const *A, Type const *B, Type *R, int n, int k, int m)
Definition matrixMatrixMultiplication.hpp:410
void matrixMatrixMultiplicationColMajor(Type const *A, Type const *B, Type *R, int n, int k, int m)
Definition matrixMatrixMultiplication.hpp:431
double Real
The type with no CoDiPack values.
Definition activeArgumentStoreTraits.hpp:207
int Identifier
The type for holding the identifiers.
Definition activeArgumentStoreTraits.hpp:208
Real Gradient
The type that can represent the gradient values.
Definition activeArgumentStoreTraits.hpp:209
Definition byteDataView.hpp:51
Low level function generation for matrixMatrixMultiplication.
Definition matrixMatrixMultiplication.hpp:48
static CODI_INLINE void callPrimal(bool active, typename codi::ActiveArgumentStoreTraits< Type * >::Real const *A, bool active_A, typename codi::ActiveArgumentStoreTraits< Type * >::Identifier const *A_i_in, typename codi::ActiveArgumentStoreTraits< Type * >::Real const *B, bool active_B, typename codi::ActiveArgumentStoreTraits< Type * >::Identifier const *B_i_in, typename codi::ActiveArgumentStoreTraits< Type * >::Real *R, typename codi::ActiveArgumentStoreTraits< Type * >::Identifier *R_i_out, int n, int k, int m)
Primal computation function.
Definition matrixMatrixMultiplication.hpp:365
static codi::Config::LowLevelFunctionToken ID
Id for this function.
Definition matrixMatrixMultiplication.hpp:55
static CODI_INLINE void callReverse(typename codi::ActiveArgumentStoreTraits< Type * >::Real const *A, bool active_A, typename codi::ActiveArgumentStoreTraits< Type * >::Gradient *A_b_in, typename codi::ActiveArgumentStoreTraits< Type * >::Real const *B, bool active_B, typename codi::ActiveArgumentStoreTraits< Type * >::Gradient *B_b_in, typename codi::ActiveArgumentStoreTraits< Type * >::Real *R, typename codi::ActiveArgumentStoreTraits< Type * >::Gradient *R_b_out, typename codi::PassiveArgumentStoreTraits< int, uint8_t >::Store n, typename codi::PassiveArgumentStoreTraits< int, uint8_t >::Store k, typename codi::PassiveArgumentStoreTraits< int, uint8_t >::Store m)
Reverse function for derivative evaluation.
Definition matrixMatrixMultiplication.hpp:228
static CODI_INLINE void reverse(Tape *tape, codi::ByteDataView &dataStore, AdjointVectorAccess adjoints)
Function for reverse interpretation.
Definition matrixMatrixMultiplication.hpp:155
static CODI_INLINE void evalAndStore(Type const *A, Type const *B, Type *R, int n, int k, int m)
Store on tape.
Definition matrixMatrixMultiplication.hpp:291
static CODI_INLINE void del(Tape *tape, codi::ByteDataView &dataStore)
Function for deletion of contents.
Definition matrixMatrixMultiplication.hpp:249
static CODI_INLINE void callForward(typename codi::ActiveArgumentStoreTraits< Type * >::Real const *A, bool active_A, typename codi::ActiveArgumentStoreTraits< Type * >::Gradient *A_d_in, typename codi::ActiveArgumentStoreTraits< Type * >::Real const *B, bool active_B, typename codi::ActiveArgumentStoreTraits< Type * >::Gradient *B_d_in, typename codi::ActiveArgumentStoreTraits< Type * >::Real *R, typename codi::ActiveArgumentStoreTraits< Type * >::Gradient *R_d_out, typename codi::PassiveArgumentStoreTraits< int, uint8_t >::Store n, typename codi::PassiveArgumentStoreTraits< int, uint8_t >::Store k, typename codi::PassiveArgumentStoreTraits< int, uint8_t >::Store m)
Forward function for derivative evaluation.
Definition matrixMatrixMultiplication.hpp:135
static CODI_INLINE void forward(Tape *tape, codi::ByteDataView &dataStore, AdjointVectorAccess adjoints)
Function for forward interpretation.
Definition matrixMatrixMultiplication.hpp:58
static CODI_INLINE void registerOnTape()
Register function on tape.
Definition matrixMatrixMultiplication.hpp:389
typename Type::Tape Tape
Abbreviation for tape.
Definition matrixMatrixMultiplication.hpp:52
Helper structure for storing low level functions and their arguments on a tape.
Definition lowLevelFunctionCreationUtilities.hpp:128
Low level function entry on the tape. See LowLevelFunctionTapeInterface for details.
Definition lowLevelFunctionEntry.hpp:67
T Store
Type for the variable declaration for restoring the data.
Definition passiveArgumentStoreTraits.hpp:61
Allocator for temporary used memory.
Definition temporaryMemory.hpp:54
bool isEmpty()
Returns true if no data is currently allocated.
Definition temporaryMemory.hpp:71
void free()
Free all allocated memory. No destructors are called. Stored pointers and resources need to be deallo...
Definition temporaryMemory.hpp:110
Unified access to the adjoint vector and primal vector in a tape evaluation.
Definition vectorAccessInterface.hpp:91
virtual size_t getVectorSize() const =0
Vector size in the current tape evaluation.