| # RUN: env SUPPORT_LIB=%mlir_c_runner_utils \ |
| # RUN: %PYTHON %s | FileCheck %s |
| |
| import ctypes |
| import os |
| import sys |
| import tempfile |
| |
| from mlir import ir |
| from mlir import runtime as rt |
| from mlir.dialects import builtin |
| from mlir.dialects import sparse_tensor as st |
| import numpy as np |
| |
| _SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__)) |
| sys.path.append(_SCRIPT_PATH) |
| from tools import sparsifier |
| |
| |
| def boilerplate(): |
| """Returns boilerplate main method.""" |
| return """ |
| #Dense = #sparse_tensor.encoding<{ |
| map = (i, j) -> (i: dense, j: dense) |
| }> |
| |
| #map = affine_map<(d0, d1) -> (d0, d1)> |
| func.func @add(%st_0 : tensor<3x4xf64, #Dense>, |
| %st_1 : tensor<3x4xf64, #Dense>) attributes { llvm.emit_c_interface } { |
| %out_st = tensor.empty() : tensor<3x4xf64, #Dense> |
| %res = linalg.generic {indexing_maps = [#map, #map, #map], |
| iterator_types = ["parallel", "parallel"]} |
| ins(%st_0, %st_1 : tensor<3x4xf64, #Dense>, tensor<3x4xf64, #Dense>) |
| outs(%out_st : tensor<3x4xf64, #Dense>) { |
| ^bb0(%in_0: f64, %in_1: f64, %out: f64): |
| %2 = sparse_tensor.binary %in_0, %in_1 : f64, f64 to f64 |
| overlap = { |
| ^bb0(%arg1: f64, %arg2: f64): |
| %3 = arith.addf %arg1, %arg2 : f64 |
| sparse_tensor.yield %3 : f64 |
| } |
| left = { |
| ^bb0(%arg1: f64): |
| sparse_tensor.yield %arg1 : f64 |
| } |
| right = { |
| ^bb0(%arg1: f64): |
| sparse_tensor.yield %arg1 : f64 |
| } |
| linalg.yield %2 : f64 |
| } -> tensor<3x4xf64, #Dense> |
| sparse_tensor.print %res : tensor<3x4xf64, #Dense> |
| return |
| } |
| """ |
| |
| |
| def main(): |
| support_lib = os.getenv("SUPPORT_LIB") |
| assert support_lib is not None, "SUPPORT_LIB is undefined" |
| if not os.path.exists(support_lib): |
| raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), support_lib) |
| |
| # CHECK-LABEL: TEST: all dense |
| # CHECK: ---- Sparse Tensor ---- |
| # CHECK: nse = 12 |
| # CHECK: dim = ( 3, 4 ) |
| # CHECK: lvl = ( 3, 4 ) |
| # CHECK: values : ( 1, 1, 0, 1, 0, 6, 2, 3, 0, 0, 0, 2 ) |
| # CHECK: ---- |
| print("\nTEST: all dense") |
| with ir.Context() as ctx, ir.Location.unknown(): |
| compiler = sparsifier.Sparsifier( |
| extras="sparse-assembler,", |
| options="enable-runtime-library=false", |
| opt_level=2, |
| shared_libs=[support_lib], |
| ) |
| module = ir.Module.parse(boilerplate()) |
| engine = compiler.compile_and_jit(module) |
| print(module) |
| |
| a = np.array([1, 0, 0, 1, 0, 2, 2, 0, 0, 0, 0, 1], dtype=np.float64) |
| b = np.array([0, 1, 0, 0, 0, 4, 0, 3, 0, 0, 0, 1], dtype=np.float64) |
| mem_a = ctypes.pointer(ctypes.pointer(rt.get_ranked_memref_descriptor(a))) |
| mem_b = ctypes.pointer(ctypes.pointer(rt.get_ranked_memref_descriptor(b))) |
| |
| # Invoke the kernel and get numpy output. |
| # Built-in bufferization uses in-out buffers. |
| engine.invoke("add", mem_a, mem_b) |
| |
| |
| if __name__ == "__main__": |
| main() |