|
1 | 1 | # python-mlir-graphblas |
2 | 2 | Implementation of the GraphBLAS spec using MLIR python bindings |
| 3 | + |
| 4 | +A full GraphBLAS implementation is possible in relatively few lines |
| 5 | +of Python code because we rely heavily on the `linalg.generic` operation |
| 6 | +in MLIR, specifically its appropriate handling of different Sparse Tensor |
| 7 | +layouts. Each GraphBLAS operation becomes essentially a single |
| 8 | +`linalg.generic` operation with some minor pre- and post-handling of |
| 9 | +object creation. |
| 10 | + |
| 11 | + |
| 12 | +# Usage |
| 13 | + |
| 14 | +### Create a Matrix or Vector |
| 15 | + |
| 16 | +```python |
| 17 | +>>> from mlir_graphblas import types, operations, operators, Matrix, Vector |
| 18 | + |
| 19 | +>>> m = Matrix.new(types.FP64, 2, 5) |
| 20 | +>>> m.build([0, 0, 1, 1, 1], [1, 3, 0, 3, 4], [1., 2., 3., 4., 5.75]) |
| 21 | +>>> m |
| 22 | +Matrix<FP64, shape=(2, 5), format=CSR> |
| 23 | + |
| 24 | +>>> v = Vector.new(types.FP64, 5) |
| 25 | +>>> v.build([0, 2, 3, 4], [3., -2., 4., 1.5]) |
| 26 | +>>> v |
| 27 | +Vector<FP64, size=5> |
| 28 | +``` |
| 29 | + |
| 30 | +### Perform Operations |
| 31 | + |
| 32 | +Each operation requires an output object to be passed in. |
| 33 | + |
| 34 | +```python |
| 35 | +>>> from mlir_graphblas.operators import Semiring |
| 36 | + |
| 37 | +>>> z = Vector.new(types.FP64, 2) |
| 38 | +>>> operations.mxv(z, Semiring.plus_times, m, v) |
| 39 | +>>> z |
| 40 | +Vector<FP64, size=2) |
| 41 | +``` |
| 42 | + |
| 43 | +### View Results |
| 44 | + |
| 45 | +```python |
| 46 | +>>> indices, values = z.extract_tuples() |
| 47 | +>>> indices |
| 48 | +array([0, 1], dtype=uint64) |
| 49 | +>>> values |
| 50 | +array([ 8. , 33.625]) |
| 51 | +``` |
| 52 | + |
| 53 | +# Building MLIR |
| 54 | + |
| 55 | +Until LLVM 16.0 is released, the required MLIR operations in the sparse_tensor dialect will only be |
| 56 | +available on the main repo branch, meaning there aren't any packages readily available to install |
| 57 | +from conda-forge. |
| 58 | + |
| 59 | +To build locally, download the LLVM repo from GitHub. |
| 60 | + |
| 61 | +``` |
| 62 | +git clone https://github.com/llvm/llvm-project.git |
| 63 | +``` |
| 64 | + |
| 65 | +Next create a conda environment for building the project. |
| 66 | + |
| 67 | +``` |
| 68 | +conda create -n mlir_build_env -y |
| 69 | +conda activate mlir_build_env |
| 70 | +conda install python=3.10 numpy pyyaml cmake ninja pybind11 python-mlir-graphblas |
| 71 | +``` |
| 72 | + |
| 73 | +Define `PREFIX` as the location of your environment (active env location when running `conda info`). |
| 74 | +Then run cmake. |
| 75 | + |
| 76 | +``` |
| 77 | +export PREFIX=/location/to/your/conda/environment |
| 78 | +
|
| 79 | +cd llvm-project |
| 80 | +mkdir build |
| 81 | +cd build |
| 82 | +
|
| 83 | +cmake -G Ninja ../llvm \ |
| 84 | + -DCMAKE_INSTALL_PREFIX=$PREFIX \ |
| 85 | + -DLLVM_ENABLE_PROJECTS=mlir \ |
| 86 | + -DLLVM_BUILD_EXAMPLES=ON \ |
| 87 | + -DLLVM_INSTALL_UTILS=ON \ |
| 88 | + -DLLVM_TARGETS_TO_BUILD="X86;AArch64;NVPTX;AMDGPU" \ |
| 89 | + -DCMAKE_BUILD_TYPE=Release \ |
| 90 | + -DLLVM_ENABLE_ASSERTIONS=ON \ |
| 91 | + -DLLVM_BUILD_LLVM_DYLIB=ON \ |
| 92 | + -DMLIR_ENABLE_BINDINGS_PYTHON=ON \ |
| 93 | + -DPython3_EXECUTABLE=`which python` |
| 94 | +``` |
| 95 | + |
| 96 | +If building on a Mac, perform this additional step. |
| 97 | + |
| 98 | +``` |
| 99 | +cp $PREFIX/lib/libtinfo* lib/ |
| 100 | +cp $PREFIX/lib/libz* lib/ |
| 101 | +``` |
| 102 | + |
| 103 | +Then build the project |
| 104 | + |
| 105 | +``` |
| 106 | +cmake --build . |
| 107 | +cmake --install . |
| 108 | +``` |
| 109 | + |
| 110 | +Finally, set `LLVM_BUILD_DIR` to point to the current build directory. |
| 111 | +Now python-mlir-graphblas should be usable. Verify by running tests. |
| 112 | + |
| 113 | +``` |
| 114 | +LLVM_BUILD_DIR=. pytest --pyargs mlir_graphblas |
| 115 | +``` |
0 commit comments