Beginner questions about MLIR

Hello! I have used LLVM for a number of compiler projects and I have some questions about MLIR.

From what I understand, MLIR can be used to both target GPUs and LLVM. Can you choose what backend your MLIR module targets? Can you have parts of your MLIR module compile to different targets, say if I wanted some functions to target LLVM and some target SPIR-V? Does MLIR handle the calling between these functions?

For example, if I have a source language that looks like this:

function(cpu) foo() {
    // do cpu things 
}

function(gpu) bar {
    // do gpu things
}

Can I compile foo to LLVM IR and bar to SPIR-V? Does MLIR target any other GPUs?

Also, does MLIR have a C API?

Sorry if these questions are a little noobish, I didn’t know where else to ask :sweat_smile:

First, keep in mind that MLIR is still a quite young project and not all the pieces may be wired end-to-end.

That said there is already a bunch of things that you can play with. In particular for understanding the GPU aspects I invite you to look at the Cuda and the Vulkan runners for examples of how you can have host and device computation that can compose in the same IR module.

(no there is no C API for MLIR right now)

1 Like

MLIR is a framework/toolkit, so you can certainly write passes that compile different parts of your program to target different backends. In our project (GitHub - iree-org/iree: 👻) we outline the “dispatch” parts of a program to be executed on a GPU using a SPIR-V compilation pipeline and separately compile the “sequencing” parts to be run on a host CPU (as an example).

1 Like

Thank you! That clears up things greatly. In the CUDA and Vulkan examples, the IR for the GPU Kernels looks like it doesn’t contain anything specific for the backend except for a few SPIR-V lines. Is making a module that could compile to both SPIR-V and CUDA possible / a design goal?

Hi @phase , good findings! :slight_smile: As the name shows, the SPIR-V lines you mentioned in the above are used to specify SPIR-V’s target environment. You can think it as the target description without going into more nuanced details so it’s Vulkan/SPIR-V specific information. Normally when one writes a Vulkan application, one needs to probe the Vulkan implementation regarding feature/limit supports with API calls as a first step. The mlir-vulkan-runner is just an application. It should actually do similar things to probe the implementation and derive the target environment there but at the moment that code is not yet fully implemented. We are not using advanced features anyway so we just use the (almost) bare minimum requirements guaranteed by the spec and attach there. After the probing code is properly done in mlir-vulkan-runner, you won’t need to explicitly specify that. Hopefully this clarifies.

As others said, MLIR provides lots of reusable components for one to mix and compose pipelines to tailor towards one’s needs. As long as you pulled in necessary components for CUDA and Vulkan, you should be able to target both.

1 Like