19#include "mlir/IR/Builders.h"
20#include "mlir/IR/IRMapping.h"
21#include "mlir/Interfaces/ControlFlowInterfaces.h"
22#include "mlir/Interfaces/FunctionInterfaces.h"
24#include "mlir/Dialect/Func/IR/FuncOps.h"
25#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
26#include "mlir/Dialect/Math/IR/Math.h"
27#include "mlir/Dialect/Tensor/IR/Tensor.h"
29#define DEBUG_TYPE "enzyme"
33#define GEN_PASS_DEF_DIFFERENTIATEWRAPPERPASS
34#include "Passes/Passes.h.inc"
40using namespace enzyme;
45 std::vector<DIFFE_TYPE> ArgActivity;
46 SmallVector<StringRef, 1> split;
47 StringRef(inp.data(), inp.size()).split(split,
',');
48 for (
auto &
str : split) {
49 if (
str ==
"enzyme_dup")
51 else if (
str ==
"enzyme_const")
53 else if (
str ==
"enzyme_dupnoneed")
55 else if (
str ==
"enzyme_active")
58 llvm::errs() <<
"unknown activity to parse, found: '" <<
str <<
"'\n";
59 assert(0 &&
" unknown constant");
66struct DifferentiateWrapperPass
67 :
public enzyme::impl::DifferentiateWrapperPassBase<
68 DifferentiateWrapperPass> {
69 using DifferentiateWrapperPassBase::DifferentiateWrapperPassBase;
71 void runOnOperation()
override {
73 SymbolTableCollection symbolTable;
74 symbolTable.getSymbolTable(getOperation());
76 Operation *symbolOp =
nullptr;
78 symbolOp = symbolTable.lookupSymbolIn<Operation *>(
79 getOperation(), StringAttr::get(getOperation()->getContext(), infn));
81 for (
auto &op : getOperation()->getRegion(0).front()) {
82 auto fn = dyn_cast<FunctionOpInterface>(symbolOp);
85 assert(symbolOp ==
nullptr);
90 llvm::errs() <<
" Could not find function '" << infn
91 <<
"' to differentiate\n";
95 auto fn = cast<FunctionOpInterface>(symbolOp);
97 std::string postpasses =
"";
98 bool verifyPostPasses =
true;
100 std::vector<DIFFE_TYPE> ArgActivity =
103 if (ArgActivity.size() != fn.getNumArguments()) {
105 <<
"Incorrect number of arg activity states for function, found "
106 << ArgActivity.size() <<
" expected "
107 << fn.getFunctionBody().front().getNumArguments();
111 std::vector<DIFFE_TYPE> RetActivity =
113 if (RetActivity.size() != fn.getNumResults()) {
115 <<
"Incorrect number of ret activity states for function, found "
116 << RetActivity.size() <<
" expected " << fn.getNumResults();
119 std::vector<bool> returnPrimal;
120 std::vector<bool> returnShadow;
121 for (
auto act : RetActivity) {
123 returnShadow.push_back(
false);
129 bool freeMemory =
true;
132 std::vector<bool> overwritten_args;
133 for (
auto &a : fn.getFunctionBody().getArguments()) {
135 overwritten_args.push_back(
139 FunctionOpInterface newFunc;
141 newFunc = Logic.CreateForwardDiff(
142 fn, RetActivity, ArgActivity, TA, returnPrimal, mode, freeMemory,
144 nullptr, type_args, overwritten_args,
145 nullptr, omp, postpasses, verifyPostPasses, strongZero);
147 return signalPassFailure();
149 newFunc = Logic.CreateReverseDiff(
150 fn, RetActivity, ArgActivity, TA, returnPrimal, returnShadow, mode,
151 freeMemory, atomicAdd, width,
152 nullptr, type_args, overwritten_args,
153 nullptr, omp, postpasses, verifyPostPasses, strongZero,
162 SymbolTable::setSymbolVisibility(newFunc,
163 SymbolTable::Visibility::Public);
164 SymbolTable::setSymbolName(cast<FunctionOpInterface>(newFunc),
167 SymbolTable::setSymbolName(cast<FunctionOpInterface>(newFunc),
171 getOperation()->walk([&](FunctionOpInterface op) {
removeSummaries(op); });
std::vector< DIFFE_TYPE > parseActivityString(StringRef inp)
static std::string str(AugmentedStruct c)
MFnTypeInfo getAnalyzedTypeInfo(FunctionOpInterface op) const
void removeSummaries(Operation *op)