Skip to content

Commit 2e7e09e

Browse files
committed
[MLIR][Python] reland stubgen v2
1 parent 3c810b7 commit 2e7e09e

File tree

10 files changed

+159
-2945
lines changed

10 files changed

+159
-2945
lines changed

.ci/all_requirements.txt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,9 @@ ml-dtypes==0.5.1 ; python_version < "3.13" \
194194
--hash=sha256:d13755f8e8445b3870114e5b6240facaa7cb0c3361e54beba3e07fa912a6e12b \
195195
--hash=sha256:fd918d4e6a4e0c110e2e05be7a7814d10dc1b95872accbf6512b80a109b71ae1
196196
# via -r mlir/python/requirements.txt
197-
nanobind==2.7.0 \
198-
--hash=sha256:73b12d0e751d140d6c1bf4b215e18818a8debfdb374f08dc3776ad208d808e74 \
199-
--hash=sha256:f9f1b160580c50dcf37b6495a0fd5ec61dc0d95dae5f8004f87dd9ad7eb46b34
197+
nanobind==2.9.2 \
198+
--hash=sha256:c37957ffd5eac7eda349cff3622ecd32e5ee1244ecc912c99b5bc8188bafd16e \
199+
--hash=sha256:e7608472de99d375759814cab3e2c94aba3f9ec80e62cfef8ced495ca5c27d6e
200200
# via -r mlir/python/requirements.txt
201201
numpy==2.0.2 \
202202
--hash=sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a \
@@ -383,6 +383,10 @@ swig==4.3.1 \
383383
--hash=sha256:efec16327029f682f649a26da726bb0305be8800bd0f1fa3e81bf0769cf5b476 \
384384
--hash=sha256:fc496c0d600cf1bb2d91e28d3d6eae9c4301e5ea7a0dec5a4281b5efed4245a8
385385
# via -r lldb/test/requirements.txt
386+
typing-extensions==4.15.0 \
387+
--hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \
388+
--hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548
389+
# via -r mlir/python/requirements.txt
386390
urllib3==2.5.0 \
387391
--hash=sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760 \
388392
--hash=sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc

mlir/cmake/modules/AddMLIRPython.cmake

Lines changed: 96 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,82 @@ function(declare_mlir_python_sources name)
9999
endif()
100100
endfunction()
101101

102+
# Function: generate_type_stubs
103+
# Turns on automatic type stub generation for extension modules.
104+
# Specifically, performs add_custom_command to run nanobind's stubgen on an extension module.
105+
#
106+
# Arguments:
107+
# MODULE_NAME: The fully-qualified name of the extension module (used for importing in python).
108+
# DEPENDS_TARGETS: List of targets these type stubs depend on being built; usually corresponding to the
109+
# specific extension module (e.g., something like StandalonePythonModules.extension._standaloneDialectsNanobind.dso)
110+
# and the core bindings extension module (e.g., something like StandalonePythonModules.extension._mlir.dso).
111+
# OUTPUT_DIR: The root output directory to emit the type stubs into.
112+
# OUTPUTS: List of expected outputs.
113+
# DEPENDS_TARGET_SRC_DEPS: List of cpp sources for extension library (for generating a DEPFILE).
114+
# IMPORT_PATHS:
115+
# Outputs:
116+
# NB_STUBGEN_CUSTOM_TARGET: The target corresponding to generation which other targets can depend on.
117+
function(generate_type_stubs)
118+
cmake_parse_arguments(ARG
119+
""
120+
"MODULE_NAME;OUTPUT_DIR"
121+
"IMPORT_PATHS;DEPENDS_TARGETS;OUTPUTS;DEPENDS_TARGET_SRC_DEPS"
122+
${ARGN})
123+
124+
# for people doing find_package(nanobind)
125+
if(EXISTS ${nanobind_DIR}/../src/stubgen.py)
126+
set(NB_STUBGEN "${nanobind_DIR}/../src/stubgen.py")
127+
elseif(EXISTS ${nanobind_DIR}/../stubgen.py)
128+
set(NB_STUBGEN "${nanobind_DIR}/../stubgen.py")
129+
# for people using FetchContent_Declare and FetchContent_MakeAvailable
130+
elseif(EXISTS ${nanobind_SOURCE_DIR}/src/stubgen.py)
131+
set(NB_STUBGEN "${nanobind_SOURCE_DIR}/src/stubgen.py")
132+
elseif(EXISTS ${nanobind_SOURCE_DIR}/stubgen.py)
133+
set(NB_STUBGEN "${nanobind_SOURCE_DIR}/stubgen.py")
134+
else()
135+
message(FATAL_ERROR "generate_type_stubs(): could not locate 'stubgen.py'!")
136+
endif()
137+
138+
file(REAL_PATH "${NB_STUBGEN}" NB_STUBGEN)
139+
set(_import_paths)
140+
foreach(_import_path IN LISTS ARG_IMPORT_PATHS)
141+
file(REAL_PATH "${_import_path}" _import_path)
142+
list(APPEND _import_paths "-i;${_import_path}")
143+
endforeach()
144+
set(_nb_stubgen_cmd
145+
"${Python_EXECUTABLE}"
146+
"${NB_STUBGEN}"
147+
--module
148+
"${ARG_MODULE_NAME}"
149+
"${_import_paths}"
150+
--recursive
151+
--include-private
152+
--output-dir
153+
"${ARG_OUTPUT_DIR}")
154+
155+
list(TRANSFORM ARG_OUTPUTS PREPEND "${ARG_OUTPUT_DIR}/" OUTPUT_VARIABLE _generated_type_stubs)
156+
set(_depfile "${ARG_OUTPUT_DIR}/${ARG_MODULE_NAME}.d")
157+
if ((NOT EXISTS ${_depfile}) AND ARG_DEPENDS_TARGET_SRC_DEPS)
158+
list(JOIN ARG_DEPENDS_TARGET_SRC_DEPS " " _depfiles)
159+
list(TRANSFORM _generated_type_stubs APPEND ": ${_depfiles}" OUTPUT_VARIABLE _depfiles)
160+
list(JOIN _depfiles "\n" _depfiles)
161+
file(GENERATE OUTPUT "${_depfile}" CONTENT "${_depfiles}")
162+
endif()
163+
164+
add_custom_command(
165+
OUTPUT ${_generated_type_stubs}
166+
COMMAND ${_nb_stubgen_cmd}
167+
WORKING_DIRECTORY "${CMAKE_CURRENT_FUNCTION_LIST_DIR}"
168+
DEPENDS "${ARG_DEPENDS_TARGETS}"
169+
DEPFILE "${_depfile}"
170+
)
171+
172+
list(JOIN ARG_DEPENDS_TARGETS "." _name)
173+
set(_name "${_name}.${ARG_MODULE_NAME}.type_stubs")
174+
add_custom_target("${_name}" DEPENDS ${_generated_type_stubs})
175+
set(NB_STUBGEN_CUSTOM_TARGET "${_name}" PARENT_SCOPE)
176+
endfunction()
177+
102178
# Function: declare_mlir_python_extension
103179
# Declares a buildable python extension from C++ source files. The built
104180
# module is considered a python source file and included as everything else.
@@ -678,26 +754,28 @@ function(add_mlir_python_extension libname extname)
678754
# the super project handle compile options as it wishes.
679755
get_property(NB_LIBRARY_TARGET_NAME TARGET ${libname} PROPERTY LINK_LIBRARIES)
680756
target_compile_options(${NB_LIBRARY_TARGET_NAME}
681-
PRIVATE
682-
-Wall -Wextra -Wpedantic
683-
-Wno-c++98-compat-extra-semi
684-
-Wno-cast-qual
685-
-Wno-covered-switch-default
686-
-Wno-nested-anon-types
687-
-Wno-unused-parameter
688-
-Wno-zero-length-array
689-
${eh_rtti_enable})
757+
PRIVATE
758+
-Wall -Wextra -Wpedantic
759+
-Wno-c++98-compat-extra-semi
760+
-Wno-cast-qual
761+
-Wno-covered-switch-default
762+
-Wno-deprecated-literal-operator
763+
-Wno-nested-anon-types
764+
-Wno-unused-parameter
765+
-Wno-zero-length-array
766+
${eh_rtti_enable})
690767

691768
target_compile_options(${libname}
692-
PRIVATE
693-
-Wall -Wextra -Wpedantic
694-
-Wno-c++98-compat-extra-semi
695-
-Wno-cast-qual
696-
-Wno-covered-switch-default
697-
-Wno-nested-anon-types
698-
-Wno-unused-parameter
699-
-Wno-zero-length-array
700-
${eh_rtti_enable})
769+
PRIVATE
770+
-Wall -Wextra -Wpedantic
771+
-Wno-c++98-compat-extra-semi
772+
-Wno-cast-qual
773+
-Wno-covered-switch-default
774+
-Wno-deprecated-literal-operator
775+
-Wno-nested-anon-types
776+
-Wno-unused-parameter
777+
-Wno-zero-length-array
778+
${eh_rtti_enable})
701779
endif()
702780

703781
if(APPLE)

mlir/examples/standalone/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ if(MLIR_ENABLE_BINDINGS_PYTHON)
5555
include(MLIRDetectPythonEnv)
5656
mlir_configure_python_dev_packages()
5757
set(MLIR_PYTHON_PACKAGE_PREFIX "mlir_standalone" CACHE STRING "" FORCE)
58-
set(MLIR_BINDINGS_PYTHON_INSTALL_PREFIX "python_packages/standalone/mlir_standalone" CACHE STRING "" FORCE)
58+
set(MLIR_BINDINGS_PYTHON_INSTALL_PREFIX "python_packages/standalone/${MLIR_PYTHON_PACKAGE_PREFIX}" CACHE STRING "" FORCE)
5959
add_subdirectory(python)
6060
endif()
6161
add_subdirectory(test)

mlir/examples/standalone/python/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ add_mlir_python_modules(StandalonePythonModules
7676
MLIRPythonSources.Dialects.builtin
7777
COMMON_CAPI_LINK_LIBS
7878
StandalonePythonCAPI
79-
)
79+
)

mlir/python/CMakeLists.txt

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
include(AddMLIRPython)
22

3+
# Specifies that all MLIR packages are co-located under the `mlir_standalone`
4+
# top level package (the API has been embedded in a relocatable way).
5+
add_compile_definitions("MLIR_PYTHON_PACKAGE_PREFIX=${MLIR_PYTHON_PACKAGE_PREFIX}.")
6+
37
################################################################################
48
# Structural groupings.
59
################################################################################
@@ -23,11 +27,6 @@ declare_mlir_python_sources(MLIRPythonSources.Core.Python
2327
passmanager.py
2428
rewrite.py
2529
dialects/_ods_common.py
26-
27-
# The main _mlir module has submodules: include stubs from each.
28-
_mlir_libs/_mlir/__init__.pyi
29-
_mlir_libs/_mlir/ir.pyi
30-
_mlir_libs/_mlir/passmanager.pyi
3130
)
3231

3332
declare_mlir_python_sources(MLIRPythonSources.Core.Python.Extras
@@ -479,28 +478,30 @@ declare_mlir_dialect_python_bindings(
479478
################################################################################
480479

481480
set(PYTHON_SOURCE_DIR "${MLIR_SOURCE_DIR}/lib/Bindings/Python")
481+
set(MLIRPythonExtension.Core.CPPSources
482+
MainModule.cpp
483+
IRAffine.cpp
484+
IRAttributes.cpp
485+
IRCore.cpp
486+
IRInterfaces.cpp
487+
IRModule.cpp
488+
IRTypes.cpp
489+
Pass.cpp
490+
Rewrite.cpp
491+
492+
# Headers must be included explicitly so they are installed.
493+
Globals.h
494+
IRModule.h
495+
Pass.h
496+
NanobindUtils.h
497+
Rewrite.h
498+
)
482499
declare_mlir_python_extension(MLIRPythonExtension.Core
483500
MODULE_NAME _mlir
484501
ADD_TO_PARENT MLIRPythonSources.Core
485502
ROOT_DIR "${PYTHON_SOURCE_DIR}"
486503
PYTHON_BINDINGS_LIBRARY nanobind
487-
SOURCES
488-
MainModule.cpp
489-
IRAffine.cpp
490-
IRAttributes.cpp
491-
IRCore.cpp
492-
IRInterfaces.cpp
493-
IRModule.cpp
494-
IRTypes.cpp
495-
Pass.cpp
496-
Rewrite.cpp
497-
498-
# Headers must be included explicitly so they are installed.
499-
Globals.h
500-
IRModule.h
501-
Pass.h
502-
NanobindUtils.h
503-
Rewrite.h
504+
SOURCES "${MLIRPythonExtension.Core.CPPSources}"
504505
PRIVATE_LINK_LIBS
505506
LLVMSupport
506507
EMBED_CAPI_LINK_LIBS
@@ -511,6 +512,18 @@ declare_mlir_python_extension(MLIRPythonExtension.Core
511512
# Dialects
512513
MLIRCAPIFunc
513514
)
515+
set(_type_stub_sources
516+
_mlir_libs/_mlir/__init__.pyi
517+
_mlir_libs/_mlir/ir.pyi
518+
_mlir_libs/_mlir/passmanager.pyi
519+
_mlir_libs/_mlir/rewrite.pyi
520+
)
521+
declare_mlir_python_sources(
522+
MLIRPythonExtension.Core.type_stub_gen
523+
ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/type_stubs"
524+
ADD_TO_PARENT MLIRPythonSources.Core
525+
SOURCES "${_type_stub_sources}"
526+
)
514527

515528
# This extension exposes an API to register all dialects, extensions, and passes
516529
# packaged in upstream MLIR and it is used for the upstream "mlir" Python
@@ -663,7 +676,7 @@ if(MLIR_ENABLE_EXECUTION_ENGINE)
663676
MODULE_NAME _mlirExecutionEngine
664677
ADD_TO_PARENT MLIRPythonSources.ExecutionEngine
665678
ROOT_DIR "${PYTHON_SOURCE_DIR}"
666-
PYTHON_BINDINGS_LIBRARY nanobind
679+
PYTHON_BINDINGS_LIBRARY nanobind
667680
SOURCES
668681
ExecutionEngineModule.cpp
669682
PRIVATE_LINK_LIBS
@@ -817,7 +830,7 @@ endif()
817830
add_mlir_python_common_capi_library(MLIRPythonCAPI
818831
INSTALL_COMPONENT MLIRPythonModules
819832
INSTALL_DESTINATION "${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}/_mlir_libs"
820-
OUTPUT_DIRECTORY "${MLIR_BINARY_DIR}/python_packages/mlir_core/mlir/_mlir_libs"
833+
OUTPUT_DIRECTORY "${MLIR_BINARY_DIR}/${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}/_mlir_libs"
821834
RELATIVE_INSTALL_ROOT "../../../.."
822835
DECLARED_HEADERS
823836
MLIRPythonCAPI.HeaderSources
@@ -845,8 +858,9 @@ endif()
845858
# This must come last.
846859
################################################################################
847860

861+
set(MLIRPythonModules_ROOT_PREFIX "${MLIR_BINARY_DIR}/${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}")
848862
add_mlir_python_modules(MLIRPythonModules
849-
ROOT_PREFIX "${MLIR_BINARY_DIR}/python_packages/mlir_core/mlir"
863+
ROOT_PREFIX ${MLIRPythonModules_ROOT_PREFIX}
850864
INSTALL_PREFIX "${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}"
851865
DECLARED_SOURCES
852866
MLIRPythonSources
@@ -855,3 +869,14 @@ add_mlir_python_modules(MLIRPythonModules
855869
COMMON_CAPI_LINK_LIBS
856870
MLIRPythonCAPI
857871
)
872+
list(TRANSFORM _type_stub_sources REPLACE "_mlir_libs/" "")
873+
generate_type_stubs(
874+
MODULE_NAME _mlir_libs._mlir
875+
DEPENDS_TARGETS
876+
MLIRPythonModules.extension._mlir.dso
877+
OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/type_stubs/_mlir_libs"
878+
OUTPUTS "${_type_stub_sources}"
879+
DEPENDS_TARGET_SRC_DEPS "${MLIRPythonExtension.Core.CPPSources}"
880+
IMPORT_PATHS "${MLIRPythonModules_ROOT_PREFIX}"
881+
)
882+
add_dependencies(MLIRPythonModules "${NB_STUBGEN_CUSTOM_TARGET}")

mlir/python/mlir/_mlir_libs/_mlir/__init__.pyi

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

0 commit comments

Comments
 (0)