Enzyme main
Loading...
Searching...
No Matches
EnzymeLogic.h
Go to the documentation of this file.
1#pragma once
2
3#include "mlir/Analysis/DataFlowFramework.h"
4#include "mlir/IR/IRMapping.h"
5#include "mlir/Interfaces/FunctionInterfaces.h"
6
8#include "../../Utils.h"
9#include <functional>
10
11namespace mlir {
12namespace enzyme {
13
14typedef void(buildReturnFunction)(OpBuilder &, mlir::Block *);
15
17
19public:
20 inline bool operator<(const MFnTypeInfo &rhs) const { return false; }
21};
22
24public:
25 MFnTypeInfo getAnalyzedTypeInfo(FunctionOpInterface op) const {
26 return MFnTypeInfo();
27 }
28};
29
31public:
32 // TODO
34 TypeTree query(Value) const { return TypeTree(); }
35 ConcreteType intType(size_t num, Value val, bool errIfNotFound = true,
36 bool pointerIntSame = false) const {
37 if (isa<IntegerType, IndexType>(val.getType())) {
38 return BaseType::Integer;
39 }
40 if (errIfNotFound) {
41 llvm_unreachable("something happened");
42 }
43 return BaseType::Unknown;
44 }
45};
46
48public:
50 FunctionOpInterface todiff;
51 const std::vector<DIFFE_TYPE> retType;
52 const std::vector<DIFFE_TYPE> constant_args;
53 // std::map<llvm::Argument *, bool> uncacheable_args;
54 std::vector<bool> returnUsed;
56 unsigned width;
57 mlir::Type additionalType;
59 bool omp;
61
62 inline bool operator<(const MForwardCacheKey &rhs) const {
63 if (todiff < rhs.todiff)
64 return true;
65 if (rhs.todiff < todiff)
66 return false;
67
68 if (retType < rhs.retType)
69 return true;
70 if (rhs.retType < retType)
71 return false;
72
73 if (std::lexicographical_compare(
74 constant_args.begin(), constant_args.end(),
75 rhs.constant_args.begin(), rhs.constant_args.end()))
76 return true;
77 if (std::lexicographical_compare(
78 rhs.constant_args.begin(), rhs.constant_args.end(),
79 constant_args.begin(), constant_args.end()))
80 return false;
81
83 return true;
84 if (rhs.returnUsed < returnUsed)
85 return false;
86
87 if (mode < rhs.mode)
88 return true;
89 if (rhs.mode < mode)
90 return false;
91
92 if (width < rhs.width)
93 return true;
94 if (rhs.width < width)
95 return false;
96
97 if (additionalType.getImpl() < rhs.additionalType.getImpl())
98 return true;
99 if (rhs.additionalType.getImpl() < additionalType.getImpl())
100 return false;
101
103 return true;
105 return false;
107 if (omp < rhs.omp)
108 return true;
109 if (rhs.omp < omp)
110 return false;
111
112 if (strongZero < rhs.strongZero)
113 return true;
114 if (rhs.strongZero < strongZero)
115 return false;
117 // equal
118 return false;
119 }
120 };
121
123 FunctionOpInterface todiff;
124 const std::vector<DIFFE_TYPE> retActivity;
125 const std::vector<DIFFE_TYPE> argActivity;
126 const std::vector<bool> returnPrimals;
127 const std::vector<bool> returnShadows;
131 unsigned width;
132 mlir::Type additionalType;
133 const MFnTypeInfo typeInfo;
134 const std::vector<bool> volatileArgs;
135 bool omp;
137
138 inline bool operator<(const MReverseCacheKey &rhs) const {
139 if (todiff < rhs.todiff)
140 return true;
141 if (rhs.todiff < todiff)
142 return false;
143
144 if (std::lexicographical_compare(retActivity.begin(), retActivity.end(),
145 rhs.retActivity.begin(),
146 rhs.retActivity.end()))
147 return true;
148 if (std::lexicographical_compare(rhs.retActivity.begin(),
149 rhs.retActivity.end(),
150 retActivity.begin(), retActivity.end()))
151 return false;
152
153 if (std::lexicographical_compare(argActivity.begin(), argActivity.end(),
154 rhs.argActivity.begin(),
155 rhs.argActivity.end()))
156 return true;
157 if (std::lexicographical_compare(rhs.argActivity.begin(),
158 rhs.argActivity.end(),
159 argActivity.begin(), argActivity.end()))
160 return false;
161
163 return true;
164 if (rhs.returnPrimals < rhs.returnPrimals)
165 return false;
166
168 return true;
170 return false;
172 if (mode < rhs.mode)
173 return true;
174 if (rhs.mode < mode)
175 return false;
178 return true;
180 return false;
182 if (width < rhs.width)
183 return true;
184 if (rhs.width < width)
185 return false;
186
187 if (additionalType.getImpl() < rhs.additionalType.getImpl())
188 return true;
189 if (rhs.additionalType.getImpl() < additionalType.getImpl())
190 return false;
191
192 if (typeInfo < rhs.typeInfo)
193 return true;
194 if (rhs.typeInfo < typeInfo)
195 return false;
196
197 if (volatileArgs < rhs.volatileArgs)
198 return true;
199 if (rhs.volatileArgs < volatileArgs)
200 return false;
201
202 if (omp < rhs.omp)
203 return true;
204 if (rhs.omp < omp)
205 return false;
206
207 if (strongZero < rhs.strongZero)
208 return true;
209 if (rhs.strongZero < strongZero)
210 return false;
211
212 // equal
213 return false;
214 }
215 };
216
217 std::map<MForwardCacheKey, FunctionOpInterface> ForwardCachedFunctions;
218 std::map<MReverseCacheKey, FunctionOpInterface> ReverseCachedFunctions;
220 // solver may be null, in which case the older inductive hypothesis activity
221 // analysis will be used.
222 std::unique_ptr<DataFlowSolver> solver;
223 MEnzymeLogic(bool dataflowActivity);
224
225 FunctionOpInterface
226 CreateForwardDiff(FunctionOpInterface fn, std::vector<DIFFE_TYPE> retType,
227 std::vector<DIFFE_TYPE> constants, MTypeAnalysis &TA,
228 std::vector<bool> returnPrimals, DerivativeMode mode,
229 bool freeMemory, size_t width, mlir::Type addedType,
230 MFnTypeInfo type_args, std::vector<bool> overwritten_args,
231 void *augmented, bool omp, llvm::StringRef postpasses,
232 bool verifyPostPasses, bool strongZero);
233
234 FunctionOpInterface
235 CreateReverseDiff(FunctionOpInterface fn, std::vector<DIFFE_TYPE> retType,
236 std::vector<DIFFE_TYPE> constants, MTypeAnalysis &TA,
237 std::vector<bool> returnPrimals,
238 std::vector<bool> returnShadows, DerivativeMode mode,
239 bool freeMemory, bool atomicAdd, size_t width,
240 mlir::Type addedType, MFnTypeInfo type_args,
241 std::vector<bool> overwritten_args, void *augmented,
242 bool omp, llvm::StringRef postpasses, bool verifyPostPasses,
243 bool strongZero, bool markReadonly);
244
245 void
246 initializeShadowValues(SmallVector<mlir::Block *> &dominatorToposortBlocks,
247 MGradientUtilsReverse *gutils);
248 void
249 handlePredecessors(Block *oBB, Block *newBB, Block *reverseBB,
250 MGradientUtilsReverse *gutils,
251 llvm::function_ref<buildReturnFunction> buildReturnOp);
252 LogicalResult visitChildren(Block *oBB, Block *reverseBB,
253 MGradientUtilsReverse *gutils);
254 LogicalResult visitChild(Operation *op, OpBuilder &builder,
255 MGradientUtilsReverse *gutils);
256 void mapInvertArguments(Block *oBB, Block *reverseBB,
257 MGradientUtilsReverse *gutils);
258 LogicalResult
259 differentiate(MGradientUtilsReverse *gutils, Region &oldRegion,
260 Region &newRegion,
261 llvm::function_ref<buildReturnFunction> buildFuncRetrunOp,
262 std::function<std::pair<Value, Value>(Type)> cacheCreator);
263};
264
265} // Namespace enzyme
266} // Namespace mlir
DerivativeMode
Definition Utils.h:524
Concrete SubType of a given value.
Class representing the underlying types of values as sequences of offsets to a ConcreteType.
Definition TypeTree.h:72
void initializeShadowValues(SmallVector< mlir::Block * > &dominatorToposortBlocks, MGradientUtilsReverse *gutils)
void mapInvertArguments(Block *oBB, Block *reverseBB, MGradientUtilsReverse *gutils)
LogicalResult visitChildren(Block *oBB, Block *reverseBB, MGradientUtilsReverse *gutils)
LogicalResult visitChild(Operation *op, OpBuilder &builder, MGradientUtilsReverse *gutils)
std::map< MReverseCacheKey, FunctionOpInterface > ReverseCachedFunctions
std::unique_ptr< DataFlowSolver > solver
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)
MEnzymeLogic(bool dataflowActivity)
FunctionOpInterface CreateReverseDiff(FunctionOpInterface fn, std::vector< DIFFE_TYPE > retType, std::vector< DIFFE_TYPE > constants, MTypeAnalysis &TA, std::vector< bool > returnPrimals, std::vector< bool > returnShadows, DerivativeMode mode, bool freeMemory, bool atomicAdd, 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, bool markReadonly)
void handlePredecessors(Block *oBB, Block *newBB, Block *reverseBB, MGradientUtilsReverse *gutils, llvm::function_ref< buildReturnFunction > buildReturnOp)
std::map< MForwardCacheKey, FunctionOpInterface > ForwardCachedFunctions
LogicalResult differentiate(MGradientUtilsReverse *gutils, Region &oldRegion, Region &newRegion, llvm::function_ref< buildReturnFunction > buildFuncRetrunOp, std::function< std::pair< Value, Value >(Type)> cacheCreator)
bool operator<(const MFnTypeInfo &rhs) const
Definition EnzymeLogic.h:20
MFnTypeInfo getAnalyzedTypeInfo(FunctionOpInterface op) const
Definition EnzymeLogic.h:25
TypeTree query(Value) const
Definition EnzymeLogic.h:34
ConcreteType intType(size_t num, Value val, bool errIfNotFound=true, bool pointerIntSame=false) const
Definition EnzymeLogic.h:35
void buildReturnFunction(OpBuilder &, mlir::Block *)
Definition EnzymeLogic.h:14
const std::vector< DIFFE_TYPE > retType
Definition EnzymeLogic.h:51
const std::vector< DIFFE_TYPE > constant_args
Definition EnzymeLogic.h:52
bool operator<(const MForwardCacheKey &rhs) const
Definition EnzymeLogic.h:62
const std::vector< DIFFE_TYPE > argActivity
const std::vector< DIFFE_TYPE > retActivity
bool operator<(const MReverseCacheKey &rhs) const