-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[mlir][spirv] Fix lookup logic spirv.target_env
for gpu.module
#147262
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?
Conversation
The `gpu.module` operation can contain `spirv.target_env` attributes within an array attribute named `"targets"`. So it accounts for that case by iterating over the `"targets"` attribute, if present, and looking up `spirv.target_env`.
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-mlir-gpu @llvm/pr-subscribers-mlir-spirv Author: Jaeho Kim (oojahooo) ChangesThe Full diff: https://github.com/llvm/llvm-project/pull/147262.diff 1 Files Affected:
diff --git a/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp b/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp
index 5ecbd5d7c59d5..dbaa10e89bd42 100644
--- a/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp
@@ -184,6 +184,15 @@ spirv::TargetEnvAttr spirv::lookupTargetEnv(Operation *op) {
if (!op)
break;
+ if (auto arrAttr = op->getAttrOfType<ArrayAttr>("targets")) {
+ for (auto attr : arrAttr) {
+ if (auto spirvTargetEnvAttr =
+ llvm::dyn_cast<spirv::TargetEnvAttr>(attr)) {
+ return spirvTargetEnvAttr;
+ }
+ }
+ }
+
if (auto attr = op->getAttrOfType<spirv::TargetEnvAttr>(
spirv::getTargetEnvAttrName()))
return attr;
|
@llvm/pr-subscribers-mlir Author: Jaeho Kim (oojahooo) ChangesThe Full diff: https://github.com/llvm/llvm-project/pull/147262.diff 1 Files Affected:
diff --git a/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp b/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp
index 5ecbd5d7c59d5..dbaa10e89bd42 100644
--- a/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp
@@ -184,6 +184,15 @@ spirv::TargetEnvAttr spirv::lookupTargetEnv(Operation *op) {
if (!op)
break;
+ if (auto arrAttr = op->getAttrOfType<ArrayAttr>("targets")) {
+ for (auto attr : arrAttr) {
+ if (auto spirvTargetEnvAttr =
+ llvm::dyn_cast<spirv::TargetEnvAttr>(attr)) {
+ return spirvTargetEnvAttr;
+ }
+ }
+ }
+
if (auto attr = op->getAttrOfType<spirv::TargetEnvAttr>(
spirv::getTargetEnvAttrName()))
return attr;
|
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 rather naive question, as I'm not familiar with the GPU dialect. Is it possible for the target env to be present in both "targets"
and as an op attribute at the same time? If so, does the look-up order matter? I’d hope the same target env is returned either way, but hypothetically if there is a different env in "targets"
and in the op, I wonder which one should take a precedence?
Also, it'd be nice to have a test for the change. Probably in GPU to SPIR-V conversion test directory?
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.
Could you add a test that shows where this comes up? I'm not sure if we should look up the target env in"targets"
attribute in any of possible parents
When the Also I added a lit test in GPU to SPIR-V conversion test directory. Thank you for your comment. |
Thank you for your comment. I added a test that reproduces the situation I had in mind. |
To me the sounds like the wrong fix. Could we teach the passes you mentioned to also look in |
If I understand your point correctly, rather than hardcoding the There are two possible approaches that I think:
I would greatly appreciate it if you could let me know which is aligned with your suggestion. If so, I would be happy to revise the implementation accordingly based on the preferred direction. Thank you for your support. |
Approach 1. sounds to me like the way to go |
…ule` Add lookup target env in "targets" attr logic to GPUToSPIRV pass
Thank you for replying. Happy to make any further changes if needed. Otherwise, would it be okay to merge? Thank you! |
bool mapMemorySpace; | ||
}; | ||
|
||
spirv::TargetEnvAttr |
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.
Is there a reason to have those two functions? Why not to call spirv::lookupTargetEnvOrDefault
directly in GPUToSPIRVPass::lookupTargetEnvInTargets
?
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.
Thank you for your comment.
Since I intentionally did not include OrDefault
in the function name GPUToSPIRVPass::lookupTargetEnvInTargets
, I wanted the function to only attempt to retrieve the target environment from the "targets"
attribute, reflecting that limited scope directly in the name.
Then, I defined a separate GPUToSPIRVPass::lookupTargetEnvOrDefault
function that calls it and falls back to spirv::lookupTargetEnvOrDefault
if needed, making the fallback behavior more explicit.
However, if adding multiple new functions is considered undesirable, I'm happy to simplify the implementation by having only GPUToSPIRVPass::lookupTargetEnvOrDefault
and letting it handle whole condition.
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.
However, if adding multiple new functions is considered undesirable, I'm happy to simplify the implementation by having only
GPUToSPIRVPass::lookupTargetEnvOrDefault
and letting it handle whole condition.
I don't think it's undesirable. I just felt like removing the extra indirection may offer a nicer solution, but you made some good argument about why it makes sense the way it is. Initially I thought that you could add OrDefault
in the name of the first function, but now I think it may be more confusing. Let's keep it the way it is, unless someone else has a strong opinion about 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.
Thank you for the thoughtful suggestion and for being open to my perspective!
remove unnecessary namespace qualifiers
bool mapMemorySpace; | ||
}; | ||
|
||
spirv::TargetEnvAttr | ||
GPUToSPIRVPass::lookupTargetEnvInTargets(gpu::GPUModuleOp moduleOp) { | ||
for (auto &targetAttr : moduleOp.getTargetsAttr()) |
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.
Spell out the type here since it's not obvious without an IDE/lsp: https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable
|
||
spirv::TargetEnvAttr | ||
GPUToSPIRVPass::lookupTargetEnvOrDefault(gpu::GPUModuleOp moduleOp) { | ||
if (auto targetEnvAttr = lookupTargetEnvInTargets(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.
also here
spirv::TargetEnvAttr lookupTargetEnvInTargets(gpu::GPUModuleOp moduleOp); | ||
spirv::TargetEnvAttr lookupTargetEnvOrDefault(gpu::GPUModuleOp 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.
Can you add documentation comments explaining what these do?
@@ -385,6 +385,9 @@ LogicalResult GPUModuleConversion::matchAndRewrite( | |||
if (auto attr = moduleOp->getAttrOfType<spirv::TargetEnvAttr>( | |||
spirv::getTargetEnvAttrName())) | |||
spvModule->setAttr(spirv::getTargetEnvAttrName(), attr); | |||
for (auto targetAttr : moduleOp.getTargetsAttr()) |
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.
Use the actual type here, it's not obvious outside of an IDE: https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable
@@ -0,0 +1,17 @@ | |||
// RUN: mlir-opt --spirv-attach-target='caps=Shader exts=SPV_KHR_storage_buffer_storage_class' --convert-gpu-to-spirv %s -o - | FileCheck %s |
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.
// RUN: mlir-opt --spirv-attach-target='caps=Shader exts=SPV_KHR_storage_buffer_storage_class' --convert-gpu-to-spirv %s -o - | FileCheck %s | |
// RUN: mlir-opt --spirv-attach-target='caps=Shader exts=SPV_KHR_storage_buffer_storage_class' --convert-gpu-to-spirv %s | FileCheck %s |
@@ -0,0 +1,17 @@ | |||
// RUN: mlir-opt --spirv-attach-target='caps=Shader exts=SPV_KHR_storage_buffer_storage_class' --convert-gpu-to-spirv %s -o - | FileCheck %s |
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 do you think about running convert-gpu-to-spirv
only? In the current form, it's not very clear where the 'targets' attribute is materialized.
spirv.target_env
for gpu.module
spirv.target_env
for gpu.module
The
gpu.module
operation can containspirv.target_env
attributes within an array attribute named"targets"
. So it accounts for that case by iterating over the"targets"
attribute, if present, and looking upspirv.target_env
.