Skip to content

Commit f88c855

Browse files
authored
[FFI][REFACTOR] Establish tvm_ffi python module (apache#18226)
* [FFI][REFACTOR] Establish tvm_ffi as a standalone python module This PR establishes tvm_ffi as a standalone python module. The ffi is structured as a minimal pip module that can be directly install by path or url. examples/get_started provided a minimal example. This is a major change as we are decoupling tvm_ffi as a separate package, users need to install tvm_ffi separately. Thanks to its minimal dependency, tvm_ffi can be easily installed even just from the source by pip install ./ffi This change would enable future improvement for library plugins to have lightweight dependencies by just working on top of the tvm_ffi, while the main compiler toolchain and runtime can be layered on top. * [FFI] Improve traceback setups This PR improves traceback related setups
1 parent aafb2a0 commit f88c855

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+6015
-189
lines changed

.clang-format

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Run the following command to reformat a file:
2+
# clang-format -i -style=Google <file>
3+
# Or use clang-format-diff to only reformat the changed lines:
4+
# https://clang.llvm.org/docs/ClangFormat.html
5+
BasedOnStyle: Google
6+
DerivePointerAlignment: false
7+
ColumnLimit: 100
8+
PointerAlignment: Left

3rdparty/libbacktrace

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 08f7c7e69f8ea61a0c4151359bc8023be8e9217b

CMakeLists.txt

Lines changed: 153 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,40 +14,42 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17-
18-
cmake_minimum_required(VERSION 3.14)
17+
cmake_minimum_required(VERSION 3.18)
1918

2019
project(
2120
tvm_ffi
22-
VERSION 1.0
23-
DESCRIPTION "TVM's FFI system"
2421
LANGUAGES CXX C
2522
)
2623

27-
option(TVM_FFI_BUILD_TESTS "Adding test targets." OFF)
2824
option(TVM_FFI_USE_LIBBACKTRACE "Enable libbacktrace" ON)
2925
option(TVM_FFI_USE_EXTRA_CXX_API "Enable extra CXX API in shared lib" ON)
3026
option(TVM_FFI_BACKTRACE_ON_SEGFAULT "Set signal handler to print traceback on segfault" ON)
3127

32-
include(cmake/Utils/CxxWarning.cmake)
33-
include(cmake/Utils/Sanitizer.cmake)
34-
include(cmake/Utils/Library.cmake)
3528
if (TVM_FFI_USE_LIBBACKTRACE)
36-
include(cmake/Utils/AddLibbacktrace.cmake)
29+
include(${CMAKE_CURRENT_LIST_DIR}/cmake/Utils/AddLibbacktrace.cmake)
3730
endif()
3831

39-
########## Target: `dlpack_header` ##########
32+
include(${CMAKE_CURRENT_LIST_DIR}/cmake/Utils/Library.cmake)
4033

41-
add_library(dlpack_header INTERFACE)
42-
target_include_directories(dlpack_header INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/dlpack/include")
4334

4435
########## Target: `tvm_ffi_header` ##########
4536

37+
# they can be used in cases where user do not want to link into the library
38+
# in cases like deferred linking
4639
add_library(tvm_ffi_header INTERFACE)
47-
target_include_directories(tvm_ffi_header INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
48-
target_link_libraries(tvm_ffi_header INTERFACE dlpack_header)
40+
target_compile_features(tvm_ffi_header INTERFACE cxx_std_17)
41+
target_include_directories(
42+
tvm_ffi_header INTERFACE
43+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
44+
$<INSTALL_INTERFACE:include>
45+
)
46+
target_include_directories(
47+
tvm_ffi_header INTERFACE
48+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/dlpack/include>
49+
$<INSTALL_INTERFACE:include>
50+
)
4951

50-
########## Target: `tvm_ffi` ##########
52+
########## Target: `tvm_ffi_objs` ##########
5153

5254
set(tvm_ffi_objs_sources
5355
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/traceback.cc"
@@ -60,39 +62,40 @@ set(tvm_ffi_objs_sources
6062
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/container.cc"
6163
)
6264

65+
set(tvm_ffi_extra_objs_sources
66+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/structural_equal.cc"
67+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/structural_hash.cc"
68+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/json_parser.cc"
69+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/json_writer.cc"
70+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/serialization.cc"
71+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/reflection_extra.cc"
72+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/module.cc"
73+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module.cc"
74+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module_system_lib.cc"
75+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module_dynamic_lib.cc"
76+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/stream_context.cc"
77+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/env_c_api.cc"
78+
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/testing.cc"
79+
)
6380
if (TVM_FFI_USE_EXTRA_CXX_API)
64-
list(APPEND tvm_ffi_objs_sources
65-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/structural_equal.cc"
66-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/structural_hash.cc"
67-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/json_parser.cc"
68-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/json_writer.cc"
69-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/serialization.cc"
70-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/reflection_extra.cc"
71-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/module.cc"
72-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module.cc"
73-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module_system_lib.cc"
74-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module_dynamic_lib.cc"
75-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/stream_context.cc"
76-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/env_c_api.cc"
77-
"${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/testing.cc"
78-
)
81+
list(APPEND tvm_ffi_objs_sources ${tvm_ffi_extra_objs_sources})
7982
endif()
8083

8184
add_library(tvm_ffi_objs OBJECT ${tvm_ffi_objs_sources})
85+
target_compile_features(tvm_ffi_objs PRIVATE cxx_std_17)
8286

8387
set_target_properties(
8488
tvm_ffi_objs PROPERTIES
8589
POSITION_INDEPENDENT_CODE ON
86-
CXX_STANDARD 17
8790
CXX_EXTENSIONS OFF
8891
CXX_STANDARD_REQUIRED ON
8992
CXX_VISIBILITY_PRESET hidden
9093
VISIBILITY_INLINES_HIDDEN ON
9194
PREFIX "lib"
9295
)
93-
add_cxx_warning(tvm_ffi_objs)
94-
target_link_libraries(tvm_ffi_objs PRIVATE dlpack_header)
95-
target_include_directories(tvm_ffi_objs PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
96+
97+
# add the include path as public so they are visible to downstreams
98+
target_link_libraries(tvm_ffi_objs PUBLIC tvm_ffi_header)
9699

97100
if (TVM_FFI_USE_LIBBACKTRACE)
98101
message(STATUS "Setting C++ macro TVM_FFI_USE_LIBBACKTRACE - 1")
@@ -110,7 +113,8 @@ else()
110113
target_compile_definitions(tvm_ffi_objs PRIVATE TVM_FFI_BACKTRACE_ON_SEGFAULT=0)
111114
endif()
112115

113-
add_target_from_obj(tvm_ffi tvm_ffi_objs)
116+
tvm_ffi_add_msvc_flags(tvm_ffi_objs)
117+
tvm_ffi_add_target_from_obj(tvm_ffi tvm_ffi_objs)
114118

115119
if (TARGET libbacktrace)
116120
target_link_libraries(tvm_ffi_objs PRIVATE libbacktrace)
@@ -122,24 +126,127 @@ if (MSVC)
122126
target_link_libraries(tvm_ffi_objs PRIVATE DbgHelp.lib)
123127
target_link_libraries(tvm_ffi_shared PRIVATE DbgHelp.lib)
124128
target_link_libraries(tvm_ffi_static PRIVATE DbgHelp.lib)
129+
# produce pdb file
130+
target_link_options(tvm_ffi_shared PRIVATE /DEBUG)
125131
endif ()
126132

133+
# expose the headers as public dependencies
127134
target_link_libraries(tvm_ffi_objs PUBLIC tvm_ffi_header)
128135
target_link_libraries(tvm_ffi_shared PUBLIC tvm_ffi_header)
129136
target_link_libraries(tvm_ffi_static PUBLIC tvm_ffi_header)
130137

131-
install(TARGETS tvm_ffi_static DESTINATION lib${LIB_SUFFIX})
132-
install(TARGETS tvm_ffi_shared DESTINATION lib${LIB_SUFFIX})
138+
#----------------------------------------------------------------------------
139+
# The following code section only is triggered when the project is the root
140+
# and will be skipped when the project is a subproject.
141+
#----------------------------------------------------------------------------
142+
if (NOT ${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
143+
return()
144+
endif()
145+
146+
option(TVM_FFI_ATTACH_DEBUG_SYMBOLS "Attach debug symbols even in release mode" OFF)
147+
option(TVM_FFI_BUILD_TESTS "Adding test targets." OFF)
148+
149+
if (TVM_FFI_ATTACH_DEBUG_SYMBOLS)
150+
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
151+
target_compile_options(tvm_ffi_objs PRIVATE -g1)
152+
endif()
153+
endif()
154+
155+
include(cmake/Utils/CxxWarning.cmake)
156+
include(cmake/Utils/Sanitizer.cmake)
157+
158+
# remap the file name to the source directory so we can see the
159+
# exact file name in traceback relative to the project source root
160+
tvm_ffi_add_prefix_map(tvm_ffi_objs ${CMAKE_SOURCE_DIR})
133161

134-
add_msvc_flags(tvm_ffi_objs)
162+
########## Adding cpp tests ##########
135163

136-
########## Adding tests ##########
164+
# logics below are only executed when the project is the root project.
165+
# but not when the project is a subproject.
166+
if (TVM_FFI_BUILD_TESTS)
167+
enable_testing()
168+
message(STATUS "Enable Testing")
169+
include(cmake/Utils/AddGoogleTest.cmake)
170+
add_subdirectory(tests/cpp/)
171+
tvm_ffi_add_cxx_warning(tvm_ffi_objs)
172+
endif()
137173

138-
if (${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
139-
if (TVM_FFI_BUILD_TESTS)
140-
enable_testing()
141-
message(STATUS "Enable Testing")
142-
include(cmake/Utils/AddGoogleTest.cmake)
143-
add_subdirectory(tests/cpp/)
174+
########## Adding python module ##########
175+
option(TVM_FFI_BUILD_PYTHON_MODULE "Adding python module." OFF)
176+
177+
if (TVM_FFI_BUILD_PYTHON_MODULE)
178+
# Helper function to build the cython module
179+
message(STATUS "Building cython module..")
180+
find_package(
181+
Python COMPONENTS Interpreter Development.Module Development.SABIModule
182+
REQUIRED)
183+
set(core_cpp ${CMAKE_CURRENT_BINARY_DIR}/core.cpp)
184+
set(core_pyx ${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/core.pyx)
185+
set(cython_sources
186+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/core.pyx
187+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/base.pxi
188+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/device.pxi
189+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/dtype.pxi
190+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/error.pxi
191+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/function.pxi
192+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/ndarray.pxi
193+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/object.pxi
194+
${CMAKE_CURRENT_SOURCE_DIR}/python/tvm_ffi/cython/string.pxi
195+
)
196+
# set working directory to source so we can see the exact file name in traceback
197+
# relatived to the project source root
198+
add_custom_command(
199+
OUTPUT ${core_cpp}
200+
COMMAND ${Python_EXECUTABLE} -m cython --cplus ${core_pyx} -o ${core_cpp}
201+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
202+
COMMENT "Transpiling ${core_pyx} to ${core_cpp}"
203+
DEPENDS ${cython_sources}
204+
VERBATIM
205+
)
206+
if(Python_VERSION VERSION_GREATER_EQUAL "3.12")
207+
# >= Python3.12, use Use_SABI version
208+
Python_add_library(tvm_ffi_cython MODULE "${core_cpp}" USE_SABI 3.12)
209+
set_target_properties(tvm_ffi_cython PROPERTIES OUTPUT_NAME "core")
210+
if(NOT WIN32)
211+
set_target_properties(tvm_ffi_cython PROPERTIES SUFFIX ".abi3.so")
212+
endif()
213+
else()
214+
# before Python3.12, use WITH_SOABI version
215+
Python_add_library(tvm_ffi_cython MODULE "${core_cpp}" WITH_SOABI)
216+
set_target_properties(tvm_ffi_cython PROPERTIES OUTPUT_NAME "core")
144217
endif()
145-
endif ()
218+
target_compile_features(tvm_ffi_cython PRIVATE cxx_std_17)
219+
target_link_libraries(tvm_ffi_cython PRIVATE tvm_ffi_header)
220+
target_link_libraries(tvm_ffi_cython PRIVATE tvm_ffi_shared)
221+
install(TARGETS tvm_ffi_cython DESTINATION .)
222+
223+
########## Installing the source ##########
224+
install(
225+
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/dlpack/include DESTINATION 3rdparty/dlpack/include
226+
)
227+
install(
228+
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/libbacktrace DESTINATION 3rdparty/libbacktrace
229+
PATTERN ".git" EXCLUDE
230+
PATTERN ".git*" EXCLUDE
231+
PATTERN "*.tmp" EXCLUDE
232+
)
233+
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/ DESTINATION src/ffi/)
234+
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Utils/ DESTINATION cmake/Utils/)
235+
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt DESTINATION .)
236+
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tvm_ffi-config.cmake DESTINATION lib/cmake/tvm_ffi/)
237+
endif()
238+
239+
########## Install the related for normal cmake library ##########
240+
241+
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/tvm/ffi/ DESTINATION include/tvm/ffi/)
242+
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/dlpack/include/ DESTINATION include/)
243+
install(TARGETS tvm_ffi_shared DESTINATION lib)
244+
# ship additional dSYM files for debugging symbols on if available
245+
if (APPLE)
246+
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib/ DESTINATION lib FILES_MATCHING PATTERN "*.dSYM")
247+
endif()
248+
249+
if (NOT TVM_FFI_BUILD_PYTHON_MODULE)
250+
# when building wheel, we do not ship static as we already ships source and dll
251+
install(TARGETS tvm_ffi_static DESTINATION lib)
252+
endif()

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!--- Licensed to the Apache Software Foundation (ASF) under one -->
2+
<!--- or more contributor license agreements. See the NOTICE file -->
3+
<!--- distributed with this work for additional information -->
4+
<!--- regarding copyright ownership. The ASF licenses this file -->
5+
<!--- to you under the Apache License, Version 2.0 (the -->
6+
<!--- "License"); you may not use this file except in compliance -->
7+
<!--- with the License. You may obtain a copy of the License at -->
8+
9+
<!--- http://www.apache.org/licenses/LICENSE-2.0 -->
10+
11+
<!--- Unless required by applicable law or agreed to in writing, -->
12+
<!--- software distributed under the License is distributed on an -->
13+
<!--- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -->
14+
<!--- KIND, either express or implied. See the License for the -->
15+
<!--- specific language governing permissions and limitations -->
16+
<!--- under the License. -->
17+
18+
# tvm ffi

cmake/Utils/AddGoogleTest.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ if (NOT googletest_POPULATED)
4242
)
4343
endif()
4444

45-
macro(add_googletest target_name)
45+
macro(tvm_ffi_add_googletest target_name)
4646
add_test(
4747
NAME ${target_name}
4848
COMMAND ${target_name}

cmake/Utils/AddLibbacktrace.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
include(ExternalProject)
1919

2020
function(_libbacktrace_compile)
21-
set(_libbacktrace_source ${CMAKE_CURRENT_LIST_DIR}/../../../3rdparty/libbacktrace)
21+
set(_libbacktrace_source ${CMAKE_CURRENT_LIST_DIR}/../../3rdparty/libbacktrace)
2222
set(_libbacktrace_prefix ${CMAKE_CURRENT_BINARY_DIR}/libbacktrace)
2323
if(CMAKE_SYSTEM_NAME MATCHES "Darwin" AND (CMAKE_C_COMPILER MATCHES "^/Library" OR CMAKE_C_COMPILER MATCHES "^/Applications"))
2424
set(_cmake_c_compiler "/usr/bin/cc")
@@ -36,6 +36,7 @@ function(_libbacktrace_compile)
3636
SOURCE_DIR ${_libbacktrace_source}
3737
BINARY_DIR ${_libbacktrace_prefix}
3838
CONFIGURE_COMMAND
39+
"sh"
3940
"${_libbacktrace_source}/configure"
4041
"--prefix=${_libbacktrace_prefix}"
4142
--with-pic

cmake/Utils/CxxWarning.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# specific language governing permissions and limitations
1616
# under the License.
1717

18-
function(add_cxx_warning target_name)
18+
function(tvm_ffi_add_cxx_warning target_name)
1919
# GNU, Clang, or AppleClang
2020
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
2121
target_compile_options(${target_name} PRIVATE "-Werror" "-Wall" "-Wextra" "-Wpedantic" "-Wno-unused-parameter")

0 commit comments

Comments
 (0)