33 const ArrayRef<bool> returnPrimals,
34 const ArrayRef<bool> returnShadows) {
35 auto inst = oBB->getTerminator();
39 auto newInst = nBB->getTerminator();
41 OpBuilder nBuilder(inst);
42 nBuilder.setInsertionPointToEnd(nBB);
44 if (
auto binst = dyn_cast<BranchOpInterface>(inst)) {
53 SmallVector<mlir::Value, 2> retargs;
55 for (
auto &&[ret, returnPrimal, returnShadow] :
56 llvm::zip(inst->getOperands(), returnPrimals, returnShadows)) {
64 Type retTy = cast<AutoDiffTypeInterface>(ret.getType()).getShadowType();
65 auto toret = cast<AutoDiffTypeInterface>(retTy).createNullValue(
66 nBuilder, ret.getLoc());
67 retargs.push_back(toret);
73 dyn_cast<AutoDiffFunctionInterface>(gutils->
newFunc.getOperation())) {
74 nBuilder.setInsertionPointToEnd(nBB);
75 fnIface.createReturn(nBuilder, newInst->getLoc(), retargs);
78 newInst->create(newInst->getLoc(), newInst->getName(), TypeRange(),
79 retargs, newInst->getAttrs(), mlir::PropertyRef(),
80 newInst->getSuccessors(), newInst->getNumRegions()));
82 gutils->
erase(newInst);
90 FunctionOpInterface fn, std::vector<DIFFE_TYPE> RetActivity,
92 std::vector<bool> returnPrimals,
DerivativeMode mode,
bool freeMemory,
93 size_t width, mlir::Type addedType,
MFnTypeInfo type_args,
94 std::vector<bool> overwritten_args,
void *augmented,
bool omp,
95 llvm::StringRef postpasses,
bool verifyPostPasses,
bool strongZero) {
96 if (fn.getFunctionBody().empty()) {
97 fn.emitError() <<
"cannot differentiate a function without a body: "
98 << fn.getNameAttr() <<
"\n";
101 assert(fn.getFunctionBody().front().getNumArguments() == ArgActivity.size());
102 assert(fn.getFunctionBody().front().getNumArguments() ==
103 overwritten_args.size());
105 MForwardCacheKey tup = {
106 fn, RetActivity, ArgActivity,
109 returnPrimals, mode,
static_cast<unsigned>(width), addedType, type_args,
112 if (ForwardCachedFunctions.find(tup) != ForwardCachedFunctions.end()) {
113 return ForwardCachedFunctions.find(tup)->second;
115 std::vector<bool> returnShadows;
116 for (
auto act : RetActivity) {
119 SmallVector<bool> returnPrimalsP(returnPrimals.begin(), returnPrimals.end());
120 SmallVector<bool> returnShadowsP(returnShadows.begin(), returnShadows.end());
122 *
this, mode, width, fn, TA, type_args, returnPrimalsP, returnShadowsP,
123 RetActivity, ArgActivity, addedType,
124 false, postpasses, verifyPostPasses, strongZero);
125 ForwardCachedFunctions[tup] = gutils->newFunc;
128 ForwardCachedFunctions, tup, gutils->newFunc);
132 const SmallPtrSet<mlir::Block *, 4> guaranteedUnreachable;
136 gutils->forceAugmentedReturns();
162 for (Block &oBB : gutils->oldFunc.getFunctionBody().getBlocks()) {
164 if (guaranteedUnreachable.find(&oBB) != guaranteedUnreachable.end()) {
165 auto newBB = gutils->getNewFromOriginal(&oBB);
167 for (
auto &I : make_early_inc_range(reverse(oBB))) {
168 gutils->eraseIfUnused(&I,
true,
false);
171 OpBuilder builder(gutils->oldFunc.getContext());
172 builder.setInsertionPointToEnd(newBB);
173 LLVM::UnreachableOp::create(builder, gutils->oldFunc.getLoc());
177 assert(oBB.getTerminator());
179 auto first = oBB.begin();
180 auto last = oBB.empty() ? oBB.end() : std::prev(oBB.end());
181 for (
auto it = first; it != last; ++it) {
183 auto res = gutils->visitChild(&*it);
184 valid &= res.succeeded();
208 auto nf = gutils->newFunc;
214 if (postpasses !=
"") {
215 mlir::PassManager pm(nf->getContext());
216 pm.enableVerifier(verifyPostPasses);
217 std::string error_message;
219 mlir::LogicalResult result = mlir::parsePassPipeline(postpasses, pm);
220 if (mlir::failed(result)) {
224 if (!mlir::succeeded(pm.run(nf))) {
static MDiffeGradientUtils * CreateFromClone(MEnzymeLogic &Logic, DerivativeMode mode, unsigned width, FunctionOpInterface todiff, MTypeAnalysis &TA, MFnTypeInfo &oldTypeInfo, const llvm::ArrayRef< bool > returnPrimals, const llvm::ArrayRef< bool > returnShadows, ArrayRef< DIFFE_TYPE > RetActivity, ArrayRef< DIFFE_TYPE > ArgActivity, mlir::Type additionalArg, bool omp, llvm::StringRef postpasses, bool verifyPostPasses, bool strongZero)
FunctionOpInterface CreateForwardDiff(FunctionOpInterface fn, std::vector< DIFFE_TYPE > retType, std::vector< DIFFE_TYPE > constants, MTypeAnalysis &TA, std::vector< bool > returnPrimals, DerivativeMode mode, bool freeMemory, size_t width, mlir::Type addedType, MFnTypeInfo type_args, std::vector< bool > overwritten_args, void *augmented, bool omp, llvm::StringRef postpasses, bool verifyPostPasses, bool strongZero)