-
Notifications
You must be signed in to change notification settings - Fork 13.7k
[mlir][spirv] Implement gpu::TargetAttrInterface #69949
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
Conversation
Create SPIRV Target Attribute to enable GPU compilation pipeline. The Target Attribute is modeled after the existing spriv.target_env Plan is to use this new attribute to enable GPU compilation pipeline for OpenCL kernels only. The changes do not impact Vulkan shaders using milr-vulkan-runner. New GPU Dialect transform pass spirv-attach-target is implemented for attaching attribute from CLI. gpu-module-to-binary pass now works with GPU module that has SPIRV module with OpenCL kernel functions inside.
Part of refactoring and breaking down #65539 into smaller PRs. |
@fabianmcg Let me know if I'm missing anything. I have one more PR after this one that makes target LLVMIR aware of SPIRV dialect since the new target attribute is part of SPIRV dialect which was not considered a leaf dialect that needs translation to LLVMIR. |
@silee2 I'll take a closer look later, at first glance it looks like everything is there. Just one quick question, can you describe the next PR a bit more? Because you shouldn't need to make the target LLVMIR aware, as the binary embedding is mostly dialect agnostic, so there shouldn't be an issue with |
} | ||
auto gpuMod = dyn_cast<gpu::GPUModuleOp>(module); | ||
auto spvMods = gpuMod.getOps<spirv::ModuleOp>(); | ||
auto spvMod = *spvMods.begin(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A check is necessary before *spvMods.begin()
, as spvMods
could be an empty range.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added check for empty range.
mlir/lib/Target/SPIRV/Target.cpp
Outdated
return std::nullopt; | ||
} | ||
|
||
SmallVector<char, 0> spvData; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest instead of the loop:
SmallVector<char, 0> spvData; | |
SmallVector<char, 0> spvData(spvBinary.size() * sizeof(uint32_t), 0); | |
memcpy(spvData.data(), spvBinary.data(), spvData.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed as suggested.
let description = [{ | ||
GPU target attribute for controlling compilation of SPIRV targets. | ||
}]; | ||
let parameters = (ins |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of all of these parameters? I couldn't find the place where they are being used, are they being used at a later patch, or are they only informational?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those parameters are for describing target environment: https://mlir.llvm.org/docs/Dialects/SPIR-V/#target-environment
The parameters are not used today since lowering to SPIR-V is restricted to common set of SPIR-V ops supported in all environments.
But in the future, lowering passes can check the parameters and utilize SPIR-V extension ops or do target specific optimizations.
|
Yes. SelectObjectAttr.cpp is the only functional change. |
@fabianmcg Can you take a look again? Answered question and addressed change requests. |
This patch LGTM! I'll approve once the builds have completed.
Did you try just registering the dialect instead of adding a translation? I'm still unsure if adding a translation to LLVM is needed, as the error is probably only happening during parsing? But I guess we can have this conversation on the next PR. |
check-flang failed on Windows with two unresolved tests. Does not look related to this PR. Merging main again to run CI again. |
@joker-eph This PR got approval from @fabianmcg. What do I need to do next to get the PR merged? |
Thanks for the contribution and sorry about the delay! I'm getting around to review this pull request (already done a few others). Please wait a bit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again for the contribution! A couple of comments inlined. My main concern is the duplication of spirv.target
attribute. We should avoid the duplication and confusion there.
@@ -188,4 +188,46 @@ def GpuROCDLAttachTarget: Pass<"rocdl-attach-target", ""> { | |||
]; | |||
} | |||
|
|||
def GpuSPIRVAttachTarget: Pass<"spirv-attach-target", ""> { | |||
let summary = "Attaches an SPIRV target attribute to a GPU Module."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: s/SPIRV/SPIR-V/.
SPIR-V is the formal spelling. We should use that when in docs and comments.
Also for all the following docs and comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
// SPIRV target attribute. | ||
//===----------------------------------------------------------------------===// | ||
|
||
def SPIRV_TargetAttr : SPIRV_Attr<"SPIRVTarget", "target"> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This attribute is pretty much a duplication of spirv::TargetEnvAttr
defined in SPIRVAttributes.h
? We should avoid introducing such duplications and causing confusion. Any reaons we cannot use spirv::TargetEnvAttr
directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the PR to use spirv::TargetEnvAttr.
@@ -0,0 +1,30 @@ | |||
//===- Target.h - MLIR SPIRV target registration ----------------*- C++ -*-===// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: again, please use SPIR-V in docs and comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -166,4 +166,35 @@ def SPIRV_ResourceLimitsAttr : SPIRV_Attr<"ResourceLimits", "resource_limits"> { | |||
let assemblyFormat = "`<` struct(params) `>`"; | |||
} | |||
|
|||
//===----------------------------------------------------------------------===// | |||
// SPIRV target attribute. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: SPIR-V
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file implements the `GpuSPIRVAttachTarget` pass, attaching |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: GPUSPIRVAttachTarget
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
mlir/lib/Target/SPIRV/Target.cpp
Outdated
module->emitError("Module must be a GPU module."); | ||
return std::nullopt; | ||
} | ||
auto gpuMod = dyn_cast<gpu::GPUModuleOp>(module); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could move this upward and check whether it's null instead of the isa
check at L77.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
mlir/lib/Target/SPIRV/Target.cpp
Outdated
auto gpuMod = dyn_cast<gpu::GPUModuleOp>(module); | ||
auto spvMods = gpuMod.getOps<spirv::ModuleOp>(); | ||
// Empty spirv::ModuleOp | ||
if (spvMods.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: drop {..}
for trivial if statements per LLVM coding sytle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
mlir/lib/Target/SPIRV/Target.cpp
Outdated
llvm::SmallVector<uint32_t, 0> spvBinary; | ||
|
||
spvBinary.clear(); | ||
// serialize the spv module to spv binary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Serialize the spv.module op to SPIR-V blob.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
mlir/lib/Target/SPIRV/Target.cpp
Outdated
spvBinary.clear(); | ||
// serialize the spv module to spv binary | ||
if (mlir::failed(spirv::serialize(spvMod, spvBinary))) { | ||
spvMod.emitError() << "Failed to serialize SPIR-V module"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: "failed to .."
no capitalization to compose better with previous / following messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks for the tip.
mlir/lib/Target/SPIRV/Target.cpp
Outdated
} | ||
auto gpuMod = dyn_cast<gpu::GPUModuleOp>(module); | ||
auto spvMods = gpuMod.getOps<spirv::ModuleOp>(); | ||
// Empty spirv::ModuleOp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment here does not provide additional value; we should remove it or expand it to be more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
@antiagainst Thanks for the detailed review and helpful comments! Updated the PR accordingly. |
@antiagainst Waiting for your approval. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for addressing the comments!
I revised the commit message a bit and landed it. Thanks for the waiting! |
This revision seems related to the following buildbot failure:
Would you mind taking a look? Thank you 👍 |
Sorry about that! I uploaded 4a4b857 to fix this. Verified that it fixes the break for me locally. |
@@ -15,6 +15,7 @@ | |||
|
|||
#include "Utils.h" | |||
#include "mlir/Dialect/GPU/IR/GPUDialect.h" | |||
#include "mlir/Dialect/SPIRV/IR/SPIRVAttributes.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels off: you have GPU dialect transforms depending on SPIRV attributes/dialect (esp in header). Why is this pass in GPU dialect rather than SPIRV one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Back when the compilation redesign was happening we decided to add the attach* passes in GPU to avoid polluting lower level dialects with GPU includes. However, I do agree that include shouldn't be there, as far as I could tell, that include is only needed by one pass option mlir::spirv::TargetEnvAttr::kUnknownDeviceID
, so it should be possible to remove it. I'll fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SG. Thanks @jpienaar & @fabianmcg!
Create SPIRV Target Attribute to enable GPU compilation pipeline. The Target Attribute is modeled after the existing spriv.target_env Plan is to use this new attribute to enable GPU compilation pipeline for OpenCL kernels only.
The changes do not impact Vulkan shaders using milr-vulkan-runner. New GPU Dialect transform pass spirv-attach-target is implemented for attaching attribute from CLI.
gpu-module-to-binary pass now works with GPU module that has SPIRV module with OpenCL kernel functions inside.