Multi-Level Intermediate Representation (MLIR)
•MLIR : Multi-Level Intermediate Representation
•Model -> MLIR -> Hardware Specific Code
•MLIR is:
•A representation format for Intermediate Representation (IR)
•A library of compiler utilities.
•It sits between the model representation and low-level compilers that generate hardware-specific code.
•Abstraction for Global Compiler Infrastructure
•MLIR provides the infrastructure for high level compilation
•It supports gradual lowering to low level representations via customizable dialects
•LLVM IR is supported as a lower level dialect which provides integration with LLVM execution environment.
•MLIR contains tools for creation of custom dialects and for inter-dialect transformation.
•MLIR does not specify any fixed instruction set unlike most IR representations.
•In the Machine Learning Domain there has been a proliferation of input formats:
- TensorFlow graphs (Google)
- XLA IR / HLO (Google)
- Onnx (Facebook, Microsoft)
- Glow (Facebook)
- nGraph (Intel)
- Stripe (PlaidML, now Intel)
- Halide IR, TVM (universities)
•MLIR consists of several dialects:
- TensorFlow IR
- XLA HLO IR
- Affine dialect ( polyhedral representation )
- LLVM IR
- Tensorflow Lite
- GPU dialects
- Vector dialect
- Custom defined IRs …
•MLIR also includes GPU dialect to target
- CUDA,
- RocM, and
- SPIR-V/Vulkan
•Conversion from one dialect to another can be performed using mlir-opt tool
For example,
mlir-opt -convert-spirv-to-llvm <filename.mlir>
•A MLIR dialect includes:
● A prefix (“namespace”)
● A list of custom types, each its C++ class.
● A list of operations, each its name and C++ class implementation:
- Verifier for operation invariants
- Semantics (has-no-side-effects, constant-folding etc.)
● Possibly custom parser and assembly printer
● Passes: analysis, transformations, and dialect conversions.
•MLIR does not provide an instruction set
•In MLIR everything is about operations
Example:
func @some_func(%arg0: !my_dialect<"custom_type">)
-> !another_dialect<"other_type"> {
%result = "custom.operation"(%arg0)
: (!my_dialect<"custom_type">) ->
!another_dialect<"other_type">
return %result : !another_dialect<"other_type">
}