diff --git a/CMakeLists.txt b/CMakeLists.txt index 38b8d72..2734a69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ option(WITH_ASCEND "Enable Ascend backend" OFF) option(AUTO_DETECT_DEVICES "Automatically detect available devices" OFF) option(INFINI_RT_BUILD_TESTING "Build InfiniRT tests" OFF) +option(INFINI_RT_BUILD_DOCS "Build InfiniRT documentation" OFF) if(AUTO_DETECT_DEVICES) message(STATUS "Auto-detecting available devices...") @@ -336,3 +337,22 @@ if(INFINI_RT_BUILD_TESTING) enable_testing() add_subdirectory(tests) endif() + +if(INFINI_RT_BUILD_DOCS) + find_package(Doxygen REQUIRED) + + set(INFINI_RT_DOXYGEN_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/docs/reference") + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in" + "${CMAKE_BINARY_DIR}/docs/Doxyfile" + @ONLY) + + add_custom_target(infinirt_docs + COMMAND ${CMAKE_COMMAND} -E make_directory + "${INFINI_RT_DOXYGEN_OUTPUT_DIRECTORY}" + COMMAND ${DOXYGEN_EXECUTABLE} "${CMAKE_BINARY_DIR}/docs/Doxyfile" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating InfiniRT documentation" + VERBATIM) +endif() diff --git a/README.md b/README.md index 5d41768..5e15d0a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # InfiniRT -InfiniRT is the runtime library of the InfiniCore project. It provides a stable runtime API for device management and memory operations across supported backends such as CPU and NVIDIA. +InfiniRT is the runtime library of the InfiniCore project. It provides the +public runtime entry for supported accelerator backends, starting with device +management and memory operations and growing with higher-level runtime +features. The recommended public entry is: @@ -8,6 +11,8 @@ The recommended public entry is: #include ``` +Full user documentation is available in [docs/README.md](docs/README.md). + ## Build and Install Configure, build, and install InfiniRT with CMake: @@ -63,6 +68,7 @@ cmake --install build ```cpp #include + #include int main() { @@ -128,6 +134,9 @@ At runtime, make sure the dynamic linker can find `libinfinirt.so`, for example: export LD_LIBRARY_PATH=/path/to/infini-rt-prefix/lib:$LD_LIBRARY_PATH ``` +See [examples/consumer_cmake](examples/consumer_cmake) for a minimal CMake +consumer project. + ## Tests Enable C++ tests with: diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in new file mode 100644 index 0000000..8f5d1b9 --- /dev/null +++ b/docs/Doxyfile.in @@ -0,0 +1,173 @@ +PROJECT_NAME = "InfiniRT" +PROJECT_BRIEF = "Runtime API for Accelerators" +OUTPUT_DIRECTORY = @INFINI_RT_DOXYGEN_OUTPUT_DIRECTORY@ +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +FULL_PATH_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +TAB_SIZE = 2 +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +EXTENSION_MAPPING = +MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 5 +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = YES +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = NO +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = NO +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 0 +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = YES +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = NO +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = NO +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_AS_ERROR = NO +INPUT = README.md \ + docs \ + docs/api \ + include/infini/rt.h \ + generated/include/infini/rt/generated.h \ + src/data_type.h \ + src/device.h \ + src/runtime.h \ + src/tensor_view.h +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.md \ + *.h +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = YES +EXCLUDE_PATTERNS = */infini/rt/detail/* \ + */generated/src/* +EXCLUDE_SYMBOLS = *::detail::* \ + *::generated_detail::* \ + *::tensor_view_detail::* +EXAMPLE_PATH = examples +EXAMPLE_PATTERNS = *.cc \ + CMakeLists.txt +EXAMPLE_RECURSIVE = YES +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = docs/README.md +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +ALPHABETICAL_INDEX = YES +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_COLORSTYLE = LIGHT +HTML_DYNAMIC_SECTIONS = NO +GENERATE_TREEVIEW = YES +ENUM_VALUES_PER_LINE = 4 +TREEVIEW_WIDTH = 250 +EXT_LINKS_IN_WINDOW = NO +OBFUSCATE_EMAILS = YES +HTML_FORMULA_FORMAT = png +FORMULA_FONTSIZE = 10 +USE_MATHJAX = NO +SEARCHENGINE = YES +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +GENERATE_LATEX = NO +GENERATE_XML = NO +GENERATE_DOCBOOK = NO +GENERATE_AUTOGEN_DEF = NO +GENERATE_PERLMOD = NO +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = include \ + generated/include \ + src +INCLUDE_FILE_PATTERNS = +PREDEFINED = +SKIP_FUNCTION_MACROS = YES +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +INTERACTIVE_SVG = NO +DOT_PATH = +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..fc375c5 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,26 @@ +# InfiniRT Documentation + +InfiniRT is the runtime layer of the InfiniCore project. This documentation +starts with the public runtime surface available today and is intended to grow +with lower-level backend capabilities and higher-level user-facing features as +they are added. + +The supported public include entry is: + +```cpp +#include +``` + +Start with these pages: + +- [Getting Started](getting-started.md): install InfiniRT and compile a minimal + consumer. +- [Build and Test](build.md): CMake options for CPU, NVIDIA, and other + backends. +- [Runtime API](api/runtime.md): the runtime namespace and backend dispatch + model. +- [Core Types](api/core-types.md): `Device`, `DataType`, and `TensorView`. +- [Backends](backends.md): supported backend options and API support notes. +- [Compatibility](compatibility.md): stable API boundary and internal headers. + +API reference generation is described in [API Reference](api/reference.md). diff --git a/docs/api/core-types.md b/docs/api/core-types.md new file mode 100644 index 0000000..3517a9b --- /dev/null +++ b/docs/api/core-types.md @@ -0,0 +1,68 @@ +# Core Types + +Core types are available through: + +```cpp +#include +``` + +## Device + +`infini::rt::Device` identifies a backend type and an index. + +```cpp +infini::rt::Device device{infini::rt::Device::Type::kCpu, 0}; +auto type = device.type(); +auto index = device.index(); +``` + +Known device types include: + +- `Device::Type::kCpu` +- `Device::Type::kNvidia` +- `Device::Type::kIluvatar` +- `Device::Type::kMetax` +- `Device::Type::kMoore` +- `Device::Type::kHygon` +- `Device::Type::kCambricon` +- `Device::Type::kAscend` + +## DataType + +`infini::rt::DataType` describes tensor element types. + +Supported values include signed integers, unsigned integers, reduced precision +floating point, and standard floating point types: + +- `kInt8`, `kInt16`, `kInt32`, `kInt64` +- `kUInt8`, `kUInt16`, `kUInt32`, `kUInt64` +- `kFloat16`, `kBFloat16`, `kFloat32`, `kFloat64` + +## TensorView + +`infini::rt::TensorView` is a non-owning description of tensor memory. + +```cpp +std::vector data(16); + +infini::rt::TensorView tensor{ + data.data(), + std::vector{4, 4}, + infini::rt::DataType::kFloat32, + infini::rt::Device{infini::rt::Device::Type::kCpu, 0}, + std::vector{4, 1}}; + +auto elements = tensor.numel(); +auto bytes_per_element = tensor.element_size(); +auto contiguous = tensor.IsContiguous(); +``` + +`TensorView` stores: + +- data pointer +- shape +- data type +- device +- strides + +It does not own the memory it references. diff --git a/docs/api/reference.md b/docs/api/reference.md new file mode 100644 index 0000000..ab9b80f --- /dev/null +++ b/docs/api/reference.md @@ -0,0 +1,55 @@ +# API Reference + +InfiniRT keeps user-facing documentation in Markdown and can generate a C++ API +reference with Doxygen. + +## Generate Reference HTML + +Configure a build first so that generated public headers exist: + +```bash +cmake -S . -B build -DWITH_CPU=ON +``` + +Then generate it through CMake: + +```bash +cmake -S . -B build -DINFINI_RT_BUILD_DOCS=ON +cmake --build build --target infinirt_docs +``` + +The generated HTML is written under: + +```text +build/docs/reference/html +``` + +## Preview the Rendered Structure + +Serve the generated HTML directory with a local static file server: + +```bash +python3 -m http.server 8000 --directory build/docs/reference/html +``` + +Then open: + +```text +http://localhost:8000/ +``` + +The Doxygen page includes a left-side tree view and search box, which are the +recommended way to inspect the rendered API structure. + +## Reference Scope + +The Doxygen configuration is intentionally scoped to the public entry header, +core public headers, and generated dispatching runtime declarations. + +The following are not intended as the primary user documentation surface: + +- `infini/rt/detail/*` +- backend implementation detail copied from `src/native/*` +- generated implementation source under `generated/src` + +Use [Compatibility](../compatibility.md) for the supported API boundary. diff --git a/docs/api/runtime.md b/docs/api/runtime.md new file mode 100644 index 0000000..0505777 --- /dev/null +++ b/docs/api/runtime.md @@ -0,0 +1,120 @@ +# Runtime API + +The runtime API is exposed through: + +```cpp +#include +``` + +Runtime functions live in `infini::rt::runtime`. + +## Backend Selection + +The top-level functions select which enabled backend receives +`infini::rt::runtime` calls: + +```cpp +infini::rt::set_runtime_device_type(infini::rt::Device::Type::kCpu); +auto current = infini::rt::runtime_device_type(); +``` + +The selected backend is thread-local. A GPU backend is selected initially when +one is enabled; otherwise CPU is selected. + +Use the dispatching API for ordinary code: + +```cpp +namespace rt = infini::rt::runtime; + +infini::rt::set_runtime_device_type(infini::rt::Device::Type::kCpu); + +void* ptr = nullptr; +rt::Malloc(&ptr, 1024); +rt::Free(ptr); +``` + +## CUDA Runtime API Alignment + +The `infini::rt::runtime` namespace follows CUDA Runtime API naming, call +shapes, return-status conventions, and handle-oriented stream/event usage where +practical. Backend implementations translate those calls to the enabled runtime +backend, while unsupported operations return a non-success status without +changing the API shape. The signatures below are therefore listed without +per-function explanations; for CUDA-like operations, use the corresponding CUDA +Runtime API behavior as the baseline unless a backend support note says +otherwise. + +## Runtime Status and Types + +```cpp +runtime::Error +runtime::Stream +runtime::Event +runtime::MemcpyKind +runtime::kSuccess +runtime::kMemcpyHostToHost +runtime::kMemcpyHostToDevice +runtime::kMemcpyDeviceToHost +runtime::kMemcpyDeviceToDevice +``` + +## Device Functions + +```cpp +runtime::Error SetDevice(int device); +runtime::Error GetDevice(int* device); +runtime::Error GetDeviceCount(int* count); +runtime::Error DeviceSynchronize(); +``` + +## Memory Functions + +```cpp +runtime::Error Malloc(void** ptr, std::size_t size); +runtime::Error MallocHost(void** ptr, std::size_t size); +runtime::Error MallocAsync(void** ptr, std::size_t size, runtime::Stream stream); +runtime::Error Free(void* ptr); +runtime::Error FreeHost(void* ptr); +runtime::Error FreeAsync(void* ptr, runtime::Stream stream); +runtime::Error MemGetInfo(std::size_t* free, std::size_t* total); +runtime::Error Memcpy(void* dst, const void* src, std::size_t count, + runtime::MemcpyKind kind); +runtime::Error MemcpyAsync(void* dst, const void* src, std::size_t count, + runtime::MemcpyKind kind, runtime::Stream stream); +runtime::Error Memset(void* ptr, int value, std::size_t count); +runtime::Error MemsetAsync(void* ptr, int value, std::size_t count, + runtime::Stream stream); +``` + +Not every backend supports every optional operation. Unsupported operations +return a non-success status. See [Backends](../backends.md). + +## Stream and Event Functions + +```cpp +runtime::Error StreamCreate(runtime::Stream* stream); +runtime::Error StreamDestroy(runtime::Stream stream); +runtime::Error StreamSynchronize(runtime::Stream stream); +runtime::Error StreamWaitEvent(runtime::Stream stream, runtime::Event event, + unsigned int flags); +runtime::Error EventCreate(runtime::Event* event); +runtime::Error EventCreateWithFlags(runtime::Event* event, unsigned int flags); +runtime::Error EventRecord(runtime::Event event, runtime::Stream stream); +runtime::Error EventQuery(runtime::Event event); +runtime::Error EventSynchronize(runtime::Event event); +runtime::Error EventDestroy(runtime::Event event); +runtime::Error EventElapsedTime(float* ms, runtime::Event start, + runtime::Event end); +``` + +## Backend-Specific Runtime Templates + +Backend runtime specializations are available as implementation-facing headers, +for example: + +```cpp +#include +``` + +These headers are useful for backend tests and low-level integrations, but +ordinary consumers should prefer the dispatching API from ``. diff --git a/docs/backends.md b/docs/backends.md new file mode 100644 index 0000000..5b62dd5 --- /dev/null +++ b/docs/backends.md @@ -0,0 +1,49 @@ +# Backends + +InfiniRT can be built with CPU and one accelerator backend. The public runtime +API remains the same, while support for optional operations can differ by +backend. + +## Backend Options + +| Backend | CMake option | Notes | +| --- | --- | --- | +| CPU | `WITH_CPU` | Enabled by default when no backend option is set. | +| NVIDIA | `WITH_NVIDIA` | Requires CUDA toolkit. | +| Iluvatar | `WITH_ILUVATAR` | CUDA-compatible backend using clang with ivcore flags. | +| MetaX | `WITH_METAX` | Requires `MACA_PATH`. | +| Moore | `WITH_MOORE` | Requires `MUSA_ROOT`, `MUSA_HOME`, or `MUSA_PATH`. | +| Hygon | `WITH_HYGON` | Requires DTK and a DTK CUDA toolkit. | +| Cambricon | `WITH_CAMBRICON` | Requires `NEUWARE_HOME`. | +| Ascend | `WITH_ASCEND` | Requires Ascend toolkit. | + +Only one accelerator backend can be enabled at a time. CPU can be enabled +together with the selected accelerator backend. + +## Runtime API Support + +All enabled runtime backends provide the core device and memory entry points +needed by the dispatching runtime API. Optional operations may return an error +status on backends that do not support them. + +Current test expectations are: + +| Backend | Async memcpy | Host memory | Async memory | Memory info | Async memset | Events | +| --- | --- | --- | --- | --- | --- | --- | +| CPU | No | Yes | No | Yes | No | Yes | +| NVIDIA | Yes | Yes | Yes | Yes | Yes | Yes | +| Iluvatar | Yes | Yes | Yes | Yes | Yes | Yes | +| MetaX | Yes | Yes | Yes | Yes | Yes | Yes | +| Moore | Yes | Yes | No | Yes | Yes | Yes | +| Hygon | Yes | Yes | Yes | Yes | Yes | Yes | +| Cambricon | Yes | No | No | No | No | No | +| Ascend | Yes | No | No | No | No | No | + +Treat a non-`kSuccess` status as the portable way to detect unsupported +operations. + +## Header Dependencies + +Backend public wrappers may include vendor headers. For example, an NVIDIA +build may require CUDA headers to be available when compiling a downstream +consumer that includes ``. diff --git a/docs/build.md b/docs/build.md new file mode 100644 index 0000000..1614251 --- /dev/null +++ b/docs/build.md @@ -0,0 +1,100 @@ +# Build and Test + +InfiniRT uses CMake and C++17. + +## Common Options + +```bash +-DWITH_CPU=ON +-DWITH_NVIDIA=ON +-DWITH_ILUVATAR=ON +-DWITH_METAX=ON +-DWITH_MOORE=ON +-DWITH_HYGON=ON +-DWITH_CAMBRICON=ON +-DWITH_ASCEND=ON +-DAUTO_DETECT_DEVICES=ON +-DINFINI_RT_BUILD_TESTING=ON +-DINFINI_RT_BUILD_DOCS=ON +``` + +Only one GPU backend can be enabled in a build. CPU can be enabled together +with a GPU backend. If no backend option is enabled, CPU is enabled by default. + +## CPU Build + +```bash +cmake -S . -B build \ + -DCMAKE_INSTALL_PREFIX=/path/to/infini-rt-prefix \ + -DWITH_CPU=ON \ + -DINFINI_RT_BUILD_TESTING=ON +cmake --build build -j +ctest --test-dir build --output-on-failure +cmake --install build +``` + +The CPU backend requires OpenMP. + +## NVIDIA Build + +```bash +cmake -S . -B build \ + -DCMAKE_INSTALL_PREFIX=/path/to/infini-rt-prefix \ + -DWITH_CPU=ON \ + -DWITH_NVIDIA=ON \ + -DINFINI_RT_BUILD_TESTING=ON +cmake --build build -j +ctest --test-dir build --output-on-failure +cmake --install build +``` + +The NVIDIA backend requires the CUDA toolkit. The installed public headers may +include CUDA headers, so consumers also need access to the CUDA include +directory when compiling against an NVIDIA build. + +## Generated Public Headers + +During CMake configuration, InfiniRT generates backend-specific public headers +under `generated/include`. The generated headers match the backend options used +for that build and are installed with the hand-written headers. + +The recommended consumer include remains: + +```cpp +#include +``` + +## Tests + +Enable tests with: + +```bash +-DINFINI_RT_BUILD_TESTING=ON +``` + +Run them with: + +```bash +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. + +## Documentation + +Enable the Doxygen documentation target with: + +```bash +cmake -S . -B build -DINFINI_RT_BUILD_DOCS=ON +cmake --build build --target infinirt_docs +``` + +The generated HTML is written to `build/docs/reference/html` under the source +tree. + +To preview the generated structure, serve the HTML directory: + +```bash +python3 -m http.server 8000 --directory build/docs/reference/html +``` diff --git a/docs/compatibility.md b/docs/compatibility.md new file mode 100644 index 0000000..2621d74 --- /dev/null +++ b/docs/compatibility.md @@ -0,0 +1,44 @@ +# Compatibility + +This page defines the intended documentation and compatibility boundary for +InfiniRT consumers. + +## Stable User Entry + +Use: + +```cpp +#include +``` + +The stable user-facing surface is: + +- `infini::rt::Device` +- `infini::rt::DataType` +- `infini::rt::TensorView` +- `infini::rt::set_runtime_device_type` +- `infini::rt::runtime_device_type` +- `infini::rt::runtime` dispatching functions and constants documented in + [Runtime API](api/runtime.md) + +## Implementation-Facing Headers + +Installed headers under `infini/rt/detail/*` are generated to support the public +entry header. They are not intended as direct user includes. + +Backend wrapper headers such as `infini/rt/cpu/runtime_.h` expose +backend-specific `runtime::Runtime` specializations. They are +useful for backend tests and advanced integrations, but ordinary consumers +should prefer ``. + +## Generated Headers + +Generated public headers depend on the backend options used during CMake +configuration. A consumer should compile against the installed prefix produced +by the same configured build. + +## ABI Notes + +InfiniRT currently exposes a C++ API. Consumers should treat the installed +headers and `libinfinirt.so` as a matching pair from the same build or release. + diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..d791aa9 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,80 @@ +# Getting Started + +This guide installs InfiniRT and builds a small application against the +installed headers and library. + +## Build and Install + +Choose an install prefix outside the source tree: + +```bash +cmake -S . -B build \ + -DCMAKE_INSTALL_PREFIX=/path/to/infini-rt-prefix \ + -DWITH_CPU=ON +cmake --build build -j +cmake --install build +``` + +The install prefix contains: + +```text +/path/to/infini-rt-prefix/include +/path/to/infini-rt-prefix/lib +``` + +On platforms that install libraries to `lib64`, use that directory in place of +`lib`. + +## Minimal Consumer + +Use the single public entry header: + +```cpp +#include + +#include + +int main() { + namespace rt = infini::rt::runtime; + + rt::SetDevice(0); + + void* ptr = nullptr; + constexpr std::size_t size = 1024; + + if (rt::Malloc(&ptr, size) != rt::kSuccess) { + return 1; + } + if (rt::Memset(ptr, 0, size) != rt::kSuccess) { + rt::Free(ptr); + return 1; + } + if (rt::Free(ptr) != rt::kSuccess) { + return 1; + } + + return 0; +} +``` + +Compile it against the installed prefix: + +```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 +``` + +If the runtime linker cannot find `libinfinirt.so`, set `LD_LIBRARY_PATH`: + +```bash +export LD_LIBRARY_PATH=/path/to/infini-rt-prefix/lib:$LD_LIBRARY_PATH +``` + +## Next Steps + +See [Runtime API](api/runtime.md) for backend dispatch and runtime functions, +and [Build and Test](build.md) for backend-specific build options. diff --git a/examples/.clang-format b/examples/.clang-format new file mode 100644 index 0000000..4af72ce --- /dev/null +++ b/examples/.clang-format @@ -0,0 +1,15 @@ +--- +BasedOnStyle: InheritParentConfig +IncludeBlocks: Regroup +IncludeCategories: + - Regex: "^" + Priority: 1 + - Regex: "^<" + Priority: 2 + - Regex: "^\"" + Priority: 4 + - Regex: ".*" + Priority: 5 +... diff --git a/examples/basic_runtime.cc b/examples/basic_runtime.cc new file mode 100644 index 0000000..bd43de4 --- /dev/null +++ b/examples/basic_runtime.cc @@ -0,0 +1,36 @@ +#include +#include +#include + +#include + +int main() { + namespace rt = infini::rt::runtime; + + if (rt::SetDevice(0) != rt::kSuccess) { + return 1; + } + + std::vector input{1, 2, 3, 4}; + std::vector output(input.size()); + void* device_ptr = nullptr; + + if (rt::Malloc(&device_ptr, input.size()) != rt::kSuccess) { + return 1; + } + + auto status = rt::Memcpy(device_ptr, input.data(), input.size(), + rt::kMemcpyHostToDevice); + if (status == rt::kSuccess) { + status = rt::Memcpy(output.data(), device_ptr, output.size(), + rt::kMemcpyDeviceToHost); + } + + const auto free_status = rt::Free(device_ptr); + + if (status != rt::kSuccess || free_status != rt::kSuccess) { + return 1; + } + + return output == input ? 0 : 1; +} diff --git a/examples/consumer_cmake/CMakeLists.txt b/examples/consumer_cmake/CMakeLists.txt new file mode 100644 index 0000000..bcaef1e --- /dev/null +++ b/examples/consumer_cmake/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.18) +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) + +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}") + diff --git a/examples/consumer_cmake/README.md b/examples/consumer_cmake/README.md new file mode 100644 index 0000000..bc590ea --- /dev/null +++ b/examples/consumer_cmake/README.md @@ -0,0 +1,23 @@ +# InfiniRT CMake Consumer Example + +This example builds a small executable against an installed InfiniRT prefix. + +Install InfiniRT first: + +```bash +cmake -S ../.. -B ../../build \ + -DCMAKE_INSTALL_PREFIX=/path/to/infini-rt-prefix \ + -DWITH_CPU=ON +cmake --build ../../build -j +cmake --install ../../build +``` + +Then build this consumer: + +```bash +cmake -S . -B build \ + -DINFINI_RT_PREFIX=/path/to/infini-rt-prefix +cmake --build build -j +./build/infinirt_consumer +``` + diff --git a/examples/consumer_cmake/main.cc b/examples/consumer_cmake/main.cc new file mode 100644 index 0000000..941f20a --- /dev/null +++ b/examples/consumer_cmake/main.cc @@ -0,0 +1,23 @@ +#include + +#include + +int main() { + namespace rt = infini::rt::runtime; + + void* ptr = nullptr; + constexpr std::size_t size = 128; + + if (rt::SetDevice(0) != rt::kSuccess) { + return 1; + } + if (rt::Malloc(&ptr, size) != rt::kSuccess) { + return 1; + } + if (rt::Memset(ptr, 0, size) != rt::kSuccess) { + rt::Free(ptr); + return 1; + } + + return rt::Free(ptr) == rt::kSuccess ? 0 : 1; +} diff --git a/examples/select_backend.cc b/examples/select_backend.cc new file mode 100644 index 0000000..21c81da --- /dev/null +++ b/examples/select_backend.cc @@ -0,0 +1,22 @@ +#include + +#include + +int main() { + namespace rt = infini::rt::runtime; + + infini::rt::set_runtime_device_type(infini::rt::Device::Type::kCpu); + + if (infini::rt::runtime_device_type() != infini::rt::Device::Type::kCpu) { + return 1; + } + + void* ptr = nullptr; + constexpr std::size_t size = 256; + + if (rt::Malloc(&ptr, size) != rt::kSuccess) { + return 1; + } + + return rt::Free(ptr) == rt::kSuccess ? 0 : 1; +} diff --git a/examples/tensor_view.cc b/examples/tensor_view.cc new file mode 100644 index 0000000..3fc66c9 --- /dev/null +++ b/examples/tensor_view.cc @@ -0,0 +1,29 @@ +#include +#include + +#include + +int main() { + std::vector data(16); + const infini::rt::Device device{infini::rt::Device::Type::kCpu, 0}; + + const infini::rt::TensorView tensor{data.data(), + std::vector{4, 4}, + infini::rt::DataType::kFloat32, device, + std::vector{4, 1}}; + + if (tensor.numel() != 16) { + return 1; + } + if (tensor.element_size() != sizeof(float)) { + return 1; + } + if (!tensor.IsContiguous()) { + return 1; + } + if (tensor.stride(0) != 4 || tensor.stride(1) != 1) { + return 1; + } + + return 0; +}