diff --git a/CMakeLists.txt b/CMakeLists.txt index 46ccd32..53b79bd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,9 @@ if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) endif() +include(MLIR.cmake) + add_subdirectory(src/builder) +add_subdirectory(src/compiler) add_subdirectory(src) diff --git a/MLIR.cmake b/MLIR.cmake new file mode 100644 index 0000000..ca7f413 --- /dev/null +++ b/MLIR.cmake @@ -0,0 +1,107 @@ +# Flags to link with LLVM/MLIR libraries +if(DEFINED ENV{LLVM_PROJECT_ROOT}) + set(LLVM_PROJECT_ROOT $ENV{LLVM_PROJECT_ROOT}) + if(EXISTS ${LLVM_PROJECT_ROOT}) + message(STATUS "LLVM_PROJECT_ROOT " ${LLVM_PROJECT_ROOT}) + else() + message( + FATAL_ERROR "The path specified by LLVM_PROJECT_ROOT does not exist: " + ${LLVM_PROJECT_ROOT}) + endif() +else() + message(FATAL_ERROR "env variable LLVM_PROJECT_ROOT not set") +endif() + +if(DEFINED ENV{LLVM_PROJECT_LIB}) + set(LLVM_PROJECT_LIB $ENV{LLVM_PROJECT_LIB}) +else() + set(LLVM_PROJECT_LIB $ENV{LLVM_PROJECT_ROOT}/build/lib) +endif() +if(EXISTS ${LLVM_PROJECT_LIB}) + message(STATUS "LLVM_PROJECT_LIB " ${LLVM_PROJECT_LIB}) +else() + message(FATAL_ERROR "The path specified by LLVM_PROJECT_LIB does not exist: " + ${LLVM_PROJECT_LIB}) +endif() + +# include path +set(LLVM_SRC_INCLUDE_PATH ${LLVM_PROJECT_ROOT}/llvm/include) +set(LLVM_BIN_INCLUDE_PATH ${LLVM_PROJECT_ROOT}/build/include) +set(MLIR_SRC_INCLUDE_PATH ${LLVM_PROJECT_ROOT}/llvm/projects/mlir/include) +set(MLIR_BIN_INCLUDE_PATH ${LLVM_PROJECT_ROOT}/build/projects/mlir/include) + +set(MLIR_INCLUDE_PATHS + ${LLVM_SRC_INCLUDE_PATH};${LLVM_BIN_INCLUDE_PATH};${MLIR_SRC_INCLUDE_PATH};${MLIR_BIN_INCLUDE_PATH}) +include_directories(${MLIR_INCLUDE_PATHS}) + +find_library(MLIRLIBANALYSIS + NAMES MLIRAnalysis + PATHS ${LLVM_PROJECT_LIB} + NO_DEFAULT_PATH) + +find_library(MLIRLIBIR NAMES MLIRIR PATHS ${LLVM_PROJECT_LIB} NO_DEFAULT_PATH) + +find_library(MLIRLIBPARSER + NAMES MLIRParser + PATHS ${LLVM_PROJECT_LIB} + NO_DEFAULT_PATH) + +find_library(MLIRLIBTRANSFORMS + NAMES MLIRTransforms + PATHS ${LLVM_PROJECT_LIB} + NO_DEFAULT_PATH) + +find_library(MLIRLIBVECTOROPS + NAMES MLIRVectorOps + PATHS ${LLVM_PROJECT_LIB} + NO_DEFAULT_PATH) + +find_library(MLIRLIBSUPPORT + NAMES MLIRSupport + PATHS ${LLVM_PROJECT_LIB} + NO_DEFAULT_PATH) + +find_library(MLIRLIBSTANDARDOPS + NAMES MLIRStandardOps + PATHS ${LLVM_PROJECT_LIB} + NO_DEFAULT_PATH) + +find_library(LLVMLIBSUPPORT + NAMES LLVMSupport + PATHS ${LLVM_PROJECT_LIB} + NO_DEFAULT_PATH) + +# libraries are set according to toy/Ch2 +set(MLIRLIBS + ${MLIRLIBANALYSIS} + ${MLIRLIBIR} + ${MLIRLIBPARSER} + ${MLIRLIBTRANSFORMS} + ${MLIRLIBANALYSIS} + ${MLIRLIBVECTOROPS} + ${MLIRLIBIR} + ${MLIRLIBSUPPORT} + ${MLIRLIBSTANDARDOPS} + ${LLVMLIBSUPPORT}) + +# Set up TableGen environment. +include(${LLVM_PROJECT_ROOT}/build/lib/cmake/llvm/TableGen.cmake) + +function(onnf_tablegen ofn) + tablegen(MLIR + ${ARGV} + "-I${MLIR_SRC_INCLUDE_PATH}" + "-I${MLIR_BIN_INCLUDE_PATH}") + set(TABLEGEN_OUTPUT + ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn} + PARENT_SCOPE) +endfunction() + +# Import the pre-built mlir TableGen as an imported exetuable. It is required by +# the LLVM TableGen command to have the TableGen target so that changes to the +# table gen utility itself can be detected and cause re-compilation of .td file. +add_executable(mlir-tblgen IMPORTED) +set_property(TARGET mlir-tblgen + PROPERTY IMPORTED_LOCATION + ${LLVM_PROJECT_ROOT}/build/bin/mlir-tblgen) +set(MLIR_TABLEGEN_EXE mlir-tblgen) diff --git a/src/builder/CMakeLists.txt b/src/builder/CMakeLists.txt index 31756ae..8627ae1 100644 --- a/src/builder/CMakeLists.txt +++ b/src/builder/CMakeLists.txt @@ -1,84 +1,7 @@ -add_definitions(-DBOOST_LOG_DYN_LINK) - add_library(builder sgir.cpp ) -#Flags to link with LLVM/MLIR libraries -if(DEFINED ENV{LLVM_PROJECT_ROOT}) - set(LLVM_PROJECT_ROOT $ENV{LLVM_PROJECT_ROOT}) - if (EXISTS ${LLVM_PROJECT_ROOT}) - message(STATUS "LLVM_PROJECT_ROOT " ${LLVM_PROJECT_ROOT}) - else() - message(FATAL_ERROR "The path specified by LLVM_PROJECT_ROOT does not exist: " ${LLVM_PROJECT_ROOT}) - endif() -else() - message(FATAL_ERROR "env variable LLVM_PROJECT_ROOT not set") -endif() - -if(DEFINED ENV{LLVM_PROJECT_LIB}) - set(LLVM_PROJECT_LIB $ENV{LLVM_PROJECT_LIB}) -else() - set(LLVM_PROJECT_LIB $ENV{LLVM_PROJECT_ROOT}/build/lib) -endif() -if (EXISTS ${LLVM_PROJECT_LIB}) - message(STATUS "LLVM_PROJECT_LIB " ${LLVM_PROJECT_LIB}) -else() - message(FATAL_ERROR "The path specified by LLVM_PROJECT_LIB does not exist: " ${LLVM_PROJECT_LIB}) -endif() - -#include path -include_directories(${LLVM_PROJECT_ROOT}/llvm/projects/mlir/include) -include_directories(${LLVM_PROJECT_ROOT}/llvm/include) -include_directories(${LLVM_PROJECT_ROOT}/build/include) -include_directories(${LLVM_PROJECT_ROOT}/build/projects/mlir/include) - -find_library(MLIRLIBANALYSIS - NAMES MLIRAnalysis - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -find_library(MLIRLIBIR - NAMES MLIRIR - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -find_library(MLIRLIBPARSER - NAMES MLIRParser - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -find_library(MLIRLIBTRANSFORMS - NAMES MLIRTransforms - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -find_library(MLIRLIBVECTOROPS - NAMES MLIRVectorOps - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -find_library(MLIRLIBSUPPORT - NAMES MLIRSupport - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -find_library(MLIRLIBSTANDARDOPS - NAMES MLIRStandardOps - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -find_library(LLVMLIBSUPPORT - NAMES LLVMSupport - PATHS ${LLVM_PROJECT_LIB} - NO_DEFAULT_PATH) - -#libraries are set according to toy/Ch2 -set(MLIRLIBS ${MLIRLIBANALYSIS} ${MLIRLIBIR} ${MLIRLIBPARSER} ${MLIRLIBTRANSFORMS} - ${MLIRLIBANALYSIS} ${MLIRLIBVECTOROPS} ${MLIRLIBIR} ${MLIRLIBSUPPORT} ${MLIRLIBSTANDARDOPS} - ${LLVMLIBSUPPORT}) - - target_link_libraries(builder onnx ${MLIRLIBS} curses) target_include_directories(builder PRIVATE diff --git a/src/builder/sgir.cpp b/src/builder/sgir.cpp index d6352f7..64eb0ef 100644 --- a/src/builder/sgir.cpp +++ b/src/builder/sgir.cpp @@ -157,7 +157,7 @@ class SGIRGenImpl { result.addOperands(inputs); auto op = builder_.createOperation(result); for (int i = 0; i < node.output().size(); i++) { - auto r = builder_.createOperation(result)->getResult(i); + auto r = op->getResult(i); sgir_symbols_.AddMapping(legalize_name(node.output()[i]), r); } @@ -212,14 +212,10 @@ class SGIRGenImpl { }; // SGIRGenImpl class } // namespace -} // namespace dlc +} // namespace onnf namespace onnf { -/*! - * Generate SGIR with MLIR for a onnx model - * @param model onnx model. - * @return module mlir module generated for the onnx model - */ + mlir::OwningModuleRef SGIRImportModel(onnx::ModelProto model) { mlir::MLIRContext context; SGIRGenImpl mySGIRGen(context); @@ -229,4 +225,11 @@ mlir::OwningModuleRef SGIRImportModel(onnx::ModelProto model) { return module; } +mlir::OwningModuleRef SGIRImportModelFile(std::string model_fname) { + onnx::ModelProto model; + std::fstream input(model_fname, std::ios::in | std::ios::binary); + + auto parse_success = model.ParseFromIstream(&input); + return SGIRImportModel(model); +} } // namespace onnf diff --git a/src/builder/sgir.hpp b/src/builder/sgir.hpp index a6f3f08..382b3d2 100644 --- a/src/builder/sgir.hpp +++ b/src/builder/sgir.hpp @@ -25,10 +25,16 @@ class OwningModuleRef; namespace onnf { /*! - * Import an ONNX Model into SGIR + * Import an ONNX Model into SGIR. * @param model onnx model. - * @return MLIR::module generated for the ONNX model + * @return MLIR::module generated for the ONNX model. */ mlir::OwningModuleRef SGIRImportModel(onnx::ModelProto model); +/*! + * Import an ONNX Model file into SGIR. + * @param model_fname file name pointing to the onnx model protobuf. + * @return MLIR::module generated for the ONNX model. + */ +mlir::OwningModuleRef SGIRImportModelFile(std::string model_fname); } // namespace onnf diff --git a/src/compiler/CMakeLists.txt b/src/compiler/CMakeLists.txt new file mode 100644 index 0000000..2ab4e9b --- /dev/null +++ b/src/compiler/CMakeLists.txt @@ -0,0 +1,28 @@ +add_library( + compiler + ir/knl/knl_ops.cpp + ir/knl/knl_ops.hpp) + +# Include root src directory. +target_include_directories(compiler PRIVATE ../..) +target_include_directories(compiler PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + +find_package(Boost 1.54.0 + COMPONENTS graph + program_options + log_setup + log + system + filesystem + REQUIRED) + +# target_link_libraries(compiler isl inja ${Boost_LIBRARIES}) +target_link_libraries(compiler + ${Boost_LIBRARIES} + ) + +set(LLVM_TARGET_DEFINITIONS ir/knl/knl.td) +onnf_tablegen(knl.hpp.inc -gen-op-decls) +onnf_tablegen(knl.cpp.inc -gen-op-defs) +add_public_tablegen_target(gen_kir) +add_dependencies(compiler gen_kir) diff --git a/src/compiler/ir/knl/knl.td b/src/compiler/ir/knl/knl.td new file mode 100644 index 0000000..9ff4758 --- /dev/null +++ b/src/compiler/ir/knl/knl.td @@ -0,0 +1,27 @@ +include "mlir/IR/OpBase.td" + +def Knl_Dialect : Dialect { + let name = "knl"; + let cppNamespace = ""; +} + +def KnlIterate : Op { + let summary = "iterate operation"; + let description = [{ + + The "knl.iterate" operation is conceptually equivalent to a nested for loop + in that it represents ordered interation of integer coordinates within an + affine integer set. + + }]; + + let arguments = (ins Variadic); + let regions = (region SizedRegion<1>:$region); + + let skipDefaultBuilders = 1; + + let builders = [ + OpBuilder<"Builder *builder, OperationState &result, " + "IntegerSet set, ArrayRef args"> + ]; +} \ No newline at end of file diff --git a/src/compiler/ir/knl/knl_ops.cpp b/src/compiler/ir/knl/knl_ops.cpp new file mode 100644 index 0000000..1d865c8 --- /dev/null +++ b/src/compiler/ir/knl/knl_ops.cpp @@ -0,0 +1,23 @@ +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallBitVector.h" +#include "mlir/IR/Block.h" +#include "mlir/IR/Builders.h" +#include "mlir/IR/Function.h" +#include "mlir/IR/IntegerSet.h" +#include "mlir/IR/Matchers.h" +#include "mlir/IR/OpImplementation.h" +#include "mlir/IR/PatternMatch.h" + +#include "knl_ops.hpp" + +namespace mlir { +KnlOpsDialect::KnlOpsDialect(MLIRContext* context) + : Dialect(getDialectNamespace(), context) { + addOperations< +#define GET_OP_LIST +#include "knl.cpp.inc" + >(); +} +} // namespace mlir + +namespace onnf {} diff --git a/src/compiler/ir/knl/knl_ops.hpp b/src/compiler/ir/knl/knl_ops.hpp new file mode 100644 index 0000000..6ec7a86 --- /dev/null +++ b/src/compiler/ir/knl/knl_ops.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "mlir/IR/Builders.h" +#include "mlir/IR/Dialect.h" +#include "mlir/IR/OpDefinition.h" +#include "mlir/IR/StandardTypes.h" + +namespace mlir { +class KnlOpsDialect : public Dialect { + public: + KnlOpsDialect(MLIRContext* context); + static StringRef getDialectNamespace() { return "knl"; } +}; + +#define GET_OP_CLASSES +#include "knl.hpp.inc" +} // namespace mlir + +namespace onnf {} diff --git a/src/main.cpp b/src/main.cpp index 764d012..7e22aea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,10 @@ #include +#include "src/builder/sgir.hpp" + +#include "mlir/IR/Module.h" + using namespace std; int main(int ac, char* av[]) { @@ -40,5 +44,8 @@ int main(int ac, char* av[]) { return 0; } + string model_filename = vm["onnx-model"].as(); + auto module = SGIRImportModelFile(model_filename); + return 0; }