37#include <medi/adToolInterface.h>
38#include <medi/ampi/ampiMisc.h>
40#include <medi/adToolImplCommon.hpp>
41#include <medi/adjointInterface.hpp>
42#include <medi/ampi/op.hpp>
43#include <medi/ampi/typeDefault.hpp>
44#include <medi/ampi/types/indexTypeHelper.hpp>
47#include "../../expressions/lhsExpressionInterface.hpp"
49#include "../../tapes/interfaces/fullTapeInterface.hpp"
50#include "../../tapes/misc/adjointVectorAccess.hpp"
55#ifndef DOXYGEN_DISABLE
57 #define MEDI_1_4_OR_GREATER MEDI_MAJOR_VERSION > 1 || (MEDI_MAJOR_VERSION == 1 && MEDI_MINOR_VERSION >= 4)
59 template<
typename T_Type>
60 struct CoDiMeDiAdjointInterfaceWrapper :
public medi::AdjointInterface {
63 using Type =
CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
65 using Real =
typename Type::Real;
66 using Identifier =
typename Type::Identifier;
68 VectorAccessInterface<Real, Identifier>* codiInterface;
72 CoDiMeDiAdjointInterfaceWrapper(VectorAccessInterface<Real, Identifier>* interface)
73 : codiInterface(interface), vecSize((int)interface->getVectorSize()) {}
76 return elements * vecSize;
85 Identifier* indices = (Identifier*)i;
87 for (
int pos = 0; pos < elements; ++pos) {
88 codiInterface->getAdjointVec(indices[pos], &adjoints[pos * vecSize]);
89 codiInterface->resetAdjointVec(indices[pos]);
93 CODI_INLINE_NO_FA void updateAdjoints(
void const* i,
void const* a,
int elements)
const {
95 Identifier* indices = (Identifier*)i;
97 for (
int pos = 0; pos < elements; ++pos) {
98 codiInterface->updateAdjointVec(indices[pos], &adjoints[pos * vecSize]);
102 CODI_INLINE_NO_FA void getPrimals(
void const* i,
void const* p,
int elements)
const {
104 Identifier* indices = (Identifier*)i;
106 for (
int pos = 0; pos < elements; ++pos) {
107 primals[pos] = codiInterface->getPrimal(indices[pos]);
111 CODI_INLINE_NO_FA void setPrimals(
void const* i,
void const* p,
int elements)
const {
113 Identifier* indices = (Identifier*)i;
115 for (
int pos = 0; pos < elements; ++pos) {
116 codiInterface->setPrimal(indices[pos], primals[pos]);
120 CODI_INLINE_NO_FA void combineAdjoints(
void* b,
int const elements,
int const ranks)
const {
123 for (
int curRank = 1; curRank < ranks; ++curRank) {
124 for (
int curPos = 0; curPos < elements; ++curPos) {
125 for (
int dim = 0;
dim < vecSize; ++
dim) {
126 buf[curPos * vecSize +
dim] += buf[(elements * curRank + curPos) * vecSize + dim];
133 buf = (
void*)(
new Real[size * vecSize]);
145 buf = (
void*)(
new Real[size * vecSize]);
157 template<
typename T_Type>
158 struct CoDiPackReverseTool
159 :
public medi::ADToolImplCommon<CoDiPackReverseTool<T_Type>, T_Type::Tape::RequiresPrimalRestore, false, T_Type,
160 typename T_Type::Gradient, typename T_Type::Real, typename T_Type::Identifier> {
164 using Type =
CODI_DD(T_Type, CODI_DEFAULT_LHS_EXPRESSION);
165 using PrimalType =
typename Type::Real;
166 using AdjointType = void;
167 using ModifiedType = Type;
168 using IndexType =
typename Type::Identifier;
171 using Tape =
CODI_DD(
typename Type::Tape, CODI_DEFAULT_TAPE);
172 using IterCallback =
typename ExternalFunction<Tape>::IterCallback;
175 medi::OperatorHelper<medi::FunctionHelper<Type, Type,
typename Type::PassiveReal,
typename Type::Gradient,
176 typename Type::Identifier, CoDiPackReverseTool> >;
178 using Base = medi::ADToolImplCommon<CoDiPackReverseTool, Tape::RequiresPrimalRestore,
false, Type,
179 typename Type::Gradient, PrimalType, IndexType>;
187 CoDiPackReverseTool(MPI_Datatype primalMpiType, MPI_Datatype adjointMpiType)
188 : Base(primalMpiType, adjointMpiType), opHelper() {
192 ~CoDiPackReverseTool() {
201 return getTape().isActive();
212 getTape().pushExternalFunction(
213 ExternalFunction<Tape>::create(callHandleReverse, h, deleteHandle, callHandleForward, callHandlePrimal,
214 callHandleIterateInputs, callHandleIterateOutputs));
218 medi::AMPI_Op convertOperator(medi::AMPI_Op op)
const {
219 return opHelper.convertOperator(op);
229 return value.getIdentifier();
232 static CODI_INLINE_NO_FA void registerValue(Type& value, PrimalType& oldPrimal, IndexType& index) {
233 bool wasActive = getTape().isIdentifierActive(value.getIdentifier());
234 value.getIdentifier() = IndexType();
238 if (Tape::LinearIndexHandling) {
240 value.getIdentifier() = index;
243 if (Tape::HasPrimalValues) {
244 getTape().setPrimal(index, value.getValue());
246 if (Tape::RequiresPrimalRestore) {
247 oldPrimal = PrimalType(0.0);
250 PrimalType primal = getTape().registerExternalFunctionOutput(value);
251 if (Tape::RequiresPrimalRestore) {
254 index = value.getIdentifier();
257 if (Tape::RequiresPrimalRestore) {
258 oldPrimal = PrimalType(0.0);
260 if (!Tape::LinearIndexHandling) {
261 index = getTape().getPassiveIndex();
267 IndexType oldIndex = value.getIdentifier();
269 value.getIdentifier() = oldIndex;
274 if (Tape::LinearIndexHandling) {
275 IndexType oldIndex = value.getIdentifier();
276 getTape().registerInput(value);
277 index = value.getIdentifier();
278 value.getIdentifier() = oldIndex;
284 return value.getValue();
287 static CODI_INLINE_NO_FA void setIntoModifyBuffer(ModifiedType& modValue, Type
const& value) {
293 static CODI_INLINE_NO_FA void getFromModifyBuffer(ModifiedType
const& modValue, Type& value) {
299 static PrimalType getPrimalFromMod(ModifiedType
const& modValue) {
300 return modValue.value();
303 static void setPrimalToMod(ModifiedType& modValue, PrimalType
const& value) {
304 modValue.value() = value;
307 static void modifyDependency(ModifiedType& inval, ModifiedType& inoutval) {
308 bool active = getTape().isIdentifierActive(inoutval.getIdentifier()) ||
309 getTape().isIdentifierActive(inval.getIdentifier());
311 inoutval.getIdentifier() = getTape().getInvalidIndex();
313 inoutval.getIdentifier() = getTape().getPassiveIndex();
319 static void callHandleReverse(Tape* tape,
void* h, VectorAccessInterface<PrimalType, IndexType>* ah) {
322 medi::HandleBase* handle =
static_cast<medi::HandleBase*
>(h);
323 CoDiMeDiAdjointInterfaceWrapper<Type> ahWrapper(ah);
324 handle->funcReverse(handle, &ahWrapper);
327 static void callHandleForward(Tape* tape,
void* h, VectorAccessInterface<PrimalType, IndexType>* ah) {
330 medi::HandleBase* handle =
static_cast<medi::HandleBase*
>(h);
331 CoDiMeDiAdjointInterfaceWrapper<Type> ahWrapper(ah);
332 handle->funcForward(handle, &ahWrapper);
335 static void callHandlePrimal(Tape* tape,
void* h, VectorAccessInterface<PrimalType, IndexType>* ah) {
338 medi::HandleBase* handle =
static_cast<medi::HandleBase*
>(h);
339 CoDiMeDiAdjointInterfaceWrapper<Type> ahWrapper(ah);
340 handle->funcPrimal(handle, &ahWrapper);
343 static void deleteHandle(Tape* tape,
void* h) {
346 medi::HandleBase* handle =
static_cast<medi::HandleBase*
>(h);
350 static void callHandleIterateInputs(Tape* tape,
void* h, IterCallback func,
void* userData) {
352 #if MEDI_1_4_OR_GREATER
353 medi::HandleBase* handle =
static_cast<medi::HandleBase*
>(h);
354 handle->funcIterateInputIds(handle, (::medi::CallbackFunc)func, userData);
357 CODI_EXCEPTION(
"Identifier iteration requires at leas MeDiPack 1.4.0.");
361 static void callHandleIterateOutputs(Tape* tape,
void* h, IterCallback func,
void* userData) {
364 #if MEDI_1_4_OR_GREATER
365 medi::HandleBase* handle =
static_cast<medi::HandleBase*
>(h);
366 handle->funcIterateOutputIds(handle, (::medi::CallbackFunc)func, userData);
369 CODI_EXCEPTION(
"Identifier iteration requires at leas MeDiPack 1.4.0.");
373 static Tape& getTape() {
374 return Type::getTape();
#define CODI_INLINE_NO_FA
See codi::Config::ForcedInlines.
Definition config.h:471
#define CODI_DD(Type, Default)
Abbreviation for CODI_DECLARE_DEFAULT.
Definition macros.hpp:97
typename TraitsImplementation< Gradient >::Real Real
The base value used in the gradient entries.
Definition gradientTraits.hpp:92
inlinesize_t constexpr dim()
Number of dimensions this gradient value has.
Definition gradientTraits.hpp:96
inlinetypename DataExtraction< Type >::Real getValue(Type const &v)
Extract an aggregate of primal values from an aggregate of active types.
Definition realTraits.hpp:381
CoDiPack - Code Differentiation Package.
Definition codi.hpp:102
inlinevoid CODI_UNUSED(Args const &...)
Disable unused warnings for an arbitrary number of arguments.
Definition macros.hpp:55