feature: redesign Proteus's lambda JIT compilation interface and pipeline - #467
feature: redesign Proteus's lambda JIT compilation interface and pipeline#467johnbowen42 wants to merge 55 commits into
Conversation
ggeorgakoudis
left a comment
There was a problem hiding this comment.
This is great and will solve our lambda issues.
I made a first pass and left comments on things we need to restructure.
There was a problem hiding this comment.
I think installing and using a separate pass is quirky. We already register ProteusPass in multiple places (early-simplifications and LTO), so we can register it also at pipeline-start and just do the lambda analysis
There was a problem hiding this comment.
Could you expand on this? How else would be run an early LambdaAnalysis pass and Proteuspass later?
There was a problem hiding this comment.
Register ProteusPass at pipeline-start and pass an argument when you construct it to indicate the insert point. Check how we do it for early-simplifications and LTO. Apparently state is not true-false anymore, if there are 3 possible insert points.
2cf03a2 to
d5b97c4
Compare
d5b97c4 to
a56679a
Compare
|
all tests are passing for me locally on Tioga with rocm 6.4.2 |
c3d3d2e to
5daef48
Compare
4441506 to
3202250
Compare
|
This analysis is now compatible with RAJA launch, kernel, and forall LLVM IR shapes |
8e43319 to
f0ed85a
Compare
f3e5a08 to
f59b51e
Compare
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
remove jit var analysis from later pass tmp update tests check point: all lambda tests GPU passing add wrapper functors Lambda redeisgn: add functors. This commit builds but the runtime needs work delete plugin get tests working Refactor tests and track lambdas by global annotations Remove changes to type traits Get rid of storing things in llvm.global.annotations. Fix lambda CPU test All lambda unit tests passing. Fixed cloning bug in ProteusPass delete xfail compile test remove script change Fix all unit tests
…need to rework host lambda specialization
… expecting jit_variable schema for every lambda
…alue and insert_value analysis
…rt through ProteusPass
f59b51e to
c462791
Compare
There was a problem hiding this comment.
This is great work. I have mostly minor things.
Because this PR is so big and has been so long in the works, I don't want to hold it up for any of these things.
I am concerned that we would perpetually run around in bike-shedding circles, all the while this important feature is held up. Anything you choose not to resolve should be opened as an issue for follow-up.
| // We need collect any kernel host stubs to pass to parse annotations, used | ||
| // in forced annotations. | ||
| const auto StubToKernelMap = getKernelHostStubs(M); | ||
|
|
There was a problem hiding this comment.
Copy-paste artifact from ProteusPass? This is never used here. Can be removed along with getKernelHostStubs.
| DenseMap<Value *, GlobalVariable *> getKernelHostStubs(Module &M) { | ||
| DenseMap<Value *, GlobalVariable *> StubToKernelMap; |
| Value *getStubGV([[maybe_unused]] Value *Operand) { | ||
| // NOTE: when called by isDeviceKernelHostStub, Operand may not be a global |
| bool hasDeviceLaunchKernelCalls(Module &M) { | ||
| Function *LaunchKernelFn = nullptr; |
|
|
||
| DenseMap<StructType *, SmallVector<LambdaJitVariableInfo, 16>> | ||
| LambdaStorageTypeToJitIndices; | ||
| DenseMap<Type *, GlobalVariable *> LambdaTypeToGlobalName; |
| DenseMap<StructType *, SmallVector<LambdaJitVariableInfo, 16>> | ||
| LambdaStorageTypeToJitIndices; | ||
| DenseMap<Type *, GlobalVariable *> LambdaTypeToGlobalName; | ||
| DenseSet<StructType *> RegisteredLambdaStorageClasses; | ||
| DenseMap<StructType *, StructType *> FunctorTypeToLambdaTypeMap; | ||
| DenseMap<uint64_t, StructType *> FunctorIDToLambdaTypeMap; | ||
| DenseMap<uint64_t, StructType *> FunctorIDToFunctorTypeMap; |
There was a problem hiding this comment.
These are all declared here but used only for host compilation?
| KernelFunction = FirstAnalysis->KernelFunction; | ||
| AnalysisSuccess = true; | ||
| AnalysisFailed = false; |
There was a problem hiding this comment.
Don't you also need to set KernelArg, Offset, and ChangedRC?
| for (User *U : F->users()) { | ||
| auto *CB = dyn_cast<CallBase>(U); | ||
| if (!CB) | ||
| continue; | ||
| DEBUG(Logger::logs("proteus-pass") | ||
| << "Analysis crossed interprocedural boundary at " | ||
| << *CB->getArgOperand(ArgNum) << "\n"); | ||
| WorkList.push_back({CB->getArgOperand(ArgNum), CB}); |
There was a problem hiding this comment.
Does this need to be context sensitive?
| std::optional<RuntimeConstantType> getRCTypeForLLVMType(Type *Ty) { | ||
| if (Ty->isIntegerTy(1)) | ||
| return RuntimeConstantType::BOOL; | ||
| if (Ty->isIntegerTy(8)) | ||
| return RuntimeConstantType::INT8; | ||
| if (Ty->isIntegerTy(32)) | ||
| return RuntimeConstantType::INT32; | ||
| if (Ty->isIntegerTy(64)) | ||
| return RuntimeConstantType::INT64; | ||
| if (Ty->isFloatTy()) | ||
| return RuntimeConstantType::FLOAT; | ||
| if (Ty->isDoubleTy()) | ||
| return RuntimeConstantType::DOUBLE; | ||
| if (Ty->isPointerTy()) | ||
| return RuntimeConstantType::PTR; | ||
| return std::nullopt; | ||
| } |
There was a problem hiding this comment.
Regression: long double is dropped
| // Legacy PM implementation. | ||
| struct LegacyProteusPass : public ModulePass { | ||
| static char ID; | ||
| LegacyProteusPass() : ModulePass(ID) {} | ||
| bool runOnModule(Module &M) override { | ||
| ProteusPassImpl PPI{M}; | ||
| bool Changed = PPI.run(M, false); | ||
| return Changed; |
There was a problem hiding this comment.
Should the lambda analysis be run here too?
This feature restructures Proteus's lambda support so that a device module containing multiple calls of a lambda with different runtime constants can be correctly JIT compiled. This feature makes Proteus's support of JIT compiled lambdas closer to supporting all possible C++ lambda syntax, instead of the narrow syntax often used by parallel programming abstraction layers. Concretely