Skip to content

Commit 294c4bd

Browse files
authored
[Testing and Infra] LIT testing and passes enabling (#33)
This commit enables LIT tests and introduces example of MLP LIT test. To run all of them use: ```sh cmake --build . --target gc-check ``` Also introduced infrastructure for adding Passes and registered dummy TileNamedLinalg pass. Currently it simply print matmuls. To enable use option: "--tile-named-linalg". Signed-off-by: Dmitrii Makarenko <[email protected]>
1 parent 2b4d29d commit 294c4bd

File tree

13 files changed

+319
-2
lines changed

13 files changed

+319
-2
lines changed

include/gc-dialects/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
add_subdirectory(OnednnGraph)
22
add_subdirectory(Microkernel)
33
add_subdirectory(Linalgx)
4+
5+
set(LLVM_TARGET_DEFINITIONS Passes.td)
6+
mlir_tablegen(Passes.h.inc -gen-pass-decls -name GraphCompiler)
7+
add_public_tablegen_target(GraphCompilerPassIncGen)
8+
add_mlir_doc(Passes GraphCompilerPasses ./ -gen-pass-doc)

include/gc-dialects/Passes.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//===- Passes.h - Graph Compiler passes -------------------------*- C++ -*-===//
2+
//
3+
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef GC_PASSES_H
10+
#define GC_PASSES_H
11+
12+
#include "mlir/Pass/Pass.h"
13+
14+
namespace mlir {
15+
namespace gc {
16+
17+
#define GEN_PASS_DECL
18+
#include "gc-dialects/Passes.h.inc"
19+
20+
#define GEN_PASS_REGISTRATION
21+
#include "gc-dialects/Passes.h.inc"
22+
} // namespace gc
23+
} // namespace mlir
24+
25+
#endif // GC_PASSES_H

include/gc-dialects/Passes.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===- Passes.td - Graph Compiler passes -------------------*- tablegen -*-===//
2+
//
3+
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef GC_DIALECT_GC_PASSES
10+
#define GC_DIALECT_GC_PASSES
11+
12+
include "mlir/Pass/PassBase.td"
13+
14+
def TileLinalgNamed : Pass<"tile-named-linalg", "func::FuncOp"> {
15+
let summary = "Tile linalg named operations.";
16+
let dependentDialects =
17+
["linalg::LinalgDialect", "scf::SCFDialect", "tensor::TensorDialect"];
18+
}
19+
20+
#endif // GC_DIALECT_GC_PASSES

lib/gc-dialects/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
add_subdirectory(Linalgx)
22
add_subdirectory(Microkernel)
33
add_subdirectory(OnednnGraph)
4+
5+
add_subdirectory(Transforms)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
add_mlir_library(GCPasses
2+
TileNamed.cpp
3+
4+
ADDITIONAL_HEADER_DIRS
5+
${PROJECT_SOURCE_DIR}/include/gc-dialects
6+
7+
DEPENDS
8+
GraphCompilerPassIncGen
9+
10+
LINK_LIBS PUBLIC
11+
${mlir_dialect_libs}
12+
MLIRIR
13+
MLIRSupport
14+
MLIRBufferizationToMemRef
15+
MLIRBufferizationPipelines
16+
)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//===- TileNamed.cpp - Tile Named Linalg Ops --------------------*- C++ -*-===//
2+
//
3+
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "gc-dialects/Passes.h"
10+
#include "mlir/Dialect/Affine/IR/AffineOps.h"
11+
#include "mlir/Dialect/Func/IR/FuncOps.h"
12+
#include "mlir/Dialect/Linalg/IR/Linalg.h"
13+
#include "mlir/Dialect/Linalg/Transforms/Transforms.h"
14+
#include "mlir/Dialect/SCF/IR/SCF.h"
15+
#include "mlir/Dialect/SCF/Transforms/TileUsingInterface.h"
16+
#include "mlir/Dialect/Tensor/IR/Tensor.h"
17+
#include "mlir/Pass/Pass.h"
18+
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
19+
20+
using namespace mlir;
21+
22+
namespace mlir {
23+
namespace gc {
24+
#define GEN_PASS_DEF_TILELINALGNAMED
25+
#include "gc-dialects/Passes.h.inc"
26+
} // namespace gc
27+
} // namespace mlir
28+
29+
namespace {
30+
class TileLinalg : public mlir::gc::impl::TileLinalgNamedBase<TileLinalg> {
31+
32+
void runOnOperation() override {
33+
auto *ctx = &getContext();
34+
IRRewriter rewriter(ctx);
35+
36+
llvm::SmallVector<Operation *> to_tile;
37+
for (Operation &o : getOperation()->getRegion(0).front().getOperations()) {
38+
if (isa<linalg::MatmulOp>(o)) {
39+
to_tile.push_back(&o);
40+
}
41+
}
42+
43+
for (Operation *o : to_tile) {
44+
llvm::errs() << "func op body to tile: " << *o << "\n";
45+
}
46+
}
47+
};
48+
49+
} // namespace

scripts/compile.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,8 @@ get_llvm() (
2121

2222
test -f "$llvm_dir/llvm-$llvm_hash"/llvm.tgz || get_llvm
2323

24-
MLIR_DIR="$llvm_dir/lib/cmake/mlir" cmake -S . -G Ninja -B build
24+
cmake -S . -G Ninja -B build \
25+
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
26+
-DMLIR_DIR=$llvm_dir/lib/cmake/mlir \
27+
-DLLVM_EXTERNAL_LIT=$llvm_dir/bin/llvm-lit
2528
cmake --build build --parallel $(nproc)

src/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
22
get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS)
3-
set(gc_opt_libs ${dialect_libs} ${conversion_libs} MLIROptLib)
3+
4+
set(gc_opt_libs
5+
${dialect_libs}
6+
${conversion_libs}
7+
MLIROptLib
8+
GCPasses)
49
add_llvm_executable(gc-opt gc-opt.cpp)
10+
511
target_link_libraries(gc-opt PRIVATE ${gc_opt_libs})
612
llvm_update_compile_flags(gc-opt)
713
mlir_check_all_link_libraries(gc-opt)

src/gc-opt.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@
1717
* SPDX-License-Identifier: Apache-2.0
1818
*/
1919

20+
#include "gc-dialects/Passes.h"
2021
#include "mlir/InitAllDialects.h"
2122
#include "mlir/InitAllPasses.h"
2223
#include "mlir/Tools/mlir-opt/MlirOptMain.h"
2324

2425
int main(int argc, char *argv[]) {
2526
mlir::registerAllPasses();
27+
mlir::gc::registerGraphCompilerPasses();
28+
2629
mlir::DialectRegistry registry;
2730
mlir::registerAllDialects(registry);
2831
return mlir::asMainReturnCode(mlir::MlirOptMain(

test/CMakeLists.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,28 @@ add_library(graph_compiler_static STATIC ${GC_LIB_SOURCES})
1010
target_include_directories(graph_compiler_static PUBLIC ${GC_LIB_INCLUDES})
1111

1212
add_subdirectory(dnnl)
13+
14+
configure_lit_site_cfg(
15+
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
16+
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
17+
MAIN_CONFIG
18+
${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
19+
)
20+
21+
set(GC_OPT_TEST_DEPENDS
22+
FileCheck count not
23+
# mlir-gen
24+
gc-opt
25+
)
26+
27+
add_lit_testsuite(gc-check "Running the regression tests"
28+
${CMAKE_CURRENT_BINARY_DIR}
29+
DEPENDS ${GC_OPT_TEST_DEPENDS}
30+
)
31+
32+
# Looks that this property is suitable for IDE
33+
# TODO: Check is this fine for IDE
34+
set_target_properties(gc-check PROPERTIES FOLDER "Tests")
35+
36+
add_lit_testsuites(GC_OPT ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${GC_OPT_TEST_DEPENDS})
37+
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: gc-opt %s --split-input-file --linalg-generalize-named-ops | FileCheck %s
2+
3+
4+
// CHECK: #[[$MAP0:.+]] = affine_map<(d0, d1) -> (d1, d0)>
5+
// CHECK: #[[$MAP1:.+]] = affine_map<(d0, d1) -> (d0, d1)>
6+
// CHECK: #[[$MAP2:.+]] = affine_map<(d0, d1) -> ()>
7+
// CHECK: #[[$MAP3:.+]] = affine_map<(d0, d1, d2) -> (d0, d2)>
8+
// CHECK: #[[$MAP4:.+]] = affine_map<(d0, d1, d2) -> (d2, d1)>
9+
// CHECK: #[[$MAP5:.+]] = affine_map<(d0, d1, d2) -> (d0, d1)>
10+
// CHECK: #[[$MAP6:.+]] = affine_map<(d0, d1) -> (d1)>
11+
// CHECK: #[[$MAP7:.+]] = affine_map<(d0, d1) -> (0, d1)>
12+
#map = affine_map<(d0, d1) -> (d1)>
13+
#map1 = affine_map<(d0, d1) -> (0, d1)>
14+
#map2 = affine_map<(d0, d1) -> (d0, d1)>
15+
// CHECK-LABEL: mlp
16+
// CHECK-SAME: %[[ARG0:.+]]: tensor<8192x16384xf32>, %[[ARG1:.+]]: tensor<8192xf32>, %[[ARG2:.+]]: tensor<1x128x128xf32>
17+
func.func @mlp(%arg0: tensor<8192x16384xf32>, %arg1: tensor<8192xf32>, %arg2: tensor<1x128x128xf32>) -> tensor<1x8192xf32> {
18+
// CHECK: %[[CST:.+]] = arith.constant 0.000000e+00 : f32
19+
%cst = arith.constant 0.000000e+00 : f32
20+
21+
// CHECK: %[[COLLAPSE:.+]] = tensor.collapse_shape %arg2
22+
// CHECK-SAME{literal}: [[0], [1, 2]] : tensor<1x128x128xf32> into tensor<1x16384xf32>
23+
%collapsed = tensor.collapse_shape %arg2 [[0], [1, 2]] : tensor<1x128x128xf32> into tensor<1x16384xf32>
24+
25+
// CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<16384x8192xf32>
26+
%0 = tensor.empty() : tensor<16384x8192xf32>
27+
28+
// CHECK: %[[TRANSPOSED:.+]] = linalg.generic
29+
// CHECK-SAME: {indexing_maps = [#map, #map1], iterator_types = ["parallel", "parallel"]}
30+
// CHECK-SAME: ins(%arg0 : tensor<8192x16384xf32>) outs(%[[EMPTY]] : tensor<16384x8192xf32>) {
31+
// CHECK: ^bb0(%[[IN:.+]]: f32, %[[OUT:.+]]: f32):
32+
// CHECK: linalg.yield %[[IN]] : f32
33+
// CHECK: } -> tensor<16384x8192xf32>
34+
%transposed = linalg.transpose ins(%arg0 : tensor<8192x16384xf32>) outs(%0 : tensor<16384x8192xf32>) permutation = [1, 0]
35+
36+
// CHECK: %[[EMPTY:.+]] = tensor.empty() : tensor<1x8192xf32>
37+
%1 = tensor.empty() : tensor<1x8192xf32>
38+
39+
// CHECK: %[[FILLED:.+]] = linalg.generic
40+
// CHECK-SAME: {indexing_maps = [#map2, #map1], iterator_types = ["parallel", "parallel"]}
41+
// CHECK-SAME: ins(%[[CST]] : f32) outs(%[[EMPTY]] : tensor<1x8192xf32>)
42+
// CHECK: ^bb0(%[[IN:.+]]: f32, %[[OUT:.+]]: f32):
43+
// CHECK: linalg.yield %[[IN]] : f32
44+
// CHECK: } -> tensor<1x8192xf32>
45+
%2 = linalg.fill ins(%cst : f32) outs(%1 : tensor<1x8192xf32>) -> tensor<1x8192xf32>
46+
47+
// CHECK: %[[MMRESULT:.+]] = linalg.generic
48+
// CHECK-SAME: {indexing_maps = [#map3, #map4, #map5], iterator_types = ["parallel", "parallel", "reduction"]}
49+
// CHECK-SAME: ins(%[[COLLAPSE]], %[[TRANSPOSED]] : tensor<1x16384xf32>, tensor<16384x8192xf32>) outs(%[[FILLED]] : tensor<1x8192xf32>)
50+
// CHECK: ^bb0(%[[IN0:.+]]: f32, %[[IN1:.+]]: f32, %[[OUT:.+]]: f32):
51+
// CHECK: %[[MUL:.+]] = arith.mulf %[[IN0]], %[[IN1]] : f32
52+
// CHECK: %[[ADD:.+]] = arith.addf %[[OUT]], %[[MUL]] : f32
53+
// CHECK: linalg.yield %[[ADD]] : f32
54+
// CHECK: } -> tensor<1x8192xf32>
55+
%3 = linalg.matmul ins(%collapsed, %transposed : tensor<1x16384xf32>, tensor<16384x8192xf32>) outs(%2 : tensor<1x8192xf32>) -> tensor<1x8192xf32>
56+
57+
// CHECK: %[[BIAS:.+]] = linalg.generic
58+
// CHECK-SAME: {indexing_maps = [#map6, #map7, #map1], iterator_types = ["parallel", "parallel"]}
59+
// CHECK-SAME: ins(%arg1, %[[MMRESULT]] : tensor<8192xf32>, tensor<1x8192xf32>) outs(%[[EMPTY]] : tensor<1x8192xf32>) {
60+
// CHECK: ^bb0(%[[IN0:.+]]: f32, %[[IN1:.+]]: f32, %[[OUT:.+]]: f32):
61+
// CHECK: %[[ADD:.+]] = arith.addf %[[IN0]], %[[IN1]] : f32
62+
// CHECK: linalg.yield %[[ADD]] : f32
63+
// CHECK: } -> tensor<1x8192xf32>
64+
%4 = linalg.generic {indexing_maps = [#map, #map1, #map2], iterator_types = ["parallel", "parallel"]} ins(%arg1, %3 : tensor<8192xf32>, tensor<1x8192xf32>) outs(%1 : tensor<1x8192xf32>) {
65+
^bb0(%in: f32, %in_0: f32, %out: f32):
66+
%5 = arith.addf %in, %in_0 : f32
67+
linalg.yield %5 : f32
68+
} -> tensor<1x8192xf32>
69+
70+
// CHECK: return %[[BIAS]] : tensor<1x8192xf32>
71+
return %4 : tensor<1x8192xf32>
72+
}
73+
// -----

test/lit.cfg.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# -*- Python -*-
2+
3+
import os
4+
import lit.formats
5+
import lit.util
6+
7+
from lit.llvm import llvm_config
8+
9+
# from lit.llvm.subst import ToolSubst
10+
# from lit.llvm.subst import FindTool
11+
12+
# Configuration file for the 'lit' test runner.
13+
14+
# name: The name of this test suite.
15+
config.name = "GRAPH_COMPILER_OPT"
16+
17+
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
18+
19+
# suffixes: A list of file extensions to treat as test files.
20+
config.suffixes = [".mlir"]
21+
22+
# test_source_root: The root path where tests are located.
23+
config.test_source_root = os.path.dirname(__file__)
24+
25+
# test_exec_root: The root path where tests should be run.
26+
config.test_exec_root = os.path.join(config.gc_obj_root, "test")
27+
28+
config.substitutions.append(("%PATH%", config.environment["PATH"]))
29+
config.substitutions.append(("%shlibext", config.llvm_shlib_ext))
30+
config.substitutions.append(("%llvmlibdir", config.llvm_lib_dir))
31+
config.substitutions.append(("%gclibdir", config.gc_obj_root + "/lib/"))
32+
33+
llvm_config.with_system_environment(["HOME", "INCLUDE", "LIB", "TMP", "TEMP"])
34+
35+
llvm_config.use_default_substitutions()
36+
37+
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
38+
# subdirectories contain auxiliary inputs for various tests in their parent
39+
# directories.
40+
config.excludes = []
41+
42+
# test_exec_root: The root path where tests should be run.
43+
config.test_exec_root = os.path.join(config.gc_obj_root, "test")
44+
config.gc_tools_dir = os.path.join(config.gc_obj_root, "src")
45+
46+
# Tweak the PATH to include the tools dir.
47+
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)
48+
49+
tool_dirs = [config.gc_tools_dir, config.llvm_tools_dir]
50+
tools = ["gc-opt"]
51+
52+
llvm_config.add_tool_substitutions(tools, tool_dirs)

test/lit.site.cfg.py.in

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
@LIT_SITE_CFG_IN_HEADER@
2+
3+
import sys
4+
5+
config.llvm_src_root = "@LLVM_SOURCE_DIR@"
6+
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
7+
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
8+
config.llvm_lib_dir = "@LLVM_LIBS_DIR@"
9+
config.llvm_shlib_dir = "@SHLIBDIR@"
10+
config.llvm_shlib_ext = "@SHLIBEXT@"
11+
config.llvm_exe_ext = "@EXEEXT@"
12+
13+
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
14+
config.python_executable = "@PYTHON_EXECUTABLE@"
15+
config.gold_executable = "@GOLD_EXECUTABLE@"
16+
config.ld64_executable = "@LD64_EXECUTABLE@"
17+
config.enable_shared = @ENABLE_SHARED@
18+
config.enable_assertions = @ENABLE_ASSERTIONS@
19+
config.targets_to_build = "@TARGETS_TO_BUILD@"
20+
config.native_target = "@LLVM_NATIVE_ARCH@"
21+
config.llvm_bindings = "@LLVM_BINDINGS@".split(' ')
22+
config.host_os = "@HOST_OS@"
23+
config.host_cc = "@HOST_CC@"
24+
config.host_cxx = "@HOST_CXX@"
25+
# Note: ldflags can contain double-quoted paths, so must use single quotes here.
26+
config.host_ldflags = '@HOST_LDFLAGS@'
27+
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
28+
config.llvm_host_triple = '@LLVM_HOST_TRIPLE@'
29+
config.host_arch = "@HOST_ARCH@"
30+
config.gc_src_root = "@CMAKE_SOURCE_DIR@"
31+
config.gc_obj_root = "@CMAKE_BINARY_DIR@"
32+
33+
34+
import lit.llvm
35+
lit.llvm.initialize(lit_config, config)
36+
37+
# Let the main config do the real work.
38+
lit_config.load_config(config, "@CMAKE_SOURCE_DIR@/test/lit.cfg.py")

0 commit comments

Comments
 (0)