[RFC] Proposal for new XeVM dialect

[RFC] Adding XeVM dialect to MLIR

TLDR;

We need a new dialect, XeVM, like NVVM or ROCDL, to supplement LLVM dialect and expose Intel Xe architecture specific features.

Background and Motivation

Intel is building an upstream MLIR lowering pipeline for Intel GPU to access Intel-specific hardware features. MLIR already has XeGPU dialect that exposes those features such as 2D block memory operation, mma and etc. But upstream still lacks a lowering pipeline from XeGPU dialect.

Other GPU vendors like NVidia and AMD lower their respective dialects, nvgpu and amdgpu, to LLVM dialect along with target specific dialects like nvvm and rocdl. The additional dialects help hide intrinsic calls that don’t fit well with MLIR passes as intrinsics calls are generic function calls instead of proper ops. And the dialects define target attributes that are required for module serialization under GPU pipeline.

By contrast, Intel needs to rely on SPIR-V dialect as lowering target instead of LLVM as upstream does not have a dialect like nvvm or rocdl for Intel GPU.

Challenges

We have encountered two major issues while developing a GPU pipeline for Intel GPU targeting SPIR-V dialect.

First, SPIR-V dialect is not integration friendly. The lowering pipeline does not provide flexible integration with popular GPU AI frameworks. For example, Triton and OpenXLA are yet to accept any downstream extensions to MLIR and any extra code for Intel GPU support needs to be added to the respective project repository. In addition, their lowering pipeline is implemented around LLVM dialect. Updating all such pipelines requires major refactoring and doing it in a clean way to accommodate SPIR-V dialect is a significant challenge as Intel does not own those projects. Also, SPIR-V dialect lowering path is less mature than that of LLVM in upstream. For example, vector to LLVM conversion pass covers more ops compared to vector to SPIR-V conversion pass.

Second, SPIR-V dialect is not future proof for Intel Xe Architecture. Intel currently exposes all advanced Xe architecture features through SPIR-V by adding SPIR-V extensions but that is not a permanent choice. However, explicit lowering through SPIR-V dialect signifies SPIR-V as a permanent layer in upstream lowering for Xe architecture. It forces SPIR-V as the architectural interface between MLIR and lower-level code generation stack. Using SPIR-V dialect as a way to access advanced features is not future proof and should be avoided.

Solution

To address the above challenges, we propose XeVM dialect.

XeVM dialect is an MLIR leaf dialect extending LLVM dialect with operation unique to Intel GPU in the same way as dialects like nvvm and rocdl. With XeVM dialect, framework integration for Intel GPU can be done easily as it fits well into pipelines designed around targeting LLVM.

XeVM dialect exposes all HW features for Xe architecture, and it does it in a way without relying on SPIR-V specification. This removes the role of SPIR-V serving as an architectural interface for Intel GPU and makes any code targeting XeVM future proof.

XeVM dialect will initially use LLVM’s SPIR-V backend, now an official LLVM backend, for module serialization, but this is an implementation detail subject to change depending on how Xe features are exposed in the future.

We want to highlight that XeVM dialect is not an optional but essential component needed for enabling Intel Xe architecture upstream which is the only reasonable way to integrate Intel GPU support for downstream projects.

Scope of XeVM and upstreaming plan

The scope of XeVM dialect is to represent all Xe architecture features that do not have an LLVM counterpart. Those include

  • Advanced memory operations such as load/store/prefetch operations on 2D tiles

  • Advanced arithmetic operations such as MMA

  • Barrier operations

  • Access to hardware indices

  • Other features

Upstreaming is planned in multiple steps. The following is a tentative list of future PRs and items covered in each step.

  • XeVM dialect definition and dialect op tests: Definition includes memory, mma and barrier operations along with XeVM target attribute.

  • XeVM attach target transform pass

  • XeVM to LLVM conversion pass

  • XeVM target for gpu kernel (gpu.object) creation

  • XeVM dialect integration tests using GPU compilation pipeline with XeVM target.

  • XeVM operations for hardware indices and GPU to XeVM conversion pass: XeVM lowering will have a temporary dependency on convert-gpu-to-llvm-spv pass till this point

Once XeVM upstreaming is complete, we will add XeGPU to XeVM lowering.

Related older proposal

Intel created an RFC to add GEN dialect and presented the proposal last year at the MLIR open design forum that eventually got rejected. XeVM may appear similar to GEN but they are designed for different goals.

They may appear similar as they are both based on LLVM and can solve framework integration issues. But there are major differences.

The primary goal of GEN was to expose select assembly instructions while still tied to SPIR-V specification.

In contrast, XeVM has a goal of freeing Intel GPU from using SPIR-V as a hard architecture interface. Making all investment targeting XeVM future proof. And XeVM has a broader scope of operation support. It is not tied to just select assembly instructions and intends to expose all hardware features for Intel Xe architecture.

GEN had to rely on external software, Khronos LLVM SPIR-V translator, for serialization.

In contrast, XeVM is not tied to a specific architecture interface and can use the DeFacto LLVM backend of choice for other Intel tools such as SYCL. The current backend is SPIR-V backend, but due to XeVM’s flexibility, it can move to other backends and stay in sync with the rest of Intel GPU eco system even if any such change happens in the future.

Link to initial PR for dialect definition: https://github.com/llvm/llvm-project/pull/144811
Link to POC with integration tests: GitHub - silee2/llvm-project at xevmWorkspace

@rengolin

Thanks for writing up the proposal @silee2. I think that if you have motivation for lowering via LLVM (i.e., ease of integration with downstream frameworks), having a custom dialect with wrappers around Xe intrinsics makes sense.

However, I found your analysis very difficult to follow and seemingly misguided when it comes to weighing whether to go through the LLVM or the SPIR-V lowering path in MLIR. I posted some replies and comments below, but the entire argument is not necessary IMO and removing it could simplify the RFC a lot.

Do you actually intend to change the binary blob format accepted by the driver / API to the llvm bitcode? I don’t know how to parse this.

The conclusion in the first sentence sounds incorrect to me: it’s the downstream projects that are not integration friendly by having inflexible pipelines that assume LLVM lowering, not the SPIR-V dialect.

I don’t understand what’s stopping you from having Intel Xe-specific intrinsics at the level of SPIR-V? IIUC, you still have to emit them after you go through the SPIR-V LLVM backend, so I don’t understand how SPIR-V can be a limiting factor here.

I don’t see a substantial difference between what you propose and the GEN dialect. IIUC, the latter was supposed to be similar to xevm/nvvm/rocdl but lower to both llvm and spirv. The main issue with GEN I saw back then was that the surface area of the dialect had significant overlap with the natively supported SPIRV constructs like workgroup / thread IDs, etc.

Why would this be the case?

I’m not aware of any major missing vector to spirv conversions or fundamental limitations in this pass. If there are some, we can definitely extend the conversion to cover whatever you need.

This is not a review of the (now defunct) GEN dialect. Let’s not bring that back in this thread or we’ll derail the discussion. It was mentioned above only as a reasoning to why XEVM is not the same as GEN.

The Intel GPU back-end is in the LLVM tree as the SPIR-V back-end. It was developed, contributed and now maintained by Intel. It does the same thing as PTX/ROC back-ends, just uses an open standard. Do not confuse the MLIR SPIR-V dialect with the LLVM SPIR-V back-end, these are not the same thing.

It is now an official back-end and is used by OpenCL, SYCL and MLIR (downstream), and Intel keeps that back-end in production quality precisely because of those ingress. We should use the same infrastructure for all three that we already committed to and spend a lot of effort maintaining.

This is in line with the other MLIR GPU dialects and there’s no strong argument against it, no principle violations here. Forcing one to use a particular dialect is not in line with MLIR community practices.

No one is forced to use the quant dialect to do quantization, just because it exists (quite the opposite). No one is forced to use linalg or TOSA or any other dialect, so that argument is invalid.

When you say “we”, are you talking about your company, the community in general or Intel?

  • I’d be surprised if AMD is willing to put effort into the SPIR-V dialect upstream, so I’m guessing it’s not that.
  • If it’s Intel, then that’s not going to happen, as we already maintain one back-end (in LLVM) for all our ingress, including MLIR downstream, which we’re trying to upstream.
  • If it’s the community, then I doubt anything is going to change on the SPIR-V side. Not that far, last year, we had the same iteration and no one has volunteered to improve support, and maintainers even mentioned removing the SPIR-V dialect if no one else uses.

In summary:

  • The MLIR SPIR-V dialect and the LLVM SPIR-V back-end are completely different things, aimed at different usages (the intersection of support is small) and on the opposite ends of both “production ready” and “amount of effort” spectrums.
  • The Intel GPU back-end (SPIR-V) in LLVM is now in production in LLVM upstream.
  • XeGPU / XeVM follow exactly the same path as the other two GPU dialect stacks in MLIR.
  • This is already being used extensively upstream (for OpenCL) and downstream inside Intel, for both SYCL and MLIR.
  • We are following the same practices as the other GPU stacks, so there should be no deltas (modulo bugs we need to fix).
  • The MLIR project does not enforce the usage of any dialects onto its users, upstream or downstream, so the argument that “the SPIR-V dialect exists” is moot.

Hi Renato,

I 100% agree with you on this and this was the main point of my reply. It sounds like you have a valid reason to prefer the llvm lowering path, and I don’t think anyone has objections to adding ‘intrinsic-level’ dialects to MLIR like recently discussed in Move / Remove `vcix` dialect . To me it does seem to make sense to go forward with the xevm dialect.

Do not confuse the MLIR SPIR-V dialect with the LLVM SPIR-V back-end, these are not the same thing.

Precisely because of this reason I find it weird that the RFC seems predominantly focused on discussing why the SPIR-V dialect is not the right solution. As the lead maintainer, I found this analysis and some bullet points in your reply misguided or factually incorrect and wanted to go on the record to clarify the state of SPIR-V support in MLIR. Even if we both agree it does not matter to move forward with xevm, I want to make sure we can get closer to being on the same page and have healthy discussions in the future.

Let me give you a broader answer because MLIR at large does not have a fully documented list of maintainers and this level of detail:

  • The SPIR-V dialect has two maintainers as documented in the github code owners file, myself and @antiagainst. I’m currently the lead maintainer and the official Khronos headers point to me as the point of contact for the MLIR SPIR-V generator: SPIRV-Headers/include/spirv/spir-v.xml at 2a611a970fdbc41ac2e3e328802aed9985352dca · KhronosGroup/SPIRV-Headers · GitHub . A few lines below you can see that @michalpaszkowski is listed as the point of contact for the LLVM SPIR-V backend.
  • The IREE team at large has been the original author and maintainer of the SPIR-V dialect. After the nod.ai acquisition, AMD has inherited these duties. As a team, we make sure that the SPIR-V dialect continues to be production-ready as demonstrated in IREE. This includes handling incoming issues, adding support for new ops that need to lower to SPIR-V, etc. For example, we kept up with all the incoming new vector ops like vector.[de]interleave, vector.from_elements, etc., within O(days) of these landing.
  • The IREE team also takes care of ongoing modernization / clean up of this area of the codebase. Some recent work include migrating from the Vulkan runner to the generic mlir runner to support SPIR-V integration tests and creating an upstream convert-to-spirv pass to improve test coverage at the intersection of multiple upstream dialects and their decomposition and canonicalization patterns.
  • Similar to the rest of MLIR, having complete support of the SPIR-V spec is not our goal and we generally add more extensions / ops as we need. The SPIR-V dialect has many contributors outside of the IREE team or AMD, including: ARM, Intel, Qualcomm, Imagination, Roofline, who often implement features that they find useful in their compiler stack. In those cases, the IREE team is unlikely to engage in the actual implementation beyond doing code reviews / RFC reviews / general mentorship. If you came to us and requested some OpenCL feature for Xe, we would be happy to guide you but won’t do the implementation work for you.
  • As the lead maintainer, I am not aware of anyone seriously proposing to remove the SPIR-V dialect and don’t know what you are referring to. In fact, we’ve seen the very opposite trend. SPIR-V dialect seems to be gaining a lot of popularity recently and I’d estimate the number of unique contributors within the last year to be somewhere around 15 people.

I think this statement in isolation misstates the state of both solutions. The MLIR SPIR-V dialect is production quality w.r.t. vulkan compute but the opencl support is incomplete. The LLVM SPIR-V backend is production quality w.r.t., opencl but incomplete for vulkan. Both could be extended to support the missing part of the SPIR-V spec, but that requires substantial implementation effort.

You’re absolutely right. Apologies from my part. What I meant by “not production ready” was solely around Intel GPU lowering versus the LLVM back-end, which already has all the support we need and we’ll continue maintaining. This was also my allusion to “AMD won’t care”, meaning about the CL/SYCL XeGPU lowering, not SPIR-V as a whole.

From the RFC points, I believe part of that analysis is outdated and the recurring Gen mention is a bit of battle scars from last year’s experience. Thank you for clarifying all those points from the SPIR-V dialect side. We do really need better visibility on what’s going on, as it’s not possible to follow all threads in the forum all the time. :slight_smile:

Exactly. But as the LLVM back-end already supports OpenCL for Xe, it wouldn’t make sense to ask that, or to re-implement that, here.

That was maybe a bit too local to be meaningful, I did not mean to inflate its importance. I was referring to the mention of removing the dialect if it’s going to create too many disagreements, last year when we were discussing the XeGPU dialect. This gave me the idea that the maintainers did not “care that much” or that it was “not being actively used”.

Now, thanks to your response, I know it wasn’t that at all, so it was probably more of an exasperation than a statement of fact. Sorry for having brought this up, it’s irrelevant to our discussion.

Thank you! This is exactly what I should have said, and missed the opportunity! :slight_smile:

NVVM and ROCDL are natural extensions of LLVM dialect as they map almost 1:1 to LLVM intrinsics. (although more recently some NVVM dialect started emitting inline ptx).
Is this going to be the same for XeVM?
What will drive the definition and lowering of the ops of the new dialect? I tried to infer it from the PR but looks like it doesn’t have lowering.

The driving force is Xe hardware features like 2d block io and matrix multiplication instructions. They are defined as SPIR-V extension (SPV_INTEL_subgroup_matrix_multiply_accumulate and SPV_INTEL_2d_block_io) and supported by LLVM’s SPV backend as built-ins

XeVM ops have 1:1 mapping to these operations. SPIR-V extension ops are encoded as intrinsic calls in LLVM following the convention : __spirv_{OpCodeName}{_OptionalPostfixes}

We may use inline assembly when necessary. SPV_INTEL_inline_assembly allows to use inline assembly. User Guide for SPIR-V Target

If there are no more comments, we would like people to start reviewing the PR for initial XeVM dialect definition and merge it soon.

Please note that the lack of comments within one week of publication is not a seal of approval. We will discuss this RFC in the area team meeting and get back to you.

Just a general FYI, Github codeowners mechanism is not not used to indicate maintainers of the dialect. See Usage of CODEOWNERS file for discussion. We are working on establishing a list of maintainers for MLIR following the developer policy.

I was just asking people to review the PR for technical issues, not claiming consensus had been reached.

The following

implied otherwise. We expect new dialects to start merging after they have been officially accepted.

In the meantime, this has been discussed at the Area Team meeting today. We identified in the community to have this dialect upstream, you may proceed with active reviews. The first PR must clearly identify maintainers (see announcement).