Skip to content
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
37 changes: 36 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
cmake_minimum_required(VERSION 3.18)
project(InfiniRT LANGUAGES CXX)
project(InfiniRT VERSION 0.1.0 LANGUAGES CXX)

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

set(INFINI_RT_INSTALL_CMAKEDIR
"${CMAKE_INSTALL_LIBDIR}/cmake/InfiniRT"
CACHE STRING "Directory for the installed InfiniRT CMake package")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down Expand Up @@ -334,6 +341,34 @@ endif()

add_subdirectory(src)

set(INFINI_RT_PACKAGE_NEEDS_CUDATOOLKIT OFF)
if(WITH_NVIDIA OR WITH_ILUVATAR OR WITH_HYGON)
set(INFINI_RT_PACKAGE_NEEDS_CUDATOOLKIT ON)
endif()

set(INFINI_RT_PACKAGE_VENDOR_BACKEND "")
foreach(_backend METAX MOORE CAMBRICON ASCEND)
if(WITH_${_backend})
set(INFINI_RT_PACKAGE_VENDOR_BACKEND "${_backend}")
endif()
endforeach()

configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/InfiniRTConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/InfiniRTConfig.cmake"
INSTALL_DESTINATION "${INFINI_RT_INSTALL_CMAKEDIR}")

write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/InfiniRTConfigVersion.cmake"
VERSION "${PROJECT_VERSION}"
COMPATIBILITY SameMinorVersion)

install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/InfiniRTConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/InfiniRTConfigVersion.cmake"
DESTINATION "${INFINI_RT_INSTALL_CMAKEDIR}")

if(INFINI_RT_BUILD_TESTING OR INFINI_RT_BUILD_PERFORMANCE_TESTING)
enable_testing()
add_subdirectory(tests)
Expand Down
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,9 @@ ruff check .
build directory per platform or delete the stale build directory.
3. **Generated headers are stale**: Re-run CMake configure. Public headers are
generated during configuration.
4. **`test_install_consumer` fails to link or run**: Verify that the install
prefix contains both headers and libraries, and that the backend SDK library
paths are available to the consumer build and runtime linker.
4. **`test_install_consumer` fails to configure, link, or run**: Verify that the
install prefix contains the CMake package, headers, and libraries. Check that
`CMAKE_PREFIX_PATH` and the backend SDK root variables documented above are
available to the consumer build and runtime linker.
5. **Documentation build cannot find Doxygen**: Install Doxygen and Graphviz, or
rely on the Documentation Pages workflow for validation.
29 changes: 14 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,29 +110,28 @@ backend.

## Using Installed InfiniRT From Another Project

Downstream projects should consume the installed headers and libraries instead of depending on the InfiniRT source tree.
Downstream projects should consume the installed CMake package instead of
depending on the InfiniRT source tree:

Typical include and library paths are:
```cmake
find_package(InfiniRT 0.1 CONFIG REQUIRED)

```text
/path/to/infini-rt-prefix/include
/path/to/infini-rt-prefix/lib
add_executable(app main.cc)
target_link_libraries(app PRIVATE InfiniRT::infinirt)
```

A simple compile command may look like:
Point CMake at the installation prefix when configuring the consumer:

```bash
c++ main.cc \
-I/path/to/infini-rt-prefix/include \
-L/path/to/infini-rt-prefix/lib \
-linfinirt
cmake -S . -B build \
-DCMAKE_PREFIX_PATH=/path/to/infini-rt-prefix
cmake --build build -j
```

At runtime, make sure the dynamic linker can find `libinfinirt.so`, for example:

```bash
export LD_LIBRARY_PATH=/path/to/infini-rt-prefix/lib:$LD_LIBRARY_PATH
```
The imported target provides the installed include directory, library, C++17
requirement, and required backend link dependencies. `InfiniRT_ENABLED_BACKENDS`
and the `InfiniRT_WITH_<BACKEND>` variables report the backends compiled into
the installed library.

See [examples/consumer_cmake](examples/consumer_cmake) for a minimal CMake
consumer project.
Expand Down
167 changes: 167 additions & 0 deletions cmake/InfiniRTConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)

set(InfiniRT_VERSION "@PROJECT_VERSION@")
set(InfiniRT_ENABLED_BACKENDS "@INFINI_RT_PUBLIC_HEADER_DEVICES@")

set(InfiniRT_WITH_CPU @WITH_CPU@)
set(InfiniRT_WITH_NVIDIA @WITH_NVIDIA@)
set(InfiniRT_WITH_ILUVATAR @WITH_ILUVATAR@)
set(InfiniRT_WITH_HYGON @WITH_HYGON@)
set(InfiniRT_WITH_METAX @WITH_METAX@)
set(InfiniRT_WITH_MOORE @WITH_MOORE@)
set(InfiniRT_WITH_CAMBRICON @WITH_CAMBRICON@)
set(InfiniRT_WITH_ASCEND @WITH_ASCEND@)

if(@INFINI_RT_PACKAGE_NEEDS_CUDATOOLKIT@)
find_dependency(CUDAToolkit)
endif()

function(_infinirt_define_backend_runtime include_dirs link_libraries)
if(NOT TARGET InfiniRT::BackendRuntime)
add_library(InfiniRT::BackendRuntime INTERFACE IMPORTED)
set_target_properties(InfiniRT::BackendRuntime PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${include_dirs}"
INTERFACE_LINK_LIBRARIES "${link_libraries}")
endif()
endfunction()

set(_InfiniRT_VENDOR_BACKEND "@INFINI_RT_PACKAGE_VENDOR_BACKEND@")

if(_InfiniRT_VENDOR_BACKEND STREQUAL "METAX")
set(_InfiniRT_ROOT_HINTS "${InfiniRT_METAX_ROOT}")
if(DEFINED ENV{MACA_PATH})
list(APPEND _InfiniRT_ROOT_HINTS "$ENV{MACA_PATH}")
endif()
find_path(_InfiniRT_BACKEND_INCLUDE_DIR
NAMES mcr/mc_runtime.h
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES include)
find_library(_InfiniRT_BACKEND_RUNTIME_LIBRARY
NAMES mcruntime
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES lib lib64)
if(NOT _InfiniRT_BACKEND_INCLUDE_DIR OR
NOT _InfiniRT_BACKEND_RUNTIME_LIBRARY)
set(InfiniRT_FOUND FALSE)
set(InfiniRT_NOT_FOUND_MESSAGE
"MetaX SDK not found. Set InfiniRT_METAX_ROOT or MACA_PATH.")
return()
endif()
_infinirt_define_backend_runtime(
"${_InfiniRT_BACKEND_INCLUDE_DIR}"
"${_InfiniRT_BACKEND_RUNTIME_LIBRARY}")
elseif(_InfiniRT_VENDOR_BACKEND STREQUAL "MOORE")
set(_InfiniRT_ROOT_HINTS "${InfiniRT_MOORE_ROOT}")
foreach(_InfiniRT_ENV MUSA_ROOT MUSA_HOME MUSA_PATH)
if(DEFINED ENV{${_InfiniRT_ENV}})
list(APPEND _InfiniRT_ROOT_HINTS "$ENV{${_InfiniRT_ENV}}")
endif()
endforeach()
list(APPEND _InfiniRT_ROOT_HINTS /usr/local/musa)
find_path(_InfiniRT_BACKEND_INCLUDE_DIR
NAMES musa_runtime.h
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES include)
find_library(_InfiniRT_BACKEND_RUNTIME_LIBRARY
NAMES musa
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES lib lib64)
find_library(_InfiniRT_BACKEND_DRIVER_LIBRARY
NAMES musart
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES lib lib64)
if(NOT _InfiniRT_BACKEND_INCLUDE_DIR OR
NOT _InfiniRT_BACKEND_RUNTIME_LIBRARY OR
NOT _InfiniRT_BACKEND_DRIVER_LIBRARY)
set(InfiniRT_FOUND FALSE)
set(InfiniRT_NOT_FOUND_MESSAGE
"Moore SDK not found. Set InfiniRT_MOORE_ROOT or a MUSA root environment variable.")
return()
endif()
_infinirt_define_backend_runtime(
"${_InfiniRT_BACKEND_INCLUDE_DIR}"
"${_InfiniRT_BACKEND_RUNTIME_LIBRARY};${_InfiniRT_BACKEND_DRIVER_LIBRARY}")
elseif(_InfiniRT_VENDOR_BACKEND STREQUAL "CAMBRICON")
set(_InfiniRT_ROOT_HINTS "${InfiniRT_CAMBRICON_ROOT}")
if(DEFINED ENV{NEUWARE_HOME})
list(APPEND _InfiniRT_ROOT_HINTS "$ENV{NEUWARE_HOME}")
endif()
find_path(_InfiniRT_BACKEND_INCLUDE_DIR
NAMES cnrt.h
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES include)
find_library(_InfiniRT_BACKEND_RUNTIME_LIBRARY
NAMES cnrt
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES lib lib64)
if(NOT _InfiniRT_BACKEND_INCLUDE_DIR OR
NOT _InfiniRT_BACKEND_RUNTIME_LIBRARY)
set(InfiniRT_FOUND FALSE)
set(InfiniRT_NOT_FOUND_MESSAGE
"Cambricon SDK not found. Set InfiniRT_CAMBRICON_ROOT or NEUWARE_HOME.")
return()
endif()
_infinirt_define_backend_runtime(
"${_InfiniRT_BACKEND_INCLUDE_DIR}"
"${_InfiniRT_BACKEND_RUNTIME_LIBRARY}")
elseif(_InfiniRT_VENDOR_BACKEND STREQUAL "ASCEND")
set(_InfiniRT_ROOT_HINTS "${InfiniRT_ASCEND_ROOT}")
if(DEFINED ENV{ASCEND_HOME_PATH})
list(APPEND _InfiniRT_ROOT_HINTS "$ENV{ASCEND_HOME_PATH}")
endif()
list(APPEND _InfiniRT_ROOT_HINTS
/usr/local/Ascend/ascend-toolkit/latest)

find_path(_InfiniRT_BACKEND_INCLUDE_DIR
NAMES acl/acl.h
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES include)
find_library(_InfiniRT_BACKEND_RUNTIME_LIBRARY
NAMES ascendcl
HINTS ${_InfiniRT_ROOT_HINTS}
PATH_SUFFIXES lib64 lib)

set(_InfiniRT_ASCEND_HAL_HINTS "")
foreach(_InfiniRT_ROOT IN LISTS _InfiniRT_ROOT_HINTS)
if(_InfiniRT_ROOT)
get_filename_component(
_InfiniRT_ASCEND_ROOT "${_InfiniRT_ROOT}/../.." ABSOLUTE)
list(APPEND _InfiniRT_ASCEND_HAL_HINTS
"${_InfiniRT_ASCEND_ROOT}/driver/lib64/driver"
"${_InfiniRT_ROOT}/runtime/lib64/stub"
"${_InfiniRT_ROOT}/${CMAKE_SYSTEM_PROCESSOR}-linux/devlib")
endif()
endforeach()
find_library(_InfiniRT_BACKEND_DRIVER_LIBRARY
NAMES ascend_hal
HINTS ${_InfiniRT_ASCEND_HAL_HINTS})

if(NOT _InfiniRT_BACKEND_INCLUDE_DIR OR
NOT _InfiniRT_BACKEND_RUNTIME_LIBRARY OR
NOT _InfiniRT_BACKEND_DRIVER_LIBRARY)
set(InfiniRT_FOUND FALSE)
set(InfiniRT_NOT_FOUND_MESSAGE
"Ascend SDK not found. Set InfiniRT_ASCEND_ROOT or ASCEND_HOME_PATH.")
return()
endif()

set(_InfiniRT_ASCEND_INCLUDE_DIRS
"${_InfiniRT_BACKEND_INCLUDE_DIR}")
get_filename_component(
_InfiniRT_ASCEND_HOME "${_InfiniRT_BACKEND_INCLUDE_DIR}" DIRECTORY)
foreach(_InfiniRT_INCLUDE_SUBDIR aclnn aclnnop)
if(IS_DIRECTORY
"${_InfiniRT_ASCEND_HOME}/include/${_InfiniRT_INCLUDE_SUBDIR}")
list(APPEND _InfiniRT_ASCEND_INCLUDE_DIRS
"${_InfiniRT_ASCEND_HOME}/include/${_InfiniRT_INCLUDE_SUBDIR}")
endif()
endforeach()
_infinirt_define_backend_runtime(
"${_InfiniRT_ASCEND_INCLUDE_DIRS}"
"${_InfiniRT_BACKEND_RUNTIME_LIBRARY};${_InfiniRT_BACKEND_DRIVER_LIBRARY};${CMAKE_DL_LIBS}")
endif()

include("${CMAKE_CURRENT_LIST_DIR}/InfiniRTTargets.cmake")
check_required_components(InfiniRT)
5 changes: 3 additions & 2 deletions docs/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ Run them with:
ctest --test-dir build --output-on-failure
```

The `test_install_consumer` test installs InfiniRT to a temporary prefix,
compiles a small external consumer against the installed prefix, and runs it.
The `test_install_consumer` test installs InfiniRT to a temporary prefix, uses
`find_package(InfiniRT CONFIG REQUIRED)` from a separate CMake project, links
that project to `InfiniRT::infinirt`, and runs it.

## Performance Tests

Expand Down
27 changes: 17 additions & 10 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,23 +57,30 @@ int main() {
}
```

Compile it against the installed prefix:
Create a `CMakeLists.txt` that imports the installed package:

```bash
c++ main.cc \
-std=c++17 \
-I/path/to/infini-rt-prefix/include \
-L/path/to/infini-rt-prefix/lib \
-linfinirt \
-Wl,-rpath,/path/to/infini-rt-prefix/lib
```cmake
cmake_minimum_required(VERSION 3.18)
project(infinirt_example LANGUAGES CXX)

find_package(InfiniRT 0.1 CONFIG REQUIRED)

add_executable(infinirt_example main.cc)
target_link_libraries(infinirt_example PRIVATE InfiniRT::infinirt)
```

If the runtime linker cannot find `libinfinirt.so`, set `LD_LIBRARY_PATH`:
Configure and build it against the installed prefix:

```bash
export LD_LIBRARY_PATH=/path/to/infini-rt-prefix/lib:$LD_LIBRARY_PATH
cmake -S . -B build \
-DCMAKE_PREFIX_PATH=/path/to/infini-rt-prefix
cmake --build build -j
```

The `InfiniRT::infinirt` target supplies the required include path, library,
C++ language level, and backend dependencies. For an accelerator build, the
corresponding SDK must also be available when configuring the consumer.

## Next Steps

See [Runtime API](api/runtime.md) for backend dispatch and runtime functions,
Expand Down
18 changes: 2 additions & 16 deletions examples/consumer_cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,8 @@ project(infinirt_consumer_example LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(NOT DEFINED INFINI_RT_PREFIX)
message(FATAL_ERROR "Set INFINI_RT_PREFIX to an installed InfiniRT prefix.")
endif()

find_library(INFINI_RT_LIBRARY
NAMES infinirt
PATHS "${INFINI_RT_PREFIX}/lib" "${INFINI_RT_PREFIX}/lib64"
REQUIRED
NO_DEFAULT_PATH)
find_package(InfiniRT CONFIG REQUIRED)

add_executable(infinirt_consumer main.cc)
target_include_directories(infinirt_consumer PRIVATE
"${INFINI_RT_PREFIX}/include")
target_link_libraries(infinirt_consumer PRIVATE "${INFINI_RT_LIBRARY}")

get_filename_component(INFINI_RT_LIBRARY_DIR "${INFINI_RT_LIBRARY}" DIRECTORY)
set_target_properties(infinirt_consumer PROPERTIES
BUILD_RPATH "${INFINI_RT_LIBRARY_DIR}")
target_link_libraries(infinirt_consumer PRIVATE InfiniRT::infinirt)

2 changes: 1 addition & 1 deletion examples/consumer_cmake/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Then build this consumer:

```bash
cmake -S . -B build \
-DINFINI_RT_PREFIX=/path/to/infini-rt-prefix
-DCMAKE_PREFIX_PATH=/path/to/infini-rt-prefix
cmake --build build -j
./build/infinirt_consumer
```
Expand Down
Loading
Loading