Skip to content

Commit 6aaac55

Browse files
committed
[MLIR][Python] use FetchContent_Declare for nanobind and remove pybind
1 parent 637bfb7 commit 6aaac55

File tree

13 files changed

+103
-1038
lines changed

13 files changed

+103
-1038
lines changed

mlir/cmake/modules/AddMLIRPython.cmake

Lines changed: 55 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ function(mlir_generate_type_stubs)
123123
"IMPORT_PATHS;DEPENDS_TARGETS;OUTPUTS;DEPENDS_TARGET_SRC_DEPS"
124124
${ARGN})
125125

126-
# for people doing find_package(nanobind)
126+
# for people installing a distro (e.g., pip install) of nanobind
127127
if(EXISTS ${nanobind_DIR}/../src/stubgen.py)
128128
set(NB_STUBGEN "${nanobind_DIR}/../src/stubgen.py")
129129
elseif(EXISTS ${nanobind_DIR}/../stubgen.py)
130130
set(NB_STUBGEN "${nanobind_DIR}/../stubgen.py")
131-
# for people using FetchContent_Declare and FetchContent_MakeAvailable
131+
# for people using nanobind git source tree (e.g., FetchContent_Declare and FetchContent_MakeAvailable)
132132
elseif(EXISTS ${nanobind_SOURCE_DIR}/src/stubgen.py)
133133
set(NB_STUBGEN "${nanobind_SOURCE_DIR}/src/stubgen.py")
134134
elseif(EXISTS ${nanobind_SOURCE_DIR}/stubgen.py)
@@ -203,11 +203,10 @@ endfunction()
203203
# EMBED_CAPI_LINK_LIBS: Dependent CAPI libraries that this extension depends
204204
# on. These will be collected for all extensions and put into an
205205
# aggregate dylib that is linked against.
206-
# PYTHON_BINDINGS_LIBRARY: Either pybind11 or nanobind.
207206
function(declare_mlir_python_extension name)
208207
cmake_parse_arguments(ARG
209208
""
210-
"ROOT_DIR;MODULE_NAME;ADD_TO_PARENT;PYTHON_BINDINGS_LIBRARY"
209+
"ROOT_DIR;MODULE_NAME;ADD_TO_PARENT"
211210
"SOURCES;PRIVATE_LINK_LIBS;EMBED_CAPI_LINK_LIBS"
212211
${ARGN})
213212

@@ -216,20 +215,15 @@ function(declare_mlir_python_extension name)
216215
endif()
217216
set(_install_destination "src/python/${name}")
218217

219-
if(NOT ARG_PYTHON_BINDINGS_LIBRARY)
220-
set(ARG_PYTHON_BINDINGS_LIBRARY "pybind11")
221-
endif()
222-
223218
add_library(${name} INTERFACE)
224219
set_target_properties(${name} PROPERTIES
225220
# Yes: Leading-lowercase property names are load bearing and the recommended
226221
# way to do this: https://gitlab.kitware.com/cmake/cmake/-/issues/19261
227-
EXPORT_PROPERTIES "mlir_python_SOURCES_TYPE;mlir_python_EXTENSION_MODULE_NAME;mlir_python_EMBED_CAPI_LINK_LIBS;mlir_python_DEPENDS;mlir_python_BINDINGS_LIBRARY"
222+
EXPORT_PROPERTIES "mlir_python_SOURCES_TYPE;mlir_python_EXTENSION_MODULE_NAME;mlir_python_EMBED_CAPI_LINK_LIBS;mlir_python_DEPENDS"
228223
mlir_python_SOURCES_TYPE extension
229224
mlir_python_EXTENSION_MODULE_NAME "${ARG_MODULE_NAME}"
230225
mlir_python_EMBED_CAPI_LINK_LIBS "${ARG_EMBED_CAPI_LINK_LIBS}"
231226
mlir_python_DEPENDS ""
232-
mlir_python_BINDINGS_LIBRARY "${ARG_PYTHON_BINDINGS_LIBRARY}"
233227
)
234228

235229
# Set the interface source and link_libs properties of the target
@@ -318,14 +312,12 @@ function(add_mlir_python_modules name)
318312
elseif(_source_type STREQUAL "extension")
319313
# Native CPP extension.
320314
get_target_property(_module_name ${sources_target} mlir_python_EXTENSION_MODULE_NAME)
321-
get_target_property(_bindings_library ${sources_target} mlir_python_BINDINGS_LIBRARY)
322315
# Transform relative source to based on root dir.
323316
set(_extension_target "${modules_target}.extension.${_module_name}.dso")
324317
add_mlir_python_extension(${_extension_target} "${_module_name}"
325318
INSTALL_COMPONENT ${modules_target}
326319
INSTALL_DIR "${ARG_INSTALL_PREFIX}/_mlir_libs"
327320
OUTPUT_DIRECTORY "${ARG_ROOT_PREFIX}/_mlir_libs"
328-
PYTHON_BINDINGS_LIBRARY ${_bindings_library}
329321
LINK_LIBS PRIVATE
330322
${sources_target}
331323
${ARG_COMMON_CAPI_LINK_LIBS}
@@ -730,78 +722,69 @@ endfunction()
730722
function(add_mlir_python_extension libname extname)
731723
cmake_parse_arguments(ARG
732724
""
733-
"INSTALL_COMPONENT;INSTALL_DIR;OUTPUT_DIRECTORY;PYTHON_BINDINGS_LIBRARY"
725+
"INSTALL_COMPONENT;INSTALL_DIR;OUTPUT_DIRECTORY"
734726
"SOURCES;LINK_LIBS"
735727
${ARGN})
736728
if(ARG_UNPARSED_ARGUMENTS)
737729
message(FATAL_ERROR "Unhandled arguments to add_mlir_python_extension(${libname}, ... : ${ARG_UNPARSED_ARGUMENTS}")
738730
endif()
739731

740732
# The extension itself must be compiled with RTTI and exceptions enabled.
741-
# Also, some warning classes triggered by pybind11 are disabled.
733+
# Also, some warning classes triggered by nanobind are disabled.
742734
set(eh_rtti_enable)
743735
if (MSVC)
744736
set(eh_rtti_enable /EHsc /GR)
745737
elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL)
746738
set(eh_rtti_enable -frtti -fexceptions)
747739
endif ()
748740

749-
# The actual extension library produces a shared-object or DLL and has
750-
# sources that must be compiled in accordance with pybind11 needs (RTTI and
751-
# exceptions).
752-
if(NOT DEFINED ARG_PYTHON_BINDINGS_LIBRARY OR ARG_PYTHON_BINDINGS_LIBRARY STREQUAL "pybind11")
753-
pybind11_add_module(${libname}
754-
${ARG_SOURCES}
755-
)
756-
elseif(ARG_PYTHON_BINDINGS_LIBRARY STREQUAL "nanobind")
757-
nanobind_add_module(${libname}
758-
NB_DOMAIN ${MLIR_BINDINGS_PYTHON_NB_DOMAIN}
759-
FREE_THREADED
760-
${ARG_SOURCES}
761-
)
741+
nanobind_add_module(${libname}
742+
NB_DOMAIN ${MLIR_BINDINGS_PYTHON_NB_DOMAIN}
743+
FREE_THREADED
744+
${ARG_SOURCES}
745+
)
762746

763-
if (NOT MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES
764-
AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL))
765-
# Avoid some warnings from upstream nanobind.
766-
# If a superproject set MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES, let
767-
# the super project handle compile options as it wishes.
768-
get_property(NB_LIBRARY_TARGET_NAME TARGET ${libname} PROPERTY LINK_LIBRARIES)
769-
target_compile_options(${NB_LIBRARY_TARGET_NAME}
770-
PRIVATE
771-
-Wall -Wextra -Wpedantic
772-
-Wno-c++98-compat-extra-semi
773-
-Wno-cast-qual
774-
-Wno-covered-switch-default
775-
-Wno-deprecated-literal-operator
776-
-Wno-nested-anon-types
777-
-Wno-unused-parameter
778-
-Wno-zero-length-array
779-
${eh_rtti_enable})
780-
781-
target_compile_options(${libname}
782-
PRIVATE
783-
-Wall -Wextra -Wpedantic
784-
-Wno-c++98-compat-extra-semi
785-
-Wno-cast-qual
786-
-Wno-covered-switch-default
787-
-Wno-deprecated-literal-operator
788-
-Wno-nested-anon-types
789-
-Wno-unused-parameter
790-
-Wno-zero-length-array
791-
${eh_rtti_enable})
792-
endif()
747+
if (NOT MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES
748+
AND (LLVM_COMPILER_IS_GCC_COMPATIBLE OR CLANG_CL))
749+
# Avoid some warnings from upstream nanobind.
750+
# If a superproject set MLIR_DISABLE_CONFIGURE_PYTHON_DEV_PACKAGES, let
751+
# the super project handle compile options as it wishes.
752+
get_property(NB_LIBRARY_TARGET_NAME TARGET ${libname} PROPERTY LINK_LIBRARIES)
753+
target_compile_options(${NB_LIBRARY_TARGET_NAME}
754+
PRIVATE
755+
-Wall -Wextra -Wpedantic
756+
-Wno-c++98-compat-extra-semi
757+
-Wno-cast-qual
758+
-Wno-covered-switch-default
759+
-Wno-deprecated-literal-operator
760+
-Wno-nested-anon-types
761+
-Wno-unused-parameter
762+
-Wno-zero-length-array
763+
${eh_rtti_enable})
764+
765+
target_compile_options(${libname}
766+
PRIVATE
767+
-Wall -Wextra -Wpedantic
768+
-Wno-c++98-compat-extra-semi
769+
-Wno-cast-qual
770+
-Wno-covered-switch-default
771+
-Wno-deprecated-literal-operator
772+
-Wno-nested-anon-types
773+
-Wno-unused-parameter
774+
-Wno-zero-length-array
775+
${eh_rtti_enable})
776+
endif()
793777

794-
if(APPLE)
795-
# NanobindAdaptors.h uses PyClassMethod_New to build `pure_subclass`es but nanobind
796-
# doesn't declare this API as undefined in its linker flags. So we need to declare it as such
797-
# for downstream users that do not do something like `-undefined dynamic_lookup`.
798-
# Same for the rest.
799-
target_link_options(${libname} PUBLIC
800-
"LINKER:-U,_PyClassMethod_New"
801-
"LINKER:-U,_PyCode_Addr2Location"
802-
"LINKER:-U,_PyFrame_GetLasti"
803-
)
804-
endif()
778+
if(APPLE)
779+
# NanobindAdaptors.h uses PyClassMethod_New to build `pure_subclass`es but nanobind
780+
# doesn't declare this API as undefined in its linker flags. So we need to declare it as such
781+
# for downstream users that do not do something like `-undefined dynamic_lookup`.
782+
# Same for the rest.
783+
target_link_options(${libname} PUBLIC
784+
"LINKER:-U,_PyClassMethod_New"
785+
"LINKER:-U,_PyCode_Addr2Location"
786+
"LINKER:-U,_PyFrame_GetLasti"
787+
)
805788
endif()
806789

807790
target_compile_options(${libname} PRIVATE ${eh_rtti_enable})
@@ -839,11 +822,11 @@ function(add_mlir_python_extension libname extname)
839822
if(WIN32)
840823
# On Windows, pyconfig.h (and by extension python.h) hardcode the version of the
841824
# python library which will be used for linkage depending on the flavor of the build.
842-
# pybind11 has a workaround which depends on the definition of Py_DEBUG (if Py_DEBUG
843-
# is not passed in as a compile definition, pybind11 undefs _DEBUG when including
825+
# nanobind has a workaround which depends on the definition of Py_DEBUG (if Py_DEBUG
826+
# is not passed in as a compile definition, nanobind undefs _DEBUG when including
844827
# python.h, so that the release python library would be used).
845-
# Since mlir uses pybind11, we can leverage their workaround by never directly
846-
# pyconfig.h or python.h and instead relying on the pybind11 headers to include the
828+
# Since mlir uses nanobind, we can leverage their workaround by never directly
829+
# pyconfig.h or python.h and instead relying on the nanobind headers to include the
847830
# necessary python headers. This results in mlir always linking against the
848831
# release python library via the (undocumented) cmake property Python3_LIBRARY_RELEASE.
849832
target_link_libraries(${libname} PRIVATE ${Python3_LIBRARY_RELEASE})

mlir/cmake/modules/MLIRDetectPythonEnv.cmake

Lines changed: 14 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ macro(mlir_configure_python_dev_packages)
2121

2222
find_package(Python3 ${LLVM_MINIMUM_PYTHON_VERSION}
2323
COMPONENTS Interpreter ${_python_development_component} REQUIRED)
24+
message(STATUS "Python extension suffix for modules: '${PYTHON_MODULE_EXTENSION}'")
2425

2526
# We look for both Python3 and Python, the search algorithm should be
2627
# consistent, otherwise disastrous result is almost guaranteed.
@@ -46,81 +47,19 @@ macro(mlir_configure_python_dev_packages)
4647
message(STATUS "Found python include dirs: ${Python3_INCLUDE_DIRS}")
4748
message(STATUS "Found python libraries: ${Python3_LIBRARIES}")
4849
message(STATUS "Found numpy v${Python3_NumPy_VERSION}: ${Python3_NumPy_INCLUDE_DIRS}")
49-
mlir_detect_pybind11_install()
50-
find_package(pybind11 2.10 CONFIG REQUIRED)
51-
message(STATUS "Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIR}")
52-
message(STATUS "Python prefix = '${PYTHON_MODULE_PREFIX}', "
53-
"suffix = '${PYTHON_MODULE_SUFFIX}', "
54-
"extension = '${PYTHON_MODULE_EXTENSION}")
55-
56-
mlir_detect_nanobind_install()
50+
if(nanobind_DIR)
51+
message(STATUS "Using explicit nanobind cmake directory: ${nanobind_DIR} (-Dnanobind_DIR to change)")
52+
else()
53+
include(FetchContent)
54+
FetchContent_Declare(
55+
nanobind
56+
URL https://github.com/wjakob/nanobind/archive/refs/tags/v2.9.0.tar.gz
57+
URL_HASH MD5=df0e9de9d5fd817df264584be4917fd0
58+
OVERRIDE_FIND_PACKAGE
59+
)
60+
FetchContent_MakeAvailable(nanobind)
61+
endif()
5762
find_package(nanobind 2.9 CONFIG REQUIRED)
58-
message(STATUS "Found nanobind v${nanobind_VERSION}: ${nanobind_INCLUDE_DIR}")
59-
message(STATUS "Python prefix = '${PYTHON_MODULE_PREFIX}', "
60-
"suffix = '${PYTHON_MODULE_SUFFIX}', "
61-
"extension = '${PYTHON_MODULE_EXTENSION}")
63+
message(STATUS "Found nanobind: ${NB_DIR}")
6264
endif()
6365
endmacro()
64-
65-
# Detects a pybind11 package installed in the current python environment
66-
# and sets variables to allow it to be found. This allows pybind11 to be
67-
# installed via pip, which typically yields a much more recent version than
68-
# the OS install, which will be available otherwise.
69-
function(mlir_detect_pybind11_install)
70-
if(pybind11_DIR)
71-
message(STATUS "Using explicit pybind11 cmake directory: ${pybind11_DIR} (-Dpybind11_DIR to change)")
72-
else()
73-
message(STATUS "Checking for pybind11 in python path...")
74-
execute_process(
75-
COMMAND "${Python3_EXECUTABLE}"
76-
-c "import pybind11;print(pybind11.get_cmake_dir(), end='')"
77-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
78-
RESULT_VARIABLE STATUS
79-
OUTPUT_VARIABLE PACKAGE_DIR
80-
ERROR_QUIET)
81-
if(NOT STATUS EQUAL "0")
82-
message(STATUS "not found (install via 'pip install pybind11' or set pybind11_DIR)")
83-
return()
84-
endif()
85-
message(STATUS "found (${PACKAGE_DIR})")
86-
set(pybind11_DIR "${PACKAGE_DIR}" PARENT_SCOPE)
87-
endif()
88-
endfunction()
89-
90-
91-
# Detects a nanobind package installed in the current python environment
92-
# and sets variables to allow it to be found. This allows nanobind to be
93-
# installed via pip, which typically yields a much more recent version than
94-
# the OS install, which will be available otherwise.
95-
function(mlir_detect_nanobind_install)
96-
if(nanobind_DIR)
97-
message(STATUS "Using explicit nanobind cmake directory: ${nanobind_DIR} (-Dnanobind_DIR to change)")
98-
else()
99-
message(STATUS "Checking for nanobind in python path...")
100-
execute_process(
101-
COMMAND "${Python3_EXECUTABLE}"
102-
-c "import nanobind;print(nanobind.cmake_dir(), end='')"
103-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
104-
RESULT_VARIABLE STATUS
105-
OUTPUT_VARIABLE PACKAGE_DIR
106-
ERROR_QUIET)
107-
if(NOT STATUS EQUAL "0")
108-
message(STATUS "not found (install via 'pip install nanobind' or set nanobind_DIR)")
109-
return()
110-
endif()
111-
message(STATUS "found (${PACKAGE_DIR})")
112-
set(nanobind_DIR "${PACKAGE_DIR}" PARENT_SCOPE)
113-
execute_process(
114-
COMMAND "${Python3_EXECUTABLE}"
115-
-c "import nanobind;print(nanobind.include_dir(), end='')"
116-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
117-
RESULT_VARIABLE STATUS
118-
OUTPUT_VARIABLE PACKAGE_DIR
119-
ERROR_QUIET)
120-
if(NOT STATUS EQUAL "0")
121-
message(STATUS "not found (install via 'pip install nanobind' or set nanobind_DIR)")
122-
return()
123-
endif()
124-
set(nanobind_INCLUDE_DIR "${PACKAGE_DIR}" PARENT_SCOPE)
125-
endif()
126-
endfunction()

mlir/examples/standalone/python/CMakeLists.txt

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,10 @@ declare_mlir_dialect_python_bindings(
1616
ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/mlir_standalone"
1717
TD_FILE dialects/StandaloneOps.td
1818
SOURCES
19-
dialects/standalone_pybind11.py
2019
dialects/standalone_nanobind.py
2120
_mlir_libs/_standaloneDialectsNanobind/py.typed
2221
DIALECT_NAME standalone)
2322

24-
25-
declare_mlir_python_extension(StandalonePythonSources.Pybind11Extension
26-
MODULE_NAME _standaloneDialectsPybind11
27-
ADD_TO_PARENT StandalonePythonSources
28-
SOURCES
29-
StandaloneExtensionPybind11.cpp
30-
PRIVATE_LINK_LIBS
31-
LLVMSupport
32-
EMBED_CAPI_LINK_LIBS
33-
MLIRCAPIIR
34-
MLIRCAPIArith
35-
MLIRCAPITransforms
36-
StandaloneCAPI
37-
PYTHON_BINDINGS_LIBRARY pybind11
38-
)
39-
4023
declare_mlir_python_extension(StandalonePythonSources.NanobindExtension
4124
MODULE_NAME _standaloneDialectsNanobind
4225
ADD_TO_PARENT StandalonePythonSources
@@ -49,7 +32,6 @@ declare_mlir_python_extension(StandalonePythonSources.NanobindExtension
4932
MLIRCAPIArith
5033
MLIRCAPITransforms
5134
StandaloneCAPI
52-
PYTHON_BINDINGS_LIBRARY nanobind
5335
)
5436

5537

mlir/examples/standalone/python/StandaloneExtensionPybind11.cpp

Lines changed: 0 additions & 38 deletions
This file was deleted.

mlir/examples/standalone/python/mlir_standalone/dialects/standalone_pybind11.py

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)