Skip to content

Commit

Permalink
[aot] (cherry-pick) Removed unused archs in C-API (#7167), FindTaichi…
Browse files Browse the repository at this point in the history
… CMake module to help outside project integration (#7168) (#7177)

Issue: #

### Brief Summary

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
PENGUINLIONG and pre-commit-ci[bot] authored Jan 16, 2023
1 parent 36d4fcc commit f455fbe
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 111 deletions.
8 changes: 5 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ include("cmake/utils.cmake")

if (NOT DEFINED TI_VERSION_MAJOR)
message(WARNING "It seems that you are running cmake manually, which may cause issues. Please use setup.py to build taichi from source, see https://docs.taichi-lang.org/docs/dev_install for more details.")
set(TI_VERSION_MAJOR 0)
set(TI_VERSION_MINOR 0)
set(TI_VERSION_PATCH 0)
file(READ "${CMAKE_CURRENT_LIST_DIR}/version.txt" TI_VERSION_LITERAL)
string(REGEX MATCH "v([0-9]+)\\.([0-9]+)\\.([0-9]+)" TI_VERSION_LITERAL ${TI_VERSION_LITERAL})
set(TI_VERSION_MAJOR ${CMAKE_MATCH_1})
set(TI_VERSION_MINOR ${CMAKE_MATCH_2})
set(TI_VERSION_PATCH ${CMAKE_MATCH_3})
endif()

set(CMAKE_CXX_STANDARD 17)
Expand Down
172 changes: 172 additions & 0 deletions c_api/cmake/FindTaichi.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#[=======================================================================[.rst:
FindTaichi
----------
Finds the Taichi library.
The module first attempts to locate ``TaichiConfig.cmake`` in any Taichi
installation in CMake variable ``TAICHI_C_API_INSTALL_DIR`` or environment
variable of the same name. If the config file cannot be found, the libraries are
heuristically searched by names and paths in ``TAICHI_C_API_INSTALL_DIR``.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported targets, if found:
``taichi::runtime``
The Taichi Runtime library.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``taichi_FOUND``
True if a Taichi installation is found.
``taichi_VERSION``
Version of installed Taichi. Components might have lower version numbers.
``taichi_INCLUDE_DIRS``
Paths to Include directories needed to use Taichi.
``taichi_LIBRARIES``
Paths to Taichi linking libraries (``.libs``).
``taichi_REDIST_LIBRARIES``
Paths to Taichi redistributed runtime libraries (``.so`` and ``.dll``). You
might want to copy them next to your executables.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``taichi_runtime_VERSION``
Taichi runtime library version.
``taichi_runtime_INCLUDE_DIR``
The directory containing ``taichi/taichi.h``.
``taichi_runtime_LIBRARY``
Path to linking library of ``taichi_runtime``.
``taichi_runtime_REDIST_LIBRARY``
Path to redistributed runtime library of ``taichi_runtime``.
#]=======================================================================]

cmake_policy(PUSH)

# Support `IN_LIST` in CMake `if` command.
if(POLICY CMP0057)
cmake_policy(SET CMP0057 NEW)
endif()

# Find TiRT in the installation directory. The installation directory is
# traditionally specified by an environment variable
# `TAICHI_C_API_INSTALL_DIR`.
if(NOT EXISTS ${TAICHI_C_API_INSTALL_DIR})
set(TAICHI_C_API_INSTALL_DIR $ENV{TAICHI_C_API_INSTALL_DIR})
endif()
if(EXISTS ${TAICHI_C_API_INSTALL_DIR})
get_filename_component(TAICHI_C_API_INSTALL_DIR "${TAICHI_C_API_INSTALL_DIR}" ABSOLUTE)
message("-- TAICHI_C_API_INSTALL_DIR=${TAICHI_C_API_INSTALL_DIR}")
endif()

set(TAICHI_C_API_INSTALL_DIR "${TAICHI_C_API_INSTALL_DIR}" CACHE PATH "Root directory to Taichi installation")

# Set up default find components
if("${taichi_FIND_COMPONENTS}" STREQUAL "")
# (penguinliong) Currently we only have Taichi Runtime. We might make the
# codegen a library in the future?
set(taichi_FIND_COMPONENTS "runtime")
endif()

message("-- Looking for Taichi components: ${taichi_FIND_COMPONENTS}")

# (penguinliong) Note that the config files only exposes libraries and their
# public headers. We still need to encapsulate the libraries into semantical
# CMake targets in this list. So please DO NOT find Taichi in config mode
# directly.
find_package(taichi CONFIG QUIET HINTS "${TAICHI_C_API_INSTALL_DIR}")

if(taichi_FOUND)
message("-- Found Taichi ${taichi_VERSION} in config mode: ${taichi_DIR}")
else()
message("-- Could NOT find Taichi in config mode; fallback to heuristic search")
endif()

# - [taichi::runtime] ----------------------------------------------------------

if(("runtime" IN_LIST taichi_FIND_COMPONENTS) AND (NOT TARGET taichi::runtime))
if(taichi_FOUND)
if(NOT TARGET taichi_c_api)
message(FATAL_ERROR "taichi is marked found but target taichi_c_api doesn't exists")
endif()

# Already found in config mode.
get_target_property(taichi_runtime_CONFIG taichi_c_api IMPORTED_CONFIGURATIONS)
if(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
get_target_property(taichi_runtime_LIBRARY taichi_c_api IMPORTED_IMPLIB_${taichi_runtime_CONFIG})
get_target_property(taichi_runtime_REDIST_LIBRARY taichi_c_api IMPORTED_LOCATION_${taichi_runtime_CONFIG})
else()
get_target_property(taichi_runtime_LIBRARY taichi_c_api IMPORTED_LOCATION_${taichi_runtime_CONFIG})
get_target_property(taichi_runtime_REDIST_LIBRARY taichi_c_api IMPORTED_LOCATION_${taichi_runtime_CONFIG})
endif()
get_target_property(taichi_runtime_INCLUDE_DIR taichi_c_api INTERFACE_INCLUDE_DIRECTORIES)
else()
find_library(taichi_runtime_LIBRARY
NAMES taichi_runtime taichi_c_api
HINTS ${TAICHI_C_API_INSTALL_DIR}
PATH_SUFFIXES lib
# CMake find root is overriden by Android toolchain.
NO_CMAKE_FIND_ROOT_PATH)

find_library(taichi_runtime_REDIST_LIBRARY
NAMES taichi_runtime taichi_c_api
HINTS ${TAICHI_C_API_INSTALL_DIR}
PATH_SUFFIXES bin lib
# CMake find root is overriden by Android toolchain.
NO_CMAKE_FIND_ROOT_PATH)

find_path(taichi_runtime_INCLUDE_DIR
NAMES taichi/taichi.h
HINTS ${TAICHI_C_API_INSTALL_DIR}
PATH_SUFFIXES include
NO_CMAKE_FIND_ROOT_PATH)
endif()

# Capture Taichi Runtime version from header definition.
file(READ "${taichi_runtime_INCLUDE_DIR}/taichi/taichi_core.h" taichi_runtime_VERSION_LITERAL)
string(REGEX MATCH "#define TI_C_API_VERSION ([0-9]+)" taichi_runtime_VERSION_LITERAL ${taichi_runtime_VERSION_LITERAL})
set(taichi_runtime_VERSION_LITERAL ${CMAKE_MATCH_1})
math(EXPR taichi_runtime_VERSION_MAJOR "${taichi_runtime_VERSION_LITERAL} / 1000000")
math(EXPR taichi_runtime_VERSION_MINOR "(${taichi_runtime_VERSION_LITERAL} / 1000) % 1000")
math(EXPR taichi_runtime_VERSION_PATCH "${taichi_runtime_VERSION_LITERAL} % 1000")
set(taichi_runtime_VERSION "${taichi_runtime_VERSION_MAJOR}.${taichi_runtime_VERSION_MINOR}.${taichi_runtime_VERSION_PATCH}")

# Ensure the version string is valid.
if(${taichi_runtime_VERSION} VERSION_GREATER "0")
message("-- Found Taichi Runtime ${taichi_runtime_VERSION}: ${taichi_runtime_LIBRARY}")

add_library(taichi::runtime UNKNOWN IMPORTED)
set_target_properties(taichi::runtime PROPERTIES
IMPORTED_LOCATION "${taichi_runtime_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${taichi_runtime_INCLUDE_DIR}")

list(APPEND COMPONENT_VARS
taichi_runtime_LIBRARY
taichi_runtime_INCLUDE_DIR)
list(APPEND taichi_LIBRARIES "${taichi_runtime_LIBRARY}")
if(EXISTS ${taichi_runtime_REDIST_LIBRARY})
list(APPEND taichi_REDIST_LIBRARIES ${taichi_runtime_REDIST_LIBRARY})
endif()
list(APPEND taichi_INCLUDE_DIRS "${taichi_runtime_INCLUDE_DIR}")
endif()
endif()

# - [taichi] -------------------------------------------------------------------

set(taichi_VERSION taichi_runtime_VERSION)
set(taichi_FOUND TRUE)

# Handle `QUIET` and `REQUIRED` args in the recommended way in `find_package`.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(taichi DEFAULT_MSG ${COMPONENT_VARS})

cmake_policy(POP)
25 changes: 15 additions & 10 deletions c_api/docs/taichi/taichi_core.h.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ Taichi Core exposes all necessary interfaces for offloading the AOT modules to T

Taichi C-API intends to support the following backends:

|Backend |Offload Target |Maintenance Tier |
|------------|-----------------|-----------------|
|Vulkan |GPU |Tier 1 |
|CUDA (LLVM) |GPU (NVIDIA) |Tier 1 |
|CPU (LLVM) |CPU |Tier 1 |
|OpenGL |GPU |Tier 2 |
|DirectX 11 |GPU (Windows) |N/A |
|Metal |GPU (macOS, iOS) |N/A |
|Backend |Offload Target |Maintenance Tier | Stabilized? |
|------------|-----------------|-----------------|-------------|
|Vulkan |GPU |Tier 1 | Yes |
|Metal |GPU (macOS, iOS) |Tier 2 | No |
|CUDA (LLVM) |GPU (NVIDIA) |Tier 2 | No |
|CPU (LLVM) |CPU |Tier 2 | No |
|OpenGL |GPU |Tier 2 | No |
|OpenGL ES |GPU |Tier 2 | No |
|DirectX 11 |GPU (Windows) |N/A | No |

The backends with tier-1 support are being developed and tested more intensively. And most new features will be available on Vulkan first because it has the most outstanding cross-platform compatibility among all the tier-1 backends.
For the backends with tier-2 support, you should expect a delay in the fixes to minor issues.
Expand Down Expand Up @@ -263,11 +264,13 @@ Errors reported by the Taichi C-API.
Types of backend archs.
- `enumeration.arch.vulkan`: Vulkan GPU backend.
- `enumeration.arch.metal`: Metal GPU backend.
- `enumeration.arch.cuda`: NVIDIA CUDA GPU backend.
- `enumeration.arch.x64`: x64 native CPU backend.
- `enumeration.arch.arm64`: Arm64 native CPU backend.
- `enumeration.arch.cuda`: NVIDIA CUDA GPU backend.
- `enumeration.arch.vulkan`: Vulkan GPU backend.
- `enumeration.arch.opengl`: OpenGL GPU backend.
- `enumeration.arch.gles`: OpenGL ES GPU backend.
`enumeration.capability`
Expand Down Expand Up @@ -466,6 +469,8 @@ Gets a list of available archs on the current platform. An arch is only availabl
An available arch has at least one device available, i.e., device index 0 is always available. If an arch is not available on the current platform, a call to `function.create_runtime` with that arch is guaranteed failing.
**WARNING** Please also note that the order or returned archs is *undefined*.
`function.get_last_error`
Gets the last error raised by Taichi C-API invocations. Returns the semantical error code.
Expand Down
13 changes: 13 additions & 0 deletions c_api/include/taichi/cpp/taichi.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// C++ wrapper of Taichi C-API
#pragma once
#include <algorithm>
#include <cstddef>
#include <cstring>
#include <list>
Expand All @@ -18,6 +19,18 @@ inline std::vector<TiArch> get_available_archs() {
ti_get_available_archs(&narch, archs.data());
return archs;
}
inline std::vector<TiArch> get_available_archs(
const std::vector<TiArch> &expect_archs) {
std::vector<TiArch> actual_archs = get_available_archs();
std::vector<TiArch> out_archs;
for (TiArch arch : actual_archs) {
auto it = std::find(expect_archs.begin(), expect_archs.end(), arch);
if (it != expect_archs.end()) {
out_archs.emplace_back(arch);
}
}
return out_archs;
}
inline bool is_arch_available(TiArch arch) {
std::vector<TiArch> archs = get_available_archs();
for (size_t i = 0; i < archs.size(); ++i) {
Expand Down
48 changes: 23 additions & 25 deletions c_api/include/taichi/taichi_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
//
// Taichi C-API intends to support the following backends:
//
// |Backend |Offload Target |Maintenance Tier |
// |------------|-----------------|-----------------|
// |Vulkan |GPU |Tier 1 |
// |CUDA (LLVM) |GPU (NVIDIA) |Tier 1 |
// |CPU (LLVM) |CPU |Tier 1 |
// |OpenGL |GPU |Tier 2 |
// |DirectX 11 |GPU (Windows) |N/A |
// |Metal |GPU (macOS, iOS) |N/A |
// |Backend |Offload Target |Maintenance Tier | Stabilized? |
// |------------|-----------------|-----------------|-------------|
// |Vulkan |GPU |Tier 1 | Yes |
// |Metal |GPU (macOS, iOS) |Tier 2 | No |
// |CUDA (LLVM) |GPU (NVIDIA) |Tier 2 | No |
// |CPU (LLVM) |CPU |Tier 2 | No |
// |OpenGL |GPU |Tier 2 | No |
// |OpenGL ES |GPU |Tier 2 | No |
// |DirectX 11 |GPU (Windows) |N/A | No |
//
// The backends with tier-1 support are being developed and tested more
// intensively. And most new features will be available on Vulkan first because
Expand Down Expand Up @@ -353,25 +354,21 @@ typedef enum TiError {
//
// Types of backend archs.
typedef enum TiArch {
TI_ARCH_RESERVED = 0,
// Vulkan GPU backend.
TI_ARCH_VULKAN = 1,
// Metal GPU backend.
TI_ARCH_METAL = 2,
// NVIDIA CUDA GPU backend.
TI_ARCH_CUDA = 3,
// x64 native CPU backend.
TI_ARCH_X64 = 0,
TI_ARCH_X64 = 4,
// Arm64 native CPU backend.
TI_ARCH_ARM64 = 1,
TI_ARCH_JS = 2,
TI_ARCH_CC = 3,
TI_ARCH_WASM = 4,
// NVIDIA CUDA GPU backend.
TI_ARCH_CUDA = 5,
TI_ARCH_METAL = 6,
TI_ARCH_ARM64 = 5,
// OpenGL GPU backend.
TI_ARCH_OPENGL = 7,
TI_ARCH_DX11 = 8,
TI_ARCH_DX12 = 9,
TI_ARCH_OPENCL = 10,
TI_ARCH_AMDGPU = 11,
// Vulkan GPU backend.
TI_ARCH_VULKAN = 12,
TI_ARCH_GLES = 13,
TI_ARCH_OPENGL = 6,
// OpenGL ES GPU backend.
TI_ARCH_GLES = 7,
TI_ARCH_MAX_ENUM = 0xffffffff,
} TiArch;

Expand Down Expand Up @@ -825,7 +822,8 @@ TI_DLL_EXPORT uint32_t TI_API_CALL ti_get_version();
// An available arch has at least one device available, i.e., device index 0 is
// always available. If an arch is not available on the current platform, a call
// to [`ti_create_runtime`](#function-ti_create_runtime) with that arch is
// guaranteed failing.
// guaranteed failing. Please also note that the order or returned archs is
// **undefined**.
TI_DLL_EXPORT void TI_API_CALL ti_get_available_archs(uint32_t *arch_count,
TiArch *archs);

Expand Down
6 changes: 3 additions & 3 deletions c_api/src/taichi_core_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,6 @@ void ti_get_available_archs(uint32_t *arch_count, TiArch *archs) {
if (is_vulkan_available()) {
AVAILABLE_ARCHS.emplace_back(TI_ARCH_VULKAN);
}
if (is_opengl_available()) {
AVAILABLE_ARCHS.emplace_back(TI_ARCH_OPENGL);
}
if (is_cuda_available()) {
AVAILABLE_ARCHS.emplace_back(TI_ARCH_CUDA);
}
Expand All @@ -167,6 +164,9 @@ void ti_get_available_archs(uint32_t *arch_count, TiArch *archs) {
if (is_arm64_available()) {
AVAILABLE_ARCHS.emplace_back(TI_ARCH_ARM64);
}
if (is_opengl_available()) {
AVAILABLE_ARCHS.emplace_back(TI_ARCH_OPENGL);
}
}

size_t n = std::min((size_t)*arch_count, AVAILABLE_ARCHS.size());
Expand Down
11 changes: 10 additions & 1 deletion c_api/taichi.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,16 @@
"name": "arch",
"type": "enumeration",
"since": "v1.4.0",
"inc_cases": "PER_ARCH"
"cases": {
"reserved": 0,
"vulkan": 1,
"metal": 2,
"cuda": 3,
"x64": 4,
"arm64": 5,
"opengl": 6,
"gles": 7
}
},
{
"name": "capability",
Expand Down
10 changes: 0 additions & 10 deletions c_api/tests/c_api_behavior_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@ TEST_F(CapiTest, TestBehaviorCreateRuntime) {

// Attempt to create runtime for unknown arch.
inner(TI_ARCH_MAX_ENUM);

// Attempt to create runtime for unsupported archs.
inner(TI_ARCH_JS);
inner(TI_ARCH_CC);
inner(TI_ARCH_WASM);
inner(TI_ARCH_METAL);
inner(TI_ARCH_DX11);
inner(TI_ARCH_DX12);
inner(TI_ARCH_OPENCL);
inner(TI_ARCH_AMDGPU);
}

TEST_F(CapiTest, TestBehaviorDestroyRuntime) {
Expand Down
Loading

0 comments on commit f455fbe

Please sign in to comment.