diff --git a/MLIR.cmake b/MLIR.cmake index 17b9fee..c9c5198 100644 --- a/MLIR.cmake +++ b/MLIR.cmake @@ -44,14 +44,26 @@ set( ) include_directories(${MLIR_INCLUDE_PATHS}) +# Force BUILD_SHARED_LIBS to be the same as LLVM build +file(STRINGS ${LLVM_PROJ_BUILD}/CMakeCache.txt shared REGEX BUILD_SHARED_LIBS) +string(REGEX REPLACE "BUILD_SHARED_LIBS:BOOL=" "" shared ${shared}) +set(BUILD_SHARED_LIBS ${shared} CACHE BOOL "" FORCE) +message(STATUS "BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}") + # Threading libraries required due to parallel pass execution. find_package(Threads REQUIRED) +# libcurses and libz required by libLLVMSupport +find_package(Curses REQUIRED) +find_package(ZLIB REQUIRED) function(find_mlir_lib lib) find_library(${lib} NAMES ${lib} PATHS ${LLVM_PROJECT_LIB} NO_DEFAULT_PATH) + if(${${lib}} STREQUAL ${lib}-NOTFOUND) + message(FATAL_ERROR "${lib} not found") + endif() endfunction(find_mlir_lib) find_mlir_lib(MLIRAffine) @@ -106,26 +118,15 @@ find_mlir_lib(LLVMProfileData) find_mlir_lib(LLVMDemangle) find_mlir_lib(LLVMFrontendOpenMP) - -set(MLIRLibsOnce - ${LLVMAnalysis} - ${LLVMAsmParser} - ${LLVMBinaryFormat} - ${LLVMBitReader} - ${LLVMBitstreamReader} - ${LLVMBitWriter} - ${LLVMCore} - ${LLVMFrontendOpenMP} - ${LLVMIRReader} - ${LLVMMC} - ${LLVMMCParser} - ${LLVMMLIRTableGen} - ${LLVMObject} - ${LLVMRemarks} - ${LLVMSupport} - ${LLVMTransformUtils} - ${LLVMProfileData} - ${LLVMDemangle} +set(MLIRLibs + ${MLIRLLVMIR} + ${MLIROptLib} + ${MLIRParser} + ${MLIRPass} + ${MLIRTargetLLVMIR} + ${MLIRTargetLLVMIRModuleTranslation} + ${MLIRTransforms} + ${MLIRTransformUtils} ${MLIRAffine} ${MLIRAffineToStandard} ${MLIRAnalysis} @@ -135,7 +136,6 @@ set(MLIRLibsOnce ${MLIREDSC} ${MLIRExecutionEngine} ${MLIRIR} - ${MLIRLLVMIR} ${MLIRLLVMIRTransforms} ${MLIRLoopToStandard} ${MLIRLoopOps} @@ -143,24 +143,39 @@ set(MLIRLibsOnce ${MLIRLoopLikeInterface} ${MLIROpenMP} ${MLIRMlirOptMain} - ${MLIROptLib} - ${MLIRParser} - ${MLIRPass} ${MLIRSideEffects} ${MLIRStandardOps} ${MLIRStandardToLLVM} ${MLIRSupport} - ${MLIRTargetLLVMIR} - ${MLIRTargetLLVMIRModuleTranslation} - ${MLIRTransforms} - ${MLIRTransformUtils} - ${MLIRTranslation}) - -set(MLIRLibs - ${MLIRLibsOnce} - ${MLIRLibsOnce} - Threads::Threads) + ${MLIRTranslation} + # strict order verified + ${LLVMBitWriter} + ${LLVMObject} + ${LLVMBitReader} + # strict order verified + ${LLVMFrontendOpenMP} + ${LLVMTransformUtils} + ${LLVMAnalysis} + # strict order verified + ${LLVMAsmParser} + ${LLVMCore} + # strict order not yet verified + ${LLVMRemarks} + ${LLVMMCParser} + ${LLVMMC} + ${LLVMProfileData} + ${LLVMBinaryFormat} + ${LLVMBitstreamReader} + ${LLVMIRReader} + ${LLVMMLIRTableGen} + ${LLVMSupport} + ${LLVMDemangle} + ${CMAKE_THREAD_LIBS_INIT} + ${CURSES_LIBRARIES} + ${ZLIB_LIBRARIES}) +# MLIR libraries that must be linked with --whole-archive for static build or +# must be specified on LD_PRELOAD for shared build. set(MLIRWholeArchiveLibs MLIRAffineToStandard MLIRAffine @@ -172,6 +187,20 @@ set(MLIRWholeArchiveLibs MLIRVector MLIRLoopOps) +# ONNX MLIR libraries that must be linked with --whole-archive for static build or +# must be specified on LD_PRELOAD for shared build. +set(ONNXMLIRWholeArchiveLibs + OMKrnlToAffine + OMKrnlToLLVM + OMONNXToKrnl + OMONNXRewrite + OMShapeInference + OMShapeInferenceOpInterface + OMAttributePromotion + OMPromotableConstOperandsOpInterface) + +# Function to construct linkage option for the static libraries that must be +# linked with --whole-archive (or equivalent). function(whole_archive_link target lib_dir) get_property(link_flags TARGET ${target} PROPERTY LINK_FLAGS) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") @@ -194,15 +223,39 @@ function(whole_archive_link target lib_dir) set_target_properties(${target} PROPERTIES LINK_FLAGS ${link_flags}) endfunction(whole_archive_link) +# Function to construct LD_PRELOAD value for the shared libraries whose +# static counterpart need --whole-archive linkage option. +function(ld_preload_libs target lib_dir) + foreach(lib ${ARGN}) + if("${${lib}}" STREQUAL "") + set(ONNX_MLIR_LD_PRELOAD_${target} + "${ONNX_MLIR_LD_PRELOAD_${target}}:${lib_dir}/lib${lib}.so" + CACHE STRING "" FORCE) + else() + set(ONNX_MLIR_LD_PRELOAD_${target} + "${ONNX_MLIR_LD_PRELOAD_${target}}:${${lib}}" + CACHE STRING "" FORCE) + endif() + endforeach(lib) +endfunction(ld_preload_libs) + function(whole_archive_link_mlir target) - whole_archive_link(${target} ${LLVM_PROJ_BUILD}/lib ${ARGN}) + if(BUILD_SHARED_LIBS) + ld_preload_libs(${target} ${LLVM_PROJ_BUILD}/lib ${ARGN}) + else() + whole_archive_link(${target} ${LLVM_PROJ_BUILD}/lib ${ARGN}) + endif() endfunction(whole_archive_link_mlir) function(whole_archive_link_onnx_mlir target) foreach(lib_target ${ARGN}) add_dependencies(${target} ${lib_target}) endforeach(lib_target) - whole_archive_link(${target} ${CMAKE_BINARY_DIR}/lib ${ARGN}) + if(BUILD_SHARED_LIBS) + ld_preload_libs(${target} ${CMAKE_BINARY_DIR}/lib ${ARGN}) + else() + whole_archive_link(${target} ${CMAKE_BINARY_DIR}/lib ${ARGN}) + endif() endfunction(whole_archive_link_onnx_mlir) set(LLVM_CMAKE_DIR diff --git a/src/Builder/CMakeLists.txt b/src/Builder/CMakeLists.txt index a85c00e..3e331a1 100644 --- a/src/Builder/CMakeLists.txt +++ b/src/Builder/CMakeLists.txt @@ -8,14 +8,19 @@ target_include_directories(OMBuilder PRIVATE ${ONNX_MLIR_SRC_ROOT}) target_include_directories(OMBuilder PRIVATE ${CMAKE_BINARY_DIR}) target_include_directories(OMBuilder PRIVATE ${ONNX_MLIR_BIN_ROOT}) +# This will cause onnx to be built. More importantly, some variable definitions +# when building onnx such as -DONNX_ML=1 -DONNX_NAMESPACE=onnx will be carried over +# when compiling FrontendDialectHelper.cpp, etc. target_link_libraries(OMBuilder - OMONNXOps onnx - ${MLIRLibs} - curses mpark_variant) target_include_directories(OMBuilder PUBLIC ${ONNX_MLIR_SRC_ROOT}/third_party/onnx ${ONNX_MLIR_SRC_ROOT}/third_party/variant ${ONNX_MLIR_SRC_ROOT}) +# If you add onnx here, it will also cause onnx to be built. However, some +# variable definitions when building onnx such as -DONNX_ML=1 -DONNX_NAMESPACE=onnx +# will NOT be carried over when compiling FrontendDialectHelper.cpp, etc. so +# the compilation will fail. +add_dependencies(OMBuilder OMONNXOps) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f05d078..37206c2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,24 +10,36 @@ add_executable(onnx-mlir MainUtils.hpp MainUtils.cpp main.cpp) + +set(ONNX_MLIR_LD_PRELOAD_onnx-mlir "" CACHE STRING "" FORCE) +whole_archive_link_mlir(onnx-mlir ${MLIRWholeArchiveLibs}) +if(BUILD_SHARED_LIBS) + message(STATUS "To run dynamically linked onnx-mlir, you must specify:") + message(STATUS "LD_PRELOAD=${ONNX_MLIR_LD_PRELOAD_onnx-mlir}") +endif() + +# Libraries specified on the target_link_libraries for the add_subdirectory +# targets get added to the end of the list here. This creates two problems: +# 1. It produces duplicated libraries being specified for the link command. +# 2. The libraries added at the end may depend on other libraries thus +# cause linkage errors due to undefined symbols. +# So it's better not to use target_link_libraries for the add_subdirectory +# targets, or only use it for libraries that have no further dependencies +# (except system libraries such as libc). target_link_libraries(onnx-mlir - ${MLIRLibs} OMBuilder OMKrnlOps OMONNXOps + OMShapeInference + OMShapeInferenceOpInterface + OMAttributePromotion + OMPromotableConstOperandsOpInterface OMKrnlToAffine OMKrnlToLLVM - OMShapeInference OMONNXToKrnl OMONNXRewrite - OMAttributePromotion - ${CMAKE_THREAD_LIBS_INIT} + ${MLIRLibs} ${CMAKE_DL_LIBS}) -whole_archive_link_mlir(onnx-mlir - ${MLIRWholeArchiveLibs}) - -find_package(ZLIB REQUIRED) -target_link_libraries(onnx-mlir ${ZLIB_LIBRARIES}) target_include_directories(onnx-mlir PRIVATE ${ONNX_MLIR_SRC_ROOT}) target_include_directories(onnx-mlir PRIVATE ${CMAKE_BINARY_DIR}) diff --git a/src/Conversion/ONNXToKrnl/CMakeLists.txt b/src/Conversion/ONNXToKrnl/CMakeLists.txt index f75cf28..5d4cbe9 100644 --- a/src/Conversion/ONNXToKrnl/CMakeLists.txt +++ b/src/Conversion/ONNXToKrnl/CMakeLists.txt @@ -22,6 +22,7 @@ target_include_directories(OMONNXToKrnl ${ONNX_MLIR_SRC_ROOT} ${ONNX_MLIR_BIN_ROOT} ${ONNX_MLIR_SRC_ROOT}) -target_link_libraries(OMONNXToKrnl - ${MLIRLibs} + +# Linking dependencies: +add_dependencies(OMONNXToKrnl OMKrnlOps) diff --git a/src/Dialect/ONNX/CMakeLists.txt b/src/Dialect/ONNX/CMakeLists.txt index 2d25210..4f26c0c 100644 --- a/src/Dialect/ONNX/CMakeLists.txt +++ b/src/Dialect/ONNX/CMakeLists.txt @@ -13,7 +13,8 @@ target_include_directories(OMONNXOps ${ONNX_MLIR_BIN_ROOT} ${ONNX_MLIR_SRC_ROOT}) add_dependencies(OMONNXOps OMONNXOpsIncGen) -target_link_libraries(OMONNXOps +# Linking dependencies: +add_dependencies(OMONNXOps OMPromotableConstOperandsOpInterface OMShapeInferenceOpInterface) diff --git a/src/Tool/ONNXMLIROpt/CMakeLists.txt b/src/Tool/ONNXMLIROpt/CMakeLists.txt index 30e6624..d135c21 100644 --- a/src/Tool/ONNXMLIROpt/CMakeLists.txt +++ b/src/Tool/ONNXMLIROpt/CMakeLists.txt @@ -4,22 +4,17 @@ add_dependencies(onnx-mlir-opt OMKrnlOpsIncGen) target_include_directories(onnx-mlir-opt PRIVATE ${ONNX_MLIR_SRC_ROOT}) target_include_directories(onnx-mlir-opt PRIVATE ${ONNX_MLIR_BIN_ROOT}) +set(ONNX_MLIR_LD_PRELOAD_onnx-mlir-opt "" CACHE STRING "" FORCE) +whole_archive_link_onnx_mlir(onnx-mlir-opt ${ONNXMLIRWholeArchiveLibs}) +whole_archive_link_mlir(onnx-mlir-opt ${MLIRWholeArchiveLibs}) +if(BUILD_SHARED_LIBS) + message(STATUS "To run dynamically linked onnx-mlir-opt, you must specify:") + message(STATUS "LD_PRELOAD=${ONNX_MLIR_LD_PRELOAD_onnx-mlir-opt}") +endif() + target_link_libraries(onnx-mlir-opt - ${MLIRLibs} OMBuilder OMKrnlOps - OMKrnlToAffine - OMKrnlToLLVM - OMShapeInference - OMONNXToKrnl - OMPromotableConstOperandsOpInterface - curses) -whole_archive_link_mlir(onnx-mlir-opt - ${MLIRWholeArchiveLibs}) -whole_archive_link_onnx_mlir(onnx-mlir-opt - OMKrnlToAffine - OMKrnlToLLVM - OMONNXToKrnl + OMONNXOps OMONNXRewrite - OMShapeInference - OMAttributePromotion) \ No newline at end of file + ${MLIRLibs}) diff --git a/src/Transform/CMakeLists.txt b/src/Transform/CMakeLists.txt index 728839d..8231004 100644 --- a/src/Transform/CMakeLists.txt +++ b/src/Transform/CMakeLists.txt @@ -5,8 +5,9 @@ target_include_directories(OMKrnlToAffine ${ONNX_MLIR_SRC_ROOT} ${ONNX_MLIR_BIN_ROOT} ${ONNX_MLIR_SRC_ROOT}) -target_link_libraries(OMKrnlToAffine - ${MLIRLibs} + +# Linking dependencies: +add_dependencies(OMKrnlToAffine OMKrnlOps OMONNXOps) @@ -17,9 +18,10 @@ target_include_directories(OMKrnlToLLVM ${ONNX_MLIR_SRC_ROOT} ${ONNX_MLIR_BIN_ROOT} ${ONNX_MLIR_SRC_ROOT}) -target_link_libraries(OMKrnlToLLVM - ${MLIRLibs} + +#Linking dependencies: +add_dependencies(OMKrnlToLLVM OMKrnlOps OMONNXOps) -add_subdirectory(ONNX) \ No newline at end of file +add_subdirectory(ONNX) diff --git a/src/Transform/ONNX/CMakeLists.txt b/src/Transform/ONNX/CMakeLists.txt index 7dce830..78ab2f7 100644 --- a/src/Transform/ONNX/CMakeLists.txt +++ b/src/Transform/ONNX/CMakeLists.txt @@ -3,7 +3,9 @@ add_library(OMAttributePromotion target_include_directories(OMAttributePromotion PRIVATE ${ONNX_MLIR_SRC_ROOT} ${ONNX_MLIR_BIN_ROOT} ${ONNF_MLIR_SRC_ROOT}) -target_link_libraries(OMAttributePromotion + +# Linking dependencies: +add_dependencies(OMAttributePromotion OMPromotableConstOperandsOpInterface) set(LLVM_TARGET_DEFINITIONS ONNXRewrite.td) @@ -25,18 +27,19 @@ add_library(OMONNXRewrite target_include_directories(OMONNXRewrite PRIVATE ${ONNX_MLIR_SRC_ROOT} ${ONNX_MLIR_BIN_ROOT} ${ONNF_MLIR_SRC_ROOT}) -target_link_libraries(OMONNXRewrite - OMONNXOps) add_dependencies(OMONNXRewrite OMONNXRewriteIncGen OMONNXDecomposeIncGen OMONNXCombineIncGen) +# Linking dependencies: +add_dependencies(OMONNXRewrite + OMONNXOps) add_library(OMShapeInference ShapeInferencePass.cpp) target_include_directories(OMShapeInference PRIVATE ${ONNX_MLIR_SRC_ROOT} ${ONNX_MLIR_BIN_ROOT} ${ONNX_MLIR_SRC_ROOT}) -target_link_libraries(OMShapeInference - ${MLIRLibs} +add_dependencies(OMShapeInference ShapeInferenceOpInterfaceIncGen) +# Linking dependencies: +add_dependencies(OMShapeInference OMShapeInferenceOpInterface) -add_dependencies(OMShapeInference ShapeInferenceOpInterfaceIncGen) \ No newline at end of file diff --git a/test/mlir/lit.site.cfg.py.in b/test/mlir/lit.site.cfg.py.in index 652f8e3..d81581c 100644 --- a/test/mlir/lit.site.cfg.py.in +++ b/test/mlir/lit.site.cfg.py.in @@ -1,6 +1,9 @@ import lit.llvm +if '@BUILD_SHARED_LIBS@' == 'ON': + config.environment['LD_PRELOAD'] = "@ONNX_MLIR_LD_PRELOAD_onnx-mlir-opt@" + config.llvm_tools_dir = "@MLIR_TOOLS_DIR@" config.mlir_obj_root = "@LLVM_PROJ_BUILD@" config.mlir_tools_dir = "@MLIR_TOOLS_DIR@" @@ -13,4 +16,4 @@ config.onnx_mlir_test_build_dir = "@ONNX_MLIR_LIT_TEST_BUILD_DIR@" lit.llvm.initialize(lit_config, config) # Let the main config do the real work. -lit_config.load_config(config, "@ONNX_MLIR_LIT_TEST_SRC_DIR@/lit.cfg.py") \ No newline at end of file +lit_config.load_config(config, "@ONNX_MLIR_LIT_TEST_SRC_DIR@/lit.cfg.py")