Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the project compatible with FetchContent and find_package #200

Merged
merged 4 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 88 additions & 76 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,99 +18,111 @@
cmake_minimum_required(VERSION 3.20)
project(GraphCompiler VERSION "0.1.0" LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
############################# Cmake options ####################################
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# Silence a false positive GCC -Wunused-but-set-parameter warning in constexpr
# cases, by marking SelectedCase as used. See
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85827 for details. The issue is
# fixed in GCC 10.
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0")
check_cxx_compiler_flag("-Wno-unused-but-set-parameter" CXX_SUPPORTS_WNO_UNUSED_BUT_SET_PARAMETER)
append_if(CXX_SUPPORTS_WNO_UNUSED_BUT_SET_PARAMETER "-Wno-unused-but-set-parameter" CMAKE_CXX_FLAGS)
endif()
################################################################################

option(GC_LEGACY_ENABLE ON)
option(GC_TEST_ENABLE "Build the tests" ON)
option(GC_USE_GPU "Enable GPU backend" OFF)
############################ Build options #####################################
option(GC_ENABLE_LEGACY ON)
option(GC_ENABLE_DNNL "Enable the oneDNN library integration" ON)
option(GC_ENABLE_TEST "Build the tests" ON)
option(GC_ENABLE_TEST_DNNL "Build the dnnl tests" ${GC_ENABLE_DNNL})
option(GC_ENABLE_TEST_MLIR "Build the mlir tests" ON)
option(GC_ENABLE_TOOLS "Build the tools" ON)
option(GC_ENABLE_OPT "Build gc-opt" ${GC_ENABLE_TOOLS})
option(GC_ENABLE_IMEX "Enable Intel® Extension for MLIR" OFF)
option(GC_ENABLE_BINDINGS_PYTHON "Enable Graph Complier Python Binding" ON)
option(GC_DEV_LINK_LLVM_DYLIB "Link dynamic libraries of LLVM and MLIR. For developers only. Do not use it in packing the library." OFF)

if(GC_LEGACY_ENABLE)
add_subdirectory(legacy/core)
endif()

find_package(MLIR REQUIRED CONFIG)

message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR})

list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")

include(TableGen)
include(AddLLVM)
include(AddMLIR)
include(HandleLLVMOptions)

if(GC_USE_GPU)
include(imex)
if(GC_DEV_LINK_LLVM_DYLIB)
message(WARN "GPU backend may not be compatible with dynamic linking to LLVM")
endif()
endif()

if(GC_ENABLE_BINDINGS_PYTHON AND NOT MLIR_ENABLE_BINDINGS_PYTHON)
message(STATUS "Failed to enable Python API due to the 'MLIR_ENABLE_BINDINGS_PYTHON' for LLVM is not ON.")
set(GC_ENABLE_BINDINGS_PYTHON OFF CACHE BOOL "" FORCE)
if(GC_ENABLE_LEGACY)
add_subdirectory(legacy/core)
endif()

if(GC_ENABLE_BINDINGS_PYTHON)
include(MLIRDetectPythonEnv)
mlir_configure_python_dev_packages()
if(GC_ENABLE_DNNL)
set(GC_ONEDNN_DIALECT_LIB_NAME MLIROneDNNGraph)
endif()
################################################################################

include_directories(
${LLVM_INCLUDE_DIRS}
${MLIR_INCLUDE_DIRS}
${PROJECT_BINARY_DIR}/include
${PROJECT_SOURCE_DIR}/include
############################## Targets #########################################
# All common options, includes etc. are added to this interface target.
add_library(GcInterface INTERFACE)
target_compile_features(GcInterface INTERFACE cxx_std_17)
target_include_directories(GcInterface INTERFACE
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)

# The paths are added in the subfolders using the gc_add_path() function.
# These lists are also used by tests.
set(GC_LIB_SOURCES CACHE INTERNAL "The graph_compiler library source paths")
set(GC_LIB_INCLUDES CACHE INTERNAL "The graph_compiler library include paths")

add_definitions(${LLVM_DEFINITIONS})

set(GC_MLIR_CXX_FLAGS "")
# Silence a false positive GCC -Wunused-but-set-parameter warning in constexpr
# cases, by marking SelectedCase as used. See
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85827 for details. The issue is
# fixed in GCC 10.
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.0")
check_cxx_compiler_flag("-Wno-unused-but-set-parameter" CXX_SUPPORTS_WNO_UNUSED_BUT_SET_PARAMETER)
append_if(CXX_SUPPORTS_WNO_UNUSED_BUT_SET_PARAMETER "-Wno-unused-but-set-parameter" GC_MLIR_CXX_FLAGS)
endif()
include("cmake/version.cmake")
include(functions)
include(version)
include(mlir)

add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(src)
if(GC_ENABLE_BINDINGS_PYTHON)
message(STATUS "Enabling Python API")
add_subdirectory(python)
endif()
add_subdirectory(python)
add_subdirectory(test)
################################################################################

set(GC_LIB_LINKED_LIBS
GCJitWrapper
GCCpuRuntime
############################### Install ########################################
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ TYPE INCLUDE)
install(DIRECTORY ${PROJECT_BINARY_DIR}/include/ TYPE INCLUDE
REGEX "CMake.*|.*cmake" EXCLUDE)

# Export the targets
get_property(GC_TOOLS GLOBAL PROPERTY GC_TOOLS)
get_property(GC_MLIR_LIBS GLOBAL PROPERTY GC_MLIR_LIBS)
get_property(GC_PASS_LIBS GLOBAL PROPERTY GC_PASS_LIBS)
get_property(GC_DIALECT_LIBS GLOBAL PROPERTY GC_DIALECT_LIBS)
install(TARGETS
GcInterface
${GC_TOOLS}
${GC_MLIR_LIBS}
${GC_PASS_LIBS}
${GC_DIALECT_LIBS}
EXPORT ${PROJECT_NAME}Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
export(EXPORT ${PROJECT_NAME}Targets
FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake"
)
install(EXPORT ${PROJECT_NAME}Targets
FILE ${PROJECT_NAME}Targets.cmake
DESTINATION lib/cmake/${PROJECT_NAME}
)
add_mlir_library(graph_compiler SHARED ${GC_LIB_SOURCES})
target_include_directories(graph_compiler PUBLIC ${GC_LIB_INCLUDES})
target_compile_options(graph_compiler PRIVATE -fvisibility=hidden -fexceptions)
target_link_options(graph_compiler PRIVATE -Wl,--gc-sections)
target_link_libraries(graph_compiler PRIVATE ${GC_LIB_LINKED_LIBS})

add_subdirectory(test)
# Generate the config files
include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
COMPATIBILITY AnyNewerVersion
)
install(FILES
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION "lib/cmake/${PROJECT_NAME}"
)
################################################################################
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ cmake --build build --target install

Notes
* It is recommended to add optional options `-DLLVM_BUILD_LLVM_DYLIB=ON -DLLVM_LINK_LLVM_DYLIB=ON` to the command `cmake -G Ninja llvm ...` above **if you are building for CPU only**. These will enable the build of LLVM/MLIR dynamic libraries and let MLIR/LLVM tools link to them, to reduce the installed binary size of LLVM/MLIR. These options also enable the `GC_DEV_LINK_LLVM_DYLIB` option of graph-compiler repo (see below).
* The option `-DLLVM_INSTALL_GTEST=ON` is optional, if the tests of graph-compiler are disabled (see `GC_TEST_ENABLE` below).
* The option `-DLLVM_INSTALL_GTEST=ON` is optional, if the tests of graph-compiler are disabled (see `GC_ENABLE_TEST` below).
* If you would like to enable GPU components of Graph Compiler, please make sure to statically link Graph Compiler and LLVM(MLIR). It is a known issue that LLVM shared library cannot be linked together with IGC (Intel's low level GPU compiler). Make sure `LLVM_BUILD_LLVM_DYLIB` and `LLVM_LINK_LLVM_DYLIB` are `OFF` (they are off by default). Also make sure Graph Compiler's cmake option `GC_DEV_LINK_LLVM_DYLIB` is `OFF` when configuring Graph Compiler (see below).

We have now installed LLVM at `llvm-project/llvm-install`.
Expand All @@ -59,7 +59,7 @@ Notes:
* `/PATH/TO/llvm-project/llvm-install` should be the install path of LLVM. If you installed LLVM elsewhere by `-DCMAKE_INSTALL_PREFIX` option when building LLVM, you need to change the path in `-DMLIR_DIR` accordingly.
* The cmake option `-DLLVM_EXTERNAL_LIT` is for the tests of this project. It requires the `lit` tool to be installed in the system. You can install it via `pip install lit`. If you don't need to run the tests of this repo, you can omit this option in the command line.

More notes if GPU components are on (`-DGC_USE_GPU=ON`):
More notes if Intel® Extension for MLIR is on (`-DGC_ENABLE_IMEX=ON`):
* make sure the OpenCL runtime is installed in your system. You can either
install using OS-provided package (Ubuntu 22.04)
```sh
Expand All @@ -70,11 +70,11 @@ sudo apt install -y intel-opencl-icd opencl-c-headers

Graph Compiler supports the following build-time options.

| CMake Option | Supported values (defaults in bold) | Description |
|:--------------------------------|:---------------------------------------|:---------------------------------------------------------------------------------------|
| GC_LEGACY_ENABLE | **ON**, OFF | Controls building the legacy graph-compiler component |
| GC_TEST_ENABLE | **ON**, OFF | Controls building the tests |
| GC_DEV_LINK_LLVM_DYLIB | ON, **OFF** | Controls dynamic link LLVM/MLIR libraries, mainly for developer |
| GC_ENABLE_BINDINGS_PYTHON | **ON**, OFF | Controls building the Python API |
| GC_USE_GPU | ON, **OFF** | Whether to enable the GPU components |
| CMake Option | Supported values (defaults in bold) | Description |
|:--------------------------|:---------------------------------------|:----------------------------------------------------------------|
| GC_ENABLE_LEGACY | **ON**, OFF | Controls building the legacy graph-compiler component |
| GC_ENABLE_TEST | **ON**, OFF | Controls building the tests |
| GC_DEV_LINK_LLVM_DYLIB | ON, **OFF** | Controls dynamic link LLVM/MLIR libraries, mainly for developer |
| GC_ENABLE_BINDINGS_PYTHON | **ON**, OFF | Controls building the Python API |
| GC_ENABLE_IMEX | ON, **OFF** | Whether to enable the GPU components |

10 changes: 10 additions & 0 deletions cmake/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@PACKAGE_INIT@

include ("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")

find_package(MLIR REQUIRED CONFIG)

include_directories(
${LLVM_INCLUDE_DIRS}
${MLIR_INCLUDE_DIRS}
)
66 changes: 38 additions & 28 deletions cmake/functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,25 @@ function(gc_fetch_content
# Optional arguments:
# SKIP_ADD: Populate but do not add the content to the project.
# SKIP_FIND: Do not use find_package().
# CMAKE_ARGS: Passed to FetchContent_Declare.
# SET: key=value variables to be set before the content population.
)
string(TOUPPER ${name} uname)
cmake_parse_arguments(GC_${uname} "SKIP_ADD;SKIP_FIND" "" "CMAKE_ARGS" ${ARGN})
cmake_parse_arguments(GC_${uname} "SKIP_ADD;SKIP_FIND" "" "SET" ${ARGN})

if (DEFINED GC_${uname}_CMAKE_ARGS)
message(STATUS "${name}_CMAKE_ARGS: ${GC_${uname}_CMAKE_ARGS}")
if (DEFINED GC_${uname}_SET)
foreach (var ${GC_${uname}_SET})
string(REGEX REPLACE "([^=]+)=(.*)" "\\1;\\2" var ${var})
list(GET var 0 key)
list(GET var 1 value)
message(STATUS "Setting ${key}=${value}")
set(${key} ${value})
endforeach ()
endif ()

if (DEFINED GC_${uname}_SRC_DIR)
FetchContent_Declare(
${name}
SOURCE_DIR ${GC_${uname}_SRC_DIR}
CMAKE_ARGS ${GC_${uname}_CMAKE_ARGS}
)
else ()
if (DEFINED GC_${uname}_VERSION)
Expand All @@ -53,7 +58,6 @@ function(gc_fetch_content
GIT_REPOSITORY ${git_repository}
GIT_TAG ${git_tag_or_version}
GIT_PROGRESS TRUE
CMAKE_ARGS ${GC_${uname}_CMAKE_ARGS}
FIND_PACKAGE_ARGS ${FIND_PACKAGE_ARGS}
)
endif ()
Expand All @@ -75,28 +79,6 @@ function(gc_fetch_content
endif ()
endfunction()

# Add one or multiple paths to the specified list.
# The paths could be specified as a list of files or a GLOB pattern:
# gc_add_path(SOURCES GLOB "src/*.cpp")
# gc_add_path(INCLUDES include1 include2 include3)
function(gc_add_path list_name paths)
if (paths STREQUAL "GLOB")
file(GLOB paths ${ARGN})
list(APPEND ${list_name} ${paths})
else ()
get_filename_component(path ${paths} ABSOLUTE)
list(APPEND ${list_name} ${path})
foreach (path ${ARGN})
get_filename_component(path ${path} ABSOLUTE)
list(APPEND ${list_name} ${path})
endforeach ()
endif ()
set(${list_name} ${${list_name}}
CACHE INTERNAL "${list_name} paths"
)
endfunction()


macro(gc_set_mlir_link_components VAR)
if(GC_DEV_LINK_LLVM_DYLIB)
set(${VAR}
Expand All @@ -108,3 +90,31 @@ macro(gc_set_mlir_link_components VAR)
)
endif()
endmacro()

function(gc_add_mlir_library name)
add_mlir_library(${ARGV})

if(name MATCHES ".+Passes")
set_property(GLOBAL APPEND PROPERTY GC_PASS_LIBS ${name})
else()
set_property(GLOBAL APPEND PROPERTY GC_MLIR_LIBS ${name})
endif()

if(GcInterface IN_LIST ARGN)
if(SHARED IN_LIST ARGN)
target_link_libraries(${name} PUBLIC GcInterface)
else()
target_link_libraries(obj.${name} PUBLIC GcInterface)
endif()
endif()
endfunction()

function(gc_add_mlir_dialect_library name)
add_mlir_dialect_library(${ARGV})
target_link_libraries(obj.${name} PUBLIC GcInterface)
set_property(GLOBAL APPEND PROPERTY GC_DIALECT_LIBS ${name})

if(GcInterface IN_LIST ARGN)
target_link_libraries(obj.${name} PUBLIC GcInterface)
endif()
endfunction()
8 changes: 4 additions & 4 deletions cmake/gtest.cmake
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
include_guard()
include(functions)

gc_fetch_content(
GTest
v1.14.0
https://github.com/google/googletest.git
GTest
v1.14.0
https://github.com/google/googletest.git
SET INSTALL_GTEST=OFF
)
11 changes: 6 additions & 5 deletions cmake/imex.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ include_guard()

get_property(IMEX_INCLUDES GLOBAL PROPERTY IMEX_INCLUDES)
if (NOT DEFINED IMEX_INCLUDES)
include(functions)
set(IMEX_CHECK_LLVM_VERSION ON)
set(IMEX_ENABLE_L0_RUNTIME 0)
# TODO: Change to main https://github.com/oneapi-src/oneDNN.git when all the
if(GC_DEV_LINK_LLVM_DYLIB)
message(WARN "GPU backend may not be compatible with dynamic linking to LLVM")
endif()

# TODO: Change to main https://github.com/intel/mlir-extensions when all the
# required functionality is merged.
gc_fetch_content(imex 496b240093b5e132b60c5ee69878300fe69be300 https://github.com/Menooker/mlir-extensions
CMAKE_ARGS "-DMLIR_DIR=${MLIR_DIR};-DIMEX_CHECK_LLVM_VERSION=ON;-DIMEX_ENABLE_L0_RUNTIME=0"
SET IMEX_CHECK_LLVM_VERSION=ON IMEX_ENABLE_L0_RUNTIME=0
)

set(IMEX_INCLUDES
Expand Down
Loading