JIT Engine¶
mlir-graphblas.MlirJitEngine
provides a way to go from MLIR code and a set of passes to runnable Python code
using a Just-in-Time compiler strategy.
engine = MlirJitEngine(llvmlite_engine=None)
An optional llvmlite
engine can be passes in. Otherwise a new one will be created.
The workflows for the JIT engine is:
mlir-opt converts MLIR code into LLVM IR through a series of passes
mlir-translate converts LLVM IR into LLVM code
llvmlite compiles LLVM code into machine code
pymlir is used to inspect the original MLIR code signatures for type information
Python functions are created which accept numeric or numpy types
The mechanism to trigger this workflow is
engine.add(mlir_code, passes)
If an error is not raised, the functions defined in mlir_code
will be available by indexing into the engine.
some_func = engine["some_func"]
Example¶
>>> mlir_code = b"""
#trait_1d_scalar = {
indexing_maps = [
affine_map<(i) -> (i)>, // A
affine_map<(i) -> (i)> // X (out)
],
iterator_types = ["parallel"],
doc = "X(i) = A(i) OP Scalar"
}
func @scale_array(%input: tensor<?xf64>, %scale: f64) -> tensor<?xf64> {
%0 = linalg.generic #trait_1d_scalar
ins(%input: tensor<?xf64>)
outs(%input: tensor<?xf64>) {
^bb(%a: f64, %s: f64):
%0 = mulf %a, %scale : f64
linalg.yield %0 : f64
} -> tensor<?xf64>
return %0 : tensor<?xf64>
}
"""
>>> passes = [
'--linalg-bufferize',
'--func-bufferize',
'--finalizing-bufferize',
'--convert-linalg-to-affine-loops',
'--lower-affine',
'--convert-scf-to-std',
'--convert-std-to-llvm',
]
>>> from mlir_graphblas import MlirJitEngine
>>> engine = MlirJitEngine()
>>> engine.add(mlir_code, passes)
['scale_array']
>>> import numpy as np
>>> x = np.array([1.1, 2.2, 3.3, 4.4, 5.5])
>>> engine['scale_array'](x, 20.0)
array([ 22., 44., 66., 88., 110.])
More Examples¶
Here is a series of tutorials and examples for the JIT engine.
They assume knowledge of the MLIR’s linalg dialect and go over how to compile and use MLIR code via the JIT engine.
The content of the tutorials are somewhat sequentially dependent as some later tutorials assume completion of previous tutorials.
Much of the complexity when using the JIT engine in practice comes from writing the MLIR code itself. While some of these tutorials go over features specific to the JIT engine, many of them are simply example uses of the JIT engine plus some MLIR code that can be useful as a template to learn from.