All Projects → spcl → pymlir

spcl / pymlir

Licence: BSD-3-Clause license
Python interface for MLIR - the Multi-Level Intermediate Representation

Programming Languages

python
139335 projects - #7 most used programming language
MLIR
15 projects

Projects that are alternatives of or similar to pymlir

Optviewer Demo
Demonstration of LLVM's opt-viewer tool
Stars: ✭ 63 (-25%)
Mutual labels:  llvm, compilers
open-ops
Open Optimizing Parallelizing System
Stars: ✭ 21 (-75%)
Mutual labels:  llvm, compilers
Llvm Tutor
A collection of out-of-tree LLVM passes for teaching and learning
Stars: ✭ 941 (+1020.24%)
Mutual labels:  llvm, compilers
Llvm Heat Printer
LLVM Profiling Visualization
Stars: ✭ 68 (-19.05%)
Mutual labels:  llvm, compilers
Meta Clang
Clang C/C++ cross compiler and runtime for OpenEmbedded/Yocto Project
Stars: ✭ 76 (-9.52%)
Mutual labels:  llvm, compilers
Jlang
JLang: Ahead-of-time compilation of Java programs to LLVM
Stars: ✭ 186 (+121.43%)
Mutual labels:  llvm, compilers
Gllvm
Whole Program LLVM: wllvm ported to go
Stars: ✭ 126 (+50%)
Mutual labels:  llvm, compilers
suicide
LLVM pass that detects one undefined behavior, and emits code to delete your hard drive
Stars: ✭ 33 (-60.71%)
Mutual labels:  llvm, compilers
compiler
My first attempt to create a compiler
Stars: ✭ 16 (-80.95%)
Mutual labels:  compilers
LOWLLVM
参照着OLLVM写的一个混淆库,只要机器上有装LLVM,就可以直接编译拿来用
Stars: ✭ 46 (-45.24%)
Mutual labels:  llvm
compilers-lectures
Lectures for the class on [email protected]
Stars: ✭ 67 (-20.24%)
Mutual labels:  compilers
llvm-package-windows
Provides LLVM binary packages for an (almost) complete Windows build matrix. Built and packaged by GitHub Actions.
Stars: ✭ 77 (-8.33%)
Mutual labels:  llvm
manyclangs
Repository hosting unofficial binary pack files for many commits of LLVM
Stars: ✭ 125 (+48.81%)
Mutual labels:  llvm
comp
Disciplina de Compiladores (INF01147) - INF/UFRGS
Stars: ✭ 28 (-66.67%)
Mutual labels:  compilers
CFI-LB
Adaptive Callsite-sensitive Control Flow Integrity - EuroS&P'19
Stars: ✭ 13 (-84.52%)
Mutual labels:  llvm
lua-in-rust
The Lua programming language, implemented in Rust.
Stars: ✭ 76 (-9.52%)
Mutual labels:  compilers
surveyor
A symbolic debugger for C/C++ (via LLVM), machine code, and JVM programs
Stars: ✭ 14 (-83.33%)
Mutual labels:  llvm
doc
Design documents related to the decompilation pipeline.
Stars: ✭ 23 (-72.62%)
Mutual labels:  llvm
imp
Compiler for IMP programming language implemented in Haskell
Stars: ✭ 16 (-80.95%)
Mutual labels:  llvm
Batch-First
A JIT compiled chess engine which traverses the search tree in batches in a best-first manner, allowing for neural network batching, asynchronous GPU use, and vectorized CPU computations.
Stars: ✭ 27 (-67.86%)
Mutual labels:  llvm

codecov

pyMLIR: Python Interface for the Multi-Level Intermediate Representation

pyMLIR is a full Python interface to parse, process, and output MLIR files according to the syntax described in the MLIR documentation. pyMLIR supports the basic dialects and can be extended with other dialects. It uses Lark to parse the MLIR syntax, and mirrors the classes into Python classes. Custom dialects can also be implemented with a Python string-format-like syntax, or via direct parsing.

Note that the tool does not depend on LLVM or MLIR. It can be installed and invoked directly from Python.

Instructions

How to install: pip install pymlir

Requirements: Python 3.6 or newer, and the requirements in setup.py or requirements.txt. To manually install the requirements, use pip install -r requirements.txt

Problem parsing MLIR files? Run the file through LLVM's mlir-opt --mlir-print-op-generic to get the generic form of the IR (instructions on how to build/install MLIR can be found here):

$ mlir-opt file.mlir --mlir-print-op-generic > output.mlir

Found other problems parsing files? Not all dialects and modes are supported. Feel free to send us an issue or create a pull request! This is a community project and we welcome any contribution.

Usage examples

Parsing MLIR files into Python

import mlir

# Read a file path, file handle (stream), or a string
ast1 = mlir.parse_path('/path/to/file.mlir')
ast2 = mlir.parse_file(open('/path/to/file.mlir', 'r'))
ast3 = mlir.parse_string('''
module {
  func @toy_func(%tensor: tensor<2x3xf64>) -> tensor<3x2xf64> {
    %t_tensor = "toy.transpose"(%tensor) { inplace = true } : (tensor<2x3xf64>) -> tensor<3x2xf64>
    return %t_tensor : tensor<3x2xf64>
  }
}
''')

Inspecting MLIR files in Python

MLIR files can be inspected by dumping their contents (which will print standard MLIR code), or by using the same tools as you would with Python's ast module.

import mlir

# Dump valid MLIR files
m = mlir.parse_path('/path/to/file.mlir')
print(m.dump())

print('---')

# Dump the AST directly
print(m.dump_ast())

print('---')

# Or visit each node type by implementing visitor functions
class MyVisitor(mlir.NodeVisitor):
    def visit_Function(self, node: mlir.astnodes.Function):
        print('Function detected:', node.name.value)
        
MyVisitor().visit(m)

Transforming MLIR files

MLIR files can also be transformed with a Python-like NodeTransformer object.

import mlir

m = mlir.parse_path('/path/to/file.mlir')

# Simple node transformer that removes all operations with a result
class RemoveAllResultOps(mlir.NodeTransformer):
    def visit_Operation(self, node: mlir.astnodes.Operation):
        # There are one or more outputs, return None to remove from AST
        if len(node.result_list) > 0:
            return None
            
        # No outputs, no need to do anything
        return self.generic_visit(node)
        
m = RemoveAllResultOps().visit(m)

# Write back to file
with open('output.mlir', 'w') as fp:
    fp.write(m.dump())

Using custom dialects

Custom dialects can be written and loaded as part of the pyMLIR parser. See full tutorial here.

import mlir
from lark import UnexpectedCharacters
from .mydialect import dialect

# Try to parse as-is
try:
    m = mlir.parse_path('/path/to/matrixfile.mlir')
except UnexpectedCharacters:  # MyMatrix dialect not recognized
    pass
    
# Add dialect to the parser
m = mlir.parse_path('/path/to/matrixfile.mlir', 
                    dialects=[dialect])

# Print output back
print(m.dump_ast())

MLIR from scratch with the builder API

pyMLIR has a Builder API that can create MLIR ASTs on the fly within Python code.

import mlir.builder

builder = mlir.builder.IRBuilder()
mlirfile = builder.make_mlir_file()
module = mlirfile.default_module

with builder.goto_block(builder.make_block(module.region)):
    hello = builder.function("hello_world")
    block = builder.make_block(hello.region)
    builder.position_at_entry(block)

    x, y = builder.add_function_args(hello, [builder.F64, builder.F64], ['a', 'b'])

    adder = builder.addf(x, y, builder.F64)
    builder.ret([adder], [builder.F64])

print(mlirfile.dump())

prints:

module {
  func @hello_world(%a: f64, %b: f64) {
    %_pymlir_ssa = addf %a , %b : f64
    return %_pymlir_ssa : f64
  }
}

See also saxpy for a full example that registers and uses a dialect in the builder.

Built-in dialect implementations and more examples

All dialect implementations can be found in the dialects subfolder. Additional uses of the library, including a custom dialect implementation, can be found in the tests subfolder.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].