-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[mlir][gpu] gpu-module-to-binary: add option to dump intermediate files
#170016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
8ce37a2
b102b57
526849e
30abee7
64a0a28
4ba95d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,9 @@ | |
|
|
||
| #include "llvm/ADT/STLExtras.h" | ||
| #include "llvm/ADT/StringSwitch.h" | ||
| #include "llvm/Support/FileSystem.h" | ||
| #include "llvm/Support/Path.h" | ||
| #include "llvm/Support/ToolOutputFile.h" | ||
|
|
||
| using namespace mlir; | ||
| using namespace mlir::gpu; | ||
|
|
@@ -26,6 +29,26 @@ namespace mlir { | |
| #include "mlir/Dialect/GPU/Transforms/Passes.h.inc" | ||
| } // namespace mlir | ||
|
|
||
| static LogicalResult | ||
| dumpToFile(Operation *op, StringRef dumpDir, const llvm::Twine &filename, | ||
| function_ref<void(llvm::raw_ostream &)> writeContent) { | ||
| if (dumpDir.empty()) | ||
| return success(); | ||
|
|
||
| llvm::SmallString<128> path(dumpDir); | ||
| llvm::sys::path::append(path, filename); | ||
|
|
||
| std::error_code ec; | ||
| llvm::ToolOutputFile output(path, ec, llvm::sys::fs::OF_None); | ||
| if (ec) | ||
| return op->emitError() << "Failed to create file '" << path | ||
| << "': " << ec.message(); | ||
|
|
||
| writeContent(output.os()); | ||
| output.keep(); | ||
kuhar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return success(); | ||
| } | ||
|
|
||
| namespace { | ||
| class GpuModuleToBinaryPass | ||
| : public impl::GpuModuleToBinaryPassBase<GpuModuleToBinaryPass> { | ||
|
|
@@ -64,11 +87,53 @@ void GpuModuleToBinaryPass::runOnOperation() { | |
| SmallVector<Attribute> librariesToLink; | ||
| for (const std::string &path : linkFiles) | ||
| librariesToLink.push_back(StringAttr::get(&getContext(), path)); | ||
|
|
||
| Operation *op = getOperation(); | ||
|
|
||
| // Create dump directory if specified. | ||
| if (!dumpIntermediates.empty()) { | ||
| if (std::error_code ec = | ||
| llvm::sys::fs::create_directories(dumpIntermediates)) { | ||
| op->emitError() << "Failed to create dump directory '" | ||
| << dumpIntermediates << "': " << ec.message(); | ||
| return signalPassFailure(); | ||
| } | ||
| } | ||
|
|
||
| // Create callbacks for dumping intermediate artifacts if requested. | ||
| auto initialIRCallback = [&](llvm::Module &mod) { | ||
| if (failed( | ||
| dumpToFile(op, dumpIntermediates, mod.getName() + ".initial.ll", | ||
| [&](llvm::raw_ostream &os) { mod.print(os, nullptr); }))) | ||
| signalPassFailure(); | ||
|
Comment on lines
+107
to
+110
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Either we make callbacks always successful, ie. no IMO it's better making them return a LogicalResult.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't quite see why? The LogicalResult does not necessarily seem relevant to the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, this actually looks straightforward enough change, I can do it.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The assumption of ModuleToObject logic is that these callbacks don't create invalid/failed states. In this particular case, while failing to dump it's unlikely to crash
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't agree: from the perspective other the ModuleToObject logic. we want to preserve this assumption that these callbacks don't create invalid states.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
ModuleToObject isn't failable right now, but I'm failing to link the question to the current discussion actually?
I don't quite see a concern with this, LLVM isn't resilient to system issues such as "swap filing up" or "machine running out of memory" in general.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is failable: https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Target/LLVM/ModuleToObject.h#L44 (TODO for me, use FailureOr instead of While LLVM it's not resilient to the issues I mentioned. It makes for a better debugging/user experience to fail at the earliest.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I think making these callbacks fallible is good improvement regardless of this PR, and it doesn't looks like particularly complicated change, I can do it as separate PR.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I may have objections with the change depending on how it looks, I'm not convinced that these should be failable conceptually (in terms of what these APIs are meant to provide).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }; | ||
|
|
||
| auto linkedIRCallback = [&](llvm::Module &mod) { | ||
| if (failed( | ||
| dumpToFile(op, dumpIntermediates, mod.getName() + ".linked.ll", | ||
| [&](llvm::raw_ostream &os) { mod.print(os, nullptr); }))) | ||
| signalPassFailure(); | ||
| }; | ||
|
|
||
| auto optimizedIRCallback = [&](llvm::Module &mod) { | ||
| if (failed( | ||
| dumpToFile(op, dumpIntermediates, mod.getName() + ".opt.ll", | ||
| [&](llvm::raw_ostream &os) { mod.print(os, nullptr); }))) | ||
| signalPassFailure(); | ||
| }; | ||
|
|
||
| auto isaCallback = [&](StringRef isa) { | ||
| if (failed(dumpToFile(op, dumpIntermediates, "kernel.isa", | ||
| [&](llvm::raw_ostream &os) { os << isa; }))) | ||
| signalPassFailure(); | ||
| }; | ||
|
|
||
| TargetOptions targetOptions(toolkitPath, librariesToLink, cmdOptions, | ||
| elfSection, *targetFormat, lazyTableBuilder); | ||
| elfSection, *targetFormat, lazyTableBuilder, | ||
| initialIRCallback, linkedIRCallback, | ||
| optimizedIRCallback, isaCallback); | ||
| if (failed(transformGpuModulesToBinaries( | ||
| getOperation(), OffloadingLLVMTranslationAttrInterface(nullptr), | ||
| targetOptions))) | ||
| op, OffloadingLLVMTranslationAttrInterface(nullptr), targetOptions))) | ||
| return signalPassFailure(); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // REQUIRES: host-supports-nvptx | ||
| // RUN: rm -rf %t | ||
| // RUN: mlir-opt %s --gpu-module-to-binary='format=isa dump-intermediates=%t' | FileCheck %s | ||
| // RUN: test -f %t/kernel_module.initial.ll | ||
| // RUN: test -f %t/kernel_module.linked.ll | ||
| // RUN: test -f %t/kernel_module.opt.ll | ||
| // RUN: test -f %t/kernel.isa | ||
|
|
||
| module attributes {gpu.container_module} { | ||
| // CHECK-LABEL: gpu.binary @kernel_module | ||
|
|
||
| gpu.module @kernel_module [#nvvm.target<chip = "sm_70">] { | ||
| llvm.func @kernel(%arg0: f32) { | ||
| llvm.return | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // REQUIRES: host-supports-amdgpu | ||
| // RUN: rm -rf %t | ||
| // RUN: mlir-opt %s --gpu-module-to-binary='format=isa dump-intermediates=%t' | FileCheck %s | ||
| // RUN: test -f %t/kernel_module.initial.ll | ||
| // RUN: test -f %t/kernel_module.linked.ll | ||
| // RUN: test -f %t/kernel_module.opt.ll | ||
| // RUN: test -f %t/kernel.isa | ||
|
|
||
| module attributes {gpu.container_module} { | ||
| // CHECK-LABEL: gpu.binary @kernel_module | ||
|
|
||
| gpu.module @kernel_module [#rocdl.target<chip = "gfx942">] { | ||
| llvm.func @kernel(%arg0: f32) { | ||
| llvm.return | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.