Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[SPIRV] Change how to detect OpenCL/Vulkan Env and update tests accordingly. #129689

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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

maarquitos14
Copy link
Contributor

@maarquitos14 maarquitos14 commented Mar 4, 2025

A new test added for spirv-friendly builtins for SPV_KHR_bit_instructions unveiled that current mechanism to detect whether SPIRV Backend is in OpenCL environment or Vulkan environment was not good enough. This PR updates how to detect the environment and all the tests accordingly.

UPDATE: the new approach is having a new member in SPIRVSubtarget to represent the environment. It can be either OpenCL, Kernel or Unknown. If the triple is explicit, we can directly set it at the creation of the SPIRVSubtarget, otherwise we just leave it unknown until we find other information that can help us set the environment. For now, the only other information we use to set the environment is hlsl.shader attribute at SPIRV::ExecutionModel::ExecutionModel getExecutionModel(const SPIRVSubtarget &STI, const Function &F). Going forward we should consider also specific instructions that are Kernel-exclusive or Shader-exclusive.

@llvmbot
Copy link
Member

llvmbot commented Mar 4, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Marcos Maronas (maarquitos14)

Changes

The test is intended to specifically test spirv-friendly builtins, so change the function name to spirv-friendly format.


Full diff: https://github.com/llvm/llvm-project/pull/129689.diff

1 Files Affected:

  • (modified) llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll (+2-2)
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll
index e49a55956aff0..c93a4ad1bf1c9 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_KHR_bit_instructions/spirv-friendly_extended_bit_ops.ll
@@ -76,12 +76,12 @@ declare spir_func <8 x i8> @_Z24__spirv_BitFieldUExtractDv8_hjj(<8 x i8>, i32, i
 ; }
 define spir_kernel void @testBitReverse_SPIRVFriendly(<4 x i64> %b, ptr addrspace(1) nocapture align 32 %res) #3 {
 entry:
-  %call = call <4 x i64> @llvm.bitreverse.v4i64(<4 x i64> %b)
+  %call = call <4 x i64> @_Z18__spirv_BitReverseDv4_l(<4 x i64> %b)
   store <4 x i64> %call, ptr addrspace(1) %res, align 32
   ret void
 }
 
-declare <4 x i64> @llvm.bitreverse.v4i64(<4 x i64>) #4
+declare <4 x i64> @_Z18__spirv_BitReverseDv4_l(<4 x i64>) #4
 
 
 

@maarquitos14 maarquitos14 changed the title Use SPIRV-friendly builtin name. [SPIRV] Use SPIRV-friendly builtin name. Mar 4, 2025
@VyacheslavLevytskyy VyacheslavLevytskyy self-requested a review March 4, 2025 11:46
@maarquitos14 maarquitos14 force-pushed the maronas/use-spirv-friendly-call branch from b8daa27 to 11e5b6f Compare April 2, 2025 14:59
@maarquitos14 maarquitos14 changed the title [SPIRV] Use SPIRV-friendly builtin name. [SPIRV] Change how to detect OpenCL/Vulkan Env and update tests accordingly. Apr 2, 2025
Copy link

github-actions bot commented Apr 2, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@maarquitos14 maarquitos14 marked this pull request as draft April 2, 2025 15:04
Copy link
Contributor

@Keenuts Keenuts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is OK for me, as I don't think there are any other target than OpenCL/Vulkan for now. This can be revisited when Microsoft adds their DX/SPIRV thing

Comment on lines 284 to 283
"This entry point lacks mandatory hlsl.shader attribute.");
"This entry point lacks mandatory hlsl.shader attribute.", false);
}

const auto value = attribute.getValueAsString();
if (value == "compute")
return SPIRV::ExecutionModel::GLCompute;

report_fatal_error("This HLSL entry point is not supported by this backend.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unrelated no?

@VyacheslavLevytskyy
Copy link
Contributor

VyacheslavLevytskyy commented Apr 2, 2025

I'm afraid, this looks fragile with regards to the triple. Triples of kinds, for instance, "spirv64-unknown-unknown" and "spirv64v1.6-unknown-unknown" are massively in use and nobody expects that the "-opencl" suffix change game rules.

If a user needs now to apply "-opencl" everywhere to be recognized as the user of the compute flavor of SPIR-V, I expect that pretty much everything will start to fail after this change. Probably we need a way that doesn't require updating the whole compute's set of test cases, this is the only guarantee that SYCL, Intel's XPU backend for Triton, etc. will not notice the internal change in the SPIR-V backend. This is not to mention non-Intel applications of the compute flavor of SPIR-V.

For the context it's important that isOpenCLEnv() is just a bad choice of the name for such a function, it should be renamed to something of a kind of isCompute() to reflect what it means.

@VyacheslavLevytskyy
Copy link
Contributor

Let's add to the discussion more people: @michalpaszkowski @MrSidims @asudarsa

@maarquitos14
Copy link
Contributor Author

I'm afraid, this looks fragile with regards to the triple. Triples of kinds, for instance, "spirv64-unknown-unknown" and "spirv64v1.6-unknown-unknown" are massively in use and nobody expects that the "-opencl" suffix change game rules.

If a user needs now to apply "-opencl" everywhere to be recognized as the user of the compute flavor of SPIR-V, I expect that pretty much everything will start to fail after this change. Probably we need a way that doesn't require updating the whole compute's set of test cases, this is the only guarantee that SYCL, Intel's XPU backend for Triton, etc. will not notice the internal change in the SPIR-V backend. This is not to mention non-Intel applications of the compute flavor of SPIR-V.

I would expect that updating Clang to generate opencl part of the triple for those other projects should suffice. What do you think?

For the context it's important that isOpenCLEnv() is just a bad choice of the name for such a function, it should be renamed to something of a kind of isCompute() to reflect what it means.

I agree, and similarly, isVulkanEnv() should be renamed to isShader(), I think.

@VyacheslavLevytskyy
Copy link
Contributor

CC: @AlexVlx

@MrSidims MrSidims requested review from bader, svenvh and AlexVlx April 4, 2025 11:07
Copy link
Contributor

@MrSidims MrSidims left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch is LGTM, but IMHO this is a case when a work shouldn't be split across components - I mean that either this PR should also include changes in clang, that are forcing OpenCL environment to be included in the triple information for OpenCL lang or the appropriate PR in clang should already exist and be linked here as we also need to have attention and feedback from the frontend folks.

fyi @svenvh

}
bool isVulkanEnv() const { return TargetTriple.getArch() == Triple::spirv; }
bool isVulkanEnv() const { return !isOpenCLEnv(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that Vulkan is added to the triple as OSType:

Vulkan, // Vulkan SPIR-V

SPIR target uses Vulkan OSType to detect Vulkan environment:
assert(Triple.getArch() == llvm::Triple::spirv &&
"Invalid architecture for Logical SPIR-V.");
assert(Triple.getOS() == llvm::Triple::Vulkan &&
Triple.getVulkanVersion() != llvm::VersionTuple(0) &&
"Logical SPIR-V requires a valid Vulkan environment.");
assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
Triple.getEnvironment() <= llvm::Triple::Amplification &&
"Logical SPIR-V environment must be a valid shader stage.");

OpenCL is a bit messy.
I see one* OpenCL OSType:


Environment component also defines OpenCL:

I don't know the meaning of OpenCL in the environment component, but using OS triple component makes more sense to me. This topic probably forth a separate discussion, but I would add OpenCL component to OSType rather than to environment component. I guess we can alias NVCL to the OpenCL OSType value.

* - Maybe Mesa3D can be also considered as OpenCL environment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know the meaning of OpenCL in the environment component

It was added in #78655 and seems to be just a side change. I've asked the author in the PR, what was the idea behind adding OpenCL to env, but not sure if I'll get a reply.

}
bool isVulkanEnv() const { return TargetTriple.getArch() == Triple::spirv; }
bool isVulkanEnv() const { return !isOpenCLEnv(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool isVulkanEnv() const { return !isOpenCLEnv(); }

This code says that any triple that doesn't match OpenCL environment is Vulkan environment.

I would prefer SPIR-V backend to keep existing behavior for existing triple i.e. spirv[32|64]-unknown-unknown -> OpenCL environment.

New triples:

  • spirv-<vendor>-vulkan - SPIR-V for Vulkan environment.
  • spirv[32|64]-<vendor>-opencl - SPIR-V for OpenCL environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the things that we would like to fix is the fact that Vulkan/Shader environment can also be for a physical target (spirv32, spirv64). In other words, although de facto every physical SPIRV is Compute, and every logical SPIRV is Shader, that is not a requirement from the spec, so we should be able to support logical SPIRV for Compute and physical SPIRV for Shader.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be done in less intrusive way e.g. by requiring vulkan OS in the target triple?
If OS target triple is not Vulkan, the environment is set to OpenCL.
This way, we won't break the existing interface for FEs using "unknown" OS type to target OpenCL environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new approach I just added shouldn't break the existing interface for FEs using "unknown" OS type to target OpenCL environment.

@maarquitos14 maarquitos14 force-pushed the maronas/use-spirv-friendly-call branch from 11e5b6f to eef5045 Compare April 23, 2025 11:01
@maarquitos14
Copy link
Contributor Author

@Keenuts the new approach I just added makes 58 tests fail. They can all pass if we explicitly pass vulkan in the triple. I didn't look at all of them individually, but took a look at a handful of them and from my POV, there's not enough information to make them work with unknown-unknown triple. In other words, I don't see anything Shader/Vulkan specific in them so that we can infer from the module what's the environment. Therefore, I think the only way to make them pass would be explicitly setting the triple to include vulkan. What do you think? Is that acceptable?

@maarquitos14
Copy link
Contributor Author

@Keenuts friendly ping

@Keenuts
Copy link
Contributor

Keenuts commented Apr 30, 2025

@Keenuts friendly ping

Sorry, missed your notification
You mean we have tests using spirv-unknown-unknown for Vulkan? If so, yes I don't see any issues with updating those to have the explicit vulkan env bit

@maarquitos14
Copy link
Contributor Author

@Keenuts friendly ping

Sorry, missed your notification You mean we have tests using spirv-unknown-unknown for Vulkan? If so, yes I don't see any issues with updating those to have the explicit vulkan env bit

Yes, that's what I meant. I'll update those and ping again when the CI is green to make sure we are on the same page.

@maarquitos14 maarquitos14 force-pushed the maronas/use-spirv-friendly-call branch from eef5045 to 1a4e754 Compare May 1, 2025 08:41
@maarquitos14 maarquitos14 marked this pull request as ready for review May 1, 2025 13:01
@maarquitos14
Copy link
Contributor Author

@Keenuts @bader @VyacheslavLevytskyy @MrSidims @michalpaszkowski this is ready for review now. Note that this changed significantly since the first time it was open.

@Keenuts
Copy link
Contributor

Keenuts commented May 2, 2025

@Keenuts @bader @VyacheslavLevytskyy @MrSidims @michalpaszkowski this is ready for review now. Note that this changed significantly since the first time it was open.

Don't know for others, but there is the re-request review button which will make this reappear in the https://github.com/pulls/review-requested page (vs a ping which is 1 notification in a ocean of noise)

Comment on lines +294 to +295
// Can we rely on "hlsl.shader" attribute? Is it mandatory for Vulkan env? If
// so, we can set Env to Vulkan whenever we find it, and to OpenCL otherwise.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but we can rely on it? Can we assume that if we find such an attribute we're in Vulkan env?

Comment on lines +270 to +274
// FIXME: At the moment, there's a possibility that both `isOpenCLEnv()` and
// `isVulkanEnv()` return true. This is because the Triple is not always
// precise enough. For now, we'll rely instead on `isLogicalSPIRV()`, but this
// should be changed when `isOpenCLEnv()` and `isVulkanEnv()` cannot be true
// at the same time.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean both return false if the env is Unknown no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, they both return true. In order to not break current behavior, where some users of SPIRV BE rely on spirv-unknown-unknown, we need to do it this way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SPIRVEnvType getEnv() const { return Env; }
  bool isOpenCLEnv() const { return getEnv() == OpenCL; }
  bool isVulkanEnv() const { return getEnv() == Vulkan; }

Env being an enum, not a bitmask, either both return false when getEnv() is Unknown or they are exclusive, or am I misreading something?

Comment on lines +92 to +100
SPIRVEnvType getEnv() const { return Env; }
bool isOpenCLEnv() const { return getEnv() == OpenCL; }
bool isVulkanEnv() const { return getEnv() == Vulkan; }
// FIXME: This should check the triple arch instead, but a lot of places use
// this method now instead of `is[OpenCL/Vulkan]Env()`, and this is a
// shortcut to make sure `is[OpenCL/Vulkan]Env()` works as expected. When we
// change back all uses of `isLogicalSPIRV()` to `is[OpenCL/Vulkan]Env()`, we
// can implement this correctly again.
bool isLogicalSPIRV() const { return isVulkanEnv(); }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine requiring an explicit -vulkan when targeting vulkan.
Question: shall those 2 functions be:

bool isKernelEnv() { return Env==Unknown && (arch == spirv64 || arch == spirv32)
bool isShaderEnv() { return OS == vulkan }
bool isLogicalSPIRV() { return arch == spirv }
```

For now we gated many capabilities/things around `isOpenCL`/`isVulkan`, but we might to change that?

The `StorageImageReadWithoutFormat` check would is isShader(), but the Structurizer would rely on `isLogicalSPIRV()`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can explore something along these lines, although one thing we wanted to do is decouple physical/logical SPIRV from Kernel/Shader env, so probably we don't want to do exactly bool isKernelEnv() { return Env==Unknown && (arch == spirv64 || arch == spirv32).

@maarquitos14 maarquitos14 requested review from bader, MrSidims and Keenuts May 2, 2025 10:51
@maarquitos14
Copy link
Contributor Author

Don't know for others, but there is the re-request review button which will make this reappear in the https://github.com/pulls/review-requested page (vs a ping which is 1 notification in a ocean of noise)

Thanks, I have done it now. Originally I couldn't even ask for reviewers myself (@VyacheslavLevytskyy did it for me), so I assumed I could not ask for re-review either, but turns out I can.

@@ -36,6 +36,10 @@ class StringRef;
class SPIRVTargetMachine;

class SPIRVSubtarget : public SPIRVGenSubtargetInfo {
public:
// Enum for the SPIR-V environment: OpenCL, Vulkan or Unkwnown.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Enum for the SPIR-V environment: OpenCL, Vulkan or Unkwnown.
// Enum for the SPIR-V environment: OpenCL, Vulkan or Unknown.

What is the semantic meaning of Unknown? Does it mean it could be either OpenCL or Vulkan? Or does it mean "invalid" since it is not set?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants