[llvm-branch-commits] [mlir] Users/makslevental/mlirpythonsupport vis pt3 (PR #173439)
Maksim Levental via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 23 20:38:47 PST 2025
https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/173439
>From 5f4d2cdf5cf3c487ea7537b352166ff0252e9b89 Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Tue, 23 Dec 2025 12:20:34 -0800
Subject: [PATCH 1/3] try MLIR_PYTHON_API_EXPORTED
---
mlir/cmake/modules/AddMLIRPython.cmake | 9 +-
mlir/include/mlir-c/Support.h | 2 +
mlir/include/mlir/Bindings/Python/Globals.h | 4 +-
mlir/include/mlir/Bindings/Python/IRCore.h | 121 +++++++++++---------
mlir/include/mlir/Bindings/Python/IRTypes.h | 3 +-
5 files changed, 75 insertions(+), 64 deletions(-)
diff --git a/mlir/cmake/modules/AddMLIRPython.cmake b/mlir/cmake/modules/AddMLIRPython.cmake
index 0501e0b5e51fe..8ec9304421b54 100644
--- a/mlir/cmake/modules/AddMLIRPython.cmake
+++ b/mlir/cmake/modules/AddMLIRPython.cmake
@@ -854,11 +854,10 @@ function(add_mlir_python_extension libname extname nb_library_target_name)
target_link_options(${libname} PRIVATE "-Wl,-z,undefs")
endif()
nanobind_link_options(${libname})
- target_compile_definitions(${libname} PRIVATE NB_DOMAIN=${MLIR_BINDINGS_PYTHON_NB_DOMAIN})
- set_target_properties(${libname} PROPERTIES
- VISIBILITY_INLINES_HIDDEN OFF
- C_VISIBILITY_PRESET default
- CXX_VISIBILITY_PRESET default
+ target_compile_definitions(${libname}
+ PRIVATE
+ NB_DOMAIN=${MLIR_BINDINGS_PYTHON_NB_DOMAIN}
+ MLIR_CAPI_BUILDING_LIBRARY=1
)
if (MSVC)
set_property(TARGET ${libname} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON)
diff --git a/mlir/include/mlir-c/Support.h b/mlir/include/mlir-c/Support.h
index 78fc94f93439e..6abd8894227c3 100644
--- a/mlir/include/mlir-c/Support.h
+++ b/mlir/include/mlir-c/Support.h
@@ -46,6 +46,8 @@
#define MLIR_CAPI_EXPORTED __attribute__((visibility("default")))
#endif
+#define MLIR_PYTHON_API_EXPORTED MLIR_CAPI_EXPORTED
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index 2184e7e2dc5ca..112c7b9b0547f 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -31,7 +31,7 @@ namespace python {
/// Globals that are always accessible once the extension has been initialized.
/// Methods of this class are thread-safe.
-class PyGlobals {
+class MLIR_PYTHON_API_EXPORTED PyGlobals {
public:
PyGlobals();
~PyGlobals();
@@ -117,7 +117,7 @@ class PyGlobals {
std::optional<nanobind::object>
lookupOperationClass(llvm::StringRef operationName);
- class TracebackLoc {
+ class MLIR_PYTHON_API_EXPORTED TracebackLoc {
public:
bool locTracebacksEnabled();
diff --git a/mlir/include/mlir/Bindings/Python/IRCore.h b/mlir/include/mlir/Bindings/Python/IRCore.h
index 649dfce22ad35..ceedeb691eb58 100644
--- a/mlir/include/mlir/Bindings/Python/IRCore.h
+++ b/mlir/include/mlir/Bindings/Python/IRCore.h
@@ -52,7 +52,7 @@ class PyValue;
/// Template for a reference to a concrete type which captures a python
/// reference to its underlying python object.
template <typename T>
-class PyObjectRef {
+class MLIR_PYTHON_API_EXPORTED PyObjectRef {
public:
PyObjectRef(T *referrent, nanobind::object object)
: referrent(referrent), object(std::move(object)) {
@@ -111,7 +111,7 @@ class PyObjectRef {
/// Context. Pushing a Context will not modify the Location or InsertionPoint
/// unless if they are from a different context, in which case, they are
/// cleared.
-class PyThreadContextEntry {
+class MLIR_PYTHON_API_EXPORTED PyThreadContextEntry {
public:
enum class FrameKind {
Context,
@@ -167,7 +167,7 @@ class PyThreadContextEntry {
/// Wrapper around MlirLlvmThreadPool
/// Python object owns the C++ thread pool
-class PyThreadPool {
+class MLIR_PYTHON_API_EXPORTED PyThreadPool {
public:
PyThreadPool() {
ownedThreadPool = std::make_unique<llvm::DefaultThreadPool>();
@@ -190,7 +190,7 @@ class PyThreadPool {
/// Wrapper around MlirContext.
using PyMlirContextRef = PyObjectRef<PyMlirContext>;
-class PyMlirContext {
+class MLIR_PYTHON_API_EXPORTED PyMlirContext {
public:
PyMlirContext() = delete;
PyMlirContext(MlirContext context);
@@ -271,7 +271,7 @@ class PyMlirContext {
/// Used in function arguments when None should resolve to the current context
/// manager set instance.
-class DefaultingPyMlirContext
+class MLIR_PYTHON_API_EXPORTED DefaultingPyMlirContext
: public Defaulting<DefaultingPyMlirContext, PyMlirContext> {
public:
using Defaulting::Defaulting;
@@ -283,7 +283,7 @@ class DefaultingPyMlirContext
/// MlirContext. The lifetime of the context will extend at least to the
/// lifetime of these instances.
/// Immutable objects that depend on a context extend this directly.
-class BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED BaseContextObject {
public:
BaseContextObject(PyMlirContextRef ref) : contextRef(std::move(ref)) {
assert(this->contextRef &&
@@ -298,7 +298,7 @@ class BaseContextObject {
};
/// Wrapper around an MlirLocation.
-class PyLocation : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyLocation : public BaseContextObject {
public:
PyLocation(PyMlirContextRef contextRef, MlirLocation loc)
: BaseContextObject(std::move(contextRef)), loc(loc) {}
@@ -329,7 +329,7 @@ class PyLocation : public BaseContextObject {
/// are only valid for the duration of a diagnostic callback and attempting
/// to access them outside of that will raise an exception. This applies to
/// nested diagnostics (in the notes) as well.
-class PyDiagnostic {
+class MLIR_PYTHON_API_EXPORTED PyDiagnostic {
public:
PyDiagnostic(MlirDiagnostic diagnostic) : diagnostic(diagnostic) {}
void invalidate();
@@ -379,7 +379,7 @@ class PyDiagnostic {
/// The object may remain live from a Python perspective for an arbitrary time
/// after detachment, but there is nothing the user can do with it (since there
/// is no way to attach an existing handler object).
-class PyDiagnosticHandler {
+class MLIR_PYTHON_API_EXPORTED PyDiagnosticHandler {
public:
PyDiagnosticHandler(MlirContext context, nanobind::object callback);
~PyDiagnosticHandler();
@@ -407,7 +407,7 @@ class PyDiagnosticHandler {
/// RAII object that captures any error diagnostics emitted to the provided
/// context.
-struct PyMlirContext::ErrorCapture {
+struct MLIR_PYTHON_API_EXPORTED PyMlirContext::ErrorCapture {
ErrorCapture(PyMlirContextRef ctx)
: ctx(ctx), handlerID(mlirContextAttachDiagnosticHandler(
ctx->get(), handler, /*userData=*/this,
@@ -434,7 +434,7 @@ struct PyMlirContext::ErrorCapture {
/// plugins which extend dialect functionality through extension python code.
/// This should be seen as the "low-level" object and `Dialect` as the
/// high-level, user facing object.
-class PyDialectDescriptor : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyDialectDescriptor : public BaseContextObject {
public:
PyDialectDescriptor(PyMlirContextRef contextRef, MlirDialect dialect)
: BaseContextObject(std::move(contextRef)), dialect(dialect) {}
@@ -447,7 +447,7 @@ class PyDialectDescriptor : public BaseContextObject {
/// User-level object for accessing dialects with dotted syntax such as:
/// ctx.dialect.std
-class PyDialects : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyDialects : public BaseContextObject {
public:
PyDialects(PyMlirContextRef contextRef)
: BaseContextObject(std::move(contextRef)) {}
@@ -458,7 +458,7 @@ class PyDialects : public BaseContextObject {
/// User-level dialect object. For dialects that have a registered extension,
/// this will be the base class of the extension dialect type. For un-extended,
/// objects of this type will be returned directly.
-class PyDialect {
+class MLIR_PYTHON_API_EXPORTED PyDialect {
public:
PyDialect(nanobind::object descriptor) : descriptor(std::move(descriptor)) {}
@@ -471,7 +471,7 @@ class PyDialect {
/// Wrapper around an MlirDialectRegistry.
/// Upon construction, the Python wrapper takes ownership of the
/// underlying MlirDialectRegistry.
-class PyDialectRegistry {
+class MLIR_PYTHON_API_EXPORTED PyDialectRegistry {
public:
PyDialectRegistry() : registry(mlirDialectRegistryCreate()) {}
PyDialectRegistry(MlirDialectRegistry registry) : registry(registry) {}
@@ -497,7 +497,7 @@ class PyDialectRegistry {
/// Used in function arguments when None should resolve to the current context
/// manager set instance.
-class DefaultingPyLocation
+class MLIR_PYTHON_API_EXPORTED DefaultingPyLocation
: public Defaulting<DefaultingPyLocation, PyLocation> {
public:
using Defaulting::Defaulting;
@@ -511,7 +511,7 @@ class DefaultingPyLocation
/// This is the top-level, user-owned object that contains regions/ops/blocks.
class PyModule;
using PyModuleRef = PyObjectRef<PyModule>;
-class PyModule : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyModule : public BaseContextObject {
public:
/// Returns a PyModule reference for the given MlirModule. This always returns
/// a new object.
@@ -551,7 +551,7 @@ class PyAsmState;
/// Base class for PyOperation and PyOpView which exposes the primary, user
/// visible methods for manipulating it.
-class PyOperationBase {
+class MLIR_PYTHON_API_EXPORTED PyOperationBase {
public:
virtual ~PyOperationBase() = default;
/// Implements the bound 'print' method and helps with others.
@@ -604,7 +604,8 @@ class PyOperationBase {
class PyOperation;
class PyOpView;
using PyOperationRef = PyObjectRef<PyOperation>;
-class PyOperation : public PyOperationBase, public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyOperation : public PyOperationBase,
+ public BaseContextObject {
public:
~PyOperation() override;
PyOperation &getOperation() override { return *this; }
@@ -722,7 +723,7 @@ class PyOperation : public PyOperationBase, public BaseContextObject {
/// custom ODS-style operation classes. Since this class is subclass on the
/// python side, it must present an __init__ method that operates in pure
/// python types.
-class PyOpView : public PyOperationBase {
+class MLIR_PYTHON_API_EXPORTED PyOpView : public PyOperationBase {
public:
PyOpView(const nanobind::object &operationObject);
PyOperation &getOperation() override { return operation; }
@@ -758,7 +759,7 @@ class PyOpView : public PyOperationBase {
/// Wrapper around an MlirRegion.
/// Regions are managed completely by their containing operation. Unlike the
/// C++ API, the python API does not support detached regions.
-class PyRegion {
+class MLIR_PYTHON_API_EXPORTED PyRegion {
public:
PyRegion(PyOperationRef parentOperation, MlirRegion region)
: parentOperation(std::move(parentOperation)), region(region) {
@@ -777,7 +778,7 @@ class PyRegion {
};
/// Wrapper around an MlirAsmState.
-class PyAsmState {
+class MLIR_PYTHON_API_EXPORTED PyAsmState {
public:
PyAsmState(MlirValue value, bool useLocalScope) {
flags = mlirOpPrintingFlagsCreate();
@@ -812,7 +813,7 @@ class PyAsmState {
/// Wrapper around an MlirBlock.
/// Blocks are managed completely by their containing operation. Unlike the
/// C++ API, the python API does not support detached blocks.
-class PyBlock {
+class MLIR_PYTHON_API_EXPORTED PyBlock {
public:
PyBlock(PyOperationRef parentOperation, MlirBlock block)
: parentOperation(std::move(parentOperation)), block(block) {
@@ -836,7 +837,7 @@ class PyBlock {
/// Calls to insert() will insert a new operation before the
/// reference operation. If the reference operation is null, then appends to
/// the end of the block.
-class PyInsertionPoint {
+class MLIR_PYTHON_API_EXPORTED PyInsertionPoint {
public:
/// Creates an insertion point positioned after the last operation in the
/// block, but still inside the block.
@@ -877,7 +878,7 @@ class PyInsertionPoint {
};
/// Wrapper around the generic MlirType.
/// The lifetime of a type is bound by the PyContext that created it.
-class PyType : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyType : public BaseContextObject {
public:
PyType(PyMlirContextRef contextRef, MlirType type)
: BaseContextObject(std::move(contextRef)), type(type) {}
@@ -903,7 +904,7 @@ class PyType : public BaseContextObject {
/// A TypeID provides an efficient and unique identifier for a specific C++
/// type. This allows for a C++ type to be compared, hashed, and stored in an
/// opaque context. This class wraps around the generic MlirTypeID.
-class PyTypeID {
+class MLIR_PYTHON_API_EXPORTED PyTypeID {
public:
PyTypeID(MlirTypeID typeID) : typeID(typeID) {}
// Note, this tests whether the underlying TypeIDs are the same,
@@ -929,7 +930,7 @@ class PyTypeID {
/// concrete type class extends PyType); however, intermediate python-visible
/// base classes can be modeled by specifying a BaseTy.
template <typename DerivedTy, typename BaseTy = PyType>
-class PyConcreteType : public BaseTy {
+class MLIR_PYTHON_API_EXPORTED PyConcreteType : public BaseTy {
public:
// Derived classes must define statics for:
// IsAFunctionTy isaFunction
@@ -1007,7 +1008,7 @@ class PyConcreteType : public BaseTy {
/// Wrapper around the generic MlirAttribute.
/// The lifetime of a type is bound by the PyContext that created it.
-class PyAttribute : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyAttribute : public BaseContextObject {
public:
PyAttribute(PyMlirContextRef contextRef, MlirAttribute attr)
: BaseContextObject(std::move(contextRef)), attr(attr) {}
@@ -1033,7 +1034,7 @@ class PyAttribute : public BaseContextObject {
/// Represents a Python MlirNamedAttr, carrying an optional owned name.
/// TODO: Refactor this and the C-API to be based on an Identifier owned
/// by the context so as to avoid ownership issues here.
-class PyNamedAttribute {
+class MLIR_PYTHON_API_EXPORTED PyNamedAttribute {
public:
/// Constructs a PyNamedAttr that retains an owned name. This should be
/// used in any code that originates an MlirNamedAttribute from a python
@@ -1059,7 +1060,7 @@ class PyNamedAttribute {
/// concrete attribute class extends PyAttribute); however, intermediate
/// python-visible base classes can be modeled by specifying a BaseTy.
template <typename DerivedTy, typename BaseTy = PyAttribute>
-class PyConcreteAttribute : public BaseTy {
+class MLIR_PYTHON_API_EXPORTED PyConcreteAttribute : public BaseTy {
public:
// Derived classes must define statics for:
// IsAFunctionTy isaFunction
@@ -1149,7 +1150,8 @@ class PyConcreteAttribute : public BaseTy {
static void bindDerived(ClassTy &m) {}
};
-class PyStringAttribute : public PyConcreteAttribute<PyStringAttribute> {
+class MLIR_PYTHON_API_EXPORTED PyStringAttribute
+ : public PyConcreteAttribute<PyStringAttribute> {
public:
static constexpr IsAFunctionTy isaFunction = mlirAttributeIsAString;
static constexpr const char *pyClassName = "StringAttr";
@@ -1166,7 +1168,7 @@ class PyStringAttribute : public PyConcreteAttribute<PyStringAttribute> {
/// value. For block argument values, this is the operation that contains the
/// block to which the value is an argument (blocks cannot be detached in Python
/// bindings so such operation always exists).
-class PyValue {
+class MLIR_PYTHON_API_EXPORTED PyValue {
public:
// The virtual here is "load bearing" in that it enables RTTI
// for PyConcreteValue CRTP classes that support maybeDownCast.
@@ -1196,7 +1198,7 @@ class PyValue {
};
/// Wrapper around MlirAffineExpr. Affine expressions are owned by the context.
-class PyAffineExpr : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyAffineExpr : public BaseContextObject {
public:
PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
: BaseContextObject(std::move(contextRef)), affineExpr(affineExpr) {}
@@ -1223,7 +1225,7 @@ class PyAffineExpr : public BaseContextObject {
MlirAffineExpr affineExpr;
};
-class PyAffineMap : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyAffineMap : public BaseContextObject {
public:
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
: BaseContextObject(std::move(contextRef)), affineMap(affineMap) {}
@@ -1244,7 +1246,7 @@ class PyAffineMap : public BaseContextObject {
MlirAffineMap affineMap;
};
-class PyIntegerSet : public BaseContextObject {
+class MLIR_PYTHON_API_EXPORTED PyIntegerSet : public BaseContextObject {
public:
PyIntegerSet(PyMlirContextRef contextRef, MlirIntegerSet integerSet)
: BaseContextObject(std::move(contextRef)), integerSet(integerSet) {}
@@ -1265,7 +1267,7 @@ class PyIntegerSet : public BaseContextObject {
};
/// Bindings for MLIR symbol tables.
-class PySymbolTable {
+class MLIR_PYTHON_API_EXPORTED PySymbolTable {
public:
/// Constructs a symbol table for the given operation.
explicit PySymbolTable(PyOperationBase &operation);
@@ -1317,7 +1319,7 @@ class PySymbolTable {
/// Custom exception that allows access to error diagnostic information. This is
/// converted to the `ir.MLIRError` python exception when thrown.
-struct MLIRError {
+struct MLIR_PYTHON_API_EXPORTED MLIRError {
MLIRError(llvm::Twine message,
std::vector<PyDiagnostic::DiagnosticInfo> &&errorDiagnostics = {})
: message(message.str()), errorDiagnostics(std::move(errorDiagnostics)) {}
@@ -1342,7 +1344,7 @@ inline void registerMLIRError() {
});
}
-void registerMLIRErrorInCore();
+MLIR_PYTHON_API_EXPORTED void registerMLIRErrorInCore();
//------------------------------------------------------------------------------
// Utilities.
@@ -1455,7 +1457,7 @@ inline nanobind::object PyBlock::getCapsule() {
// Collections.
//------------------------------------------------------------------------------
-class PyRegionIterator {
+class MLIR_PYTHON_API_EXPORTED PyRegionIterator {
public:
PyRegionIterator(PyOperationRef operation, int nextIndex)
: operation(std::move(operation)), nextIndex(nextIndex) {}
@@ -1486,7 +1488,8 @@ class PyRegionIterator {
/// Regions of an op are fixed length and indexed numerically so are represented
/// with a sequence-like container.
-class PyRegionList : public Sliceable<PyRegionList, PyRegion> {
+class MLIR_PYTHON_API_EXPORTED PyRegionList
+ : public Sliceable<PyRegionList, PyRegion> {
public:
static constexpr const char *pyClassName = "RegionSequence";
@@ -1529,7 +1532,7 @@ class PyRegionList : public Sliceable<PyRegionList, PyRegion> {
PyOperationRef operation;
};
-class PyBlockIterator {
+class MLIR_PYTHON_API_EXPORTED PyBlockIterator {
public:
PyBlockIterator(PyOperationRef operation, MlirBlock next)
: operation(std::move(operation)), next(next) {}
@@ -1563,7 +1566,7 @@ class PyBlockIterator {
/// Blocks are exposed by the C-API as a forward-only linked list. In Python,
/// we present them as a more full-featured list-like container but optimize
/// it for forward iteration. Blocks are always owned by a region.
-class PyBlockList {
+class MLIR_PYTHON_API_EXPORTED PyBlockList {
public:
PyBlockList(PyOperationRef operation, MlirRegion region)
: operation(std::move(operation)), region(region) {}
@@ -1636,7 +1639,7 @@ class PyBlockList {
MlirRegion region;
};
-class PyOperationIterator {
+class MLIR_PYTHON_API_EXPORTED PyOperationIterator {
public:
PyOperationIterator(PyOperationRef parentOperation, MlirOperation next)
: parentOperation(std::move(parentOperation)), next(next) {}
@@ -1672,7 +1675,7 @@ class PyOperationIterator {
/// Python, we present them as a more full-featured list-like container but
/// optimize it for forward iteration. Iterable operations are always owned
/// by a block.
-class PyOperationList {
+class MLIR_PYTHON_API_EXPORTED PyOperationList {
public:
PyOperationList(PyOperationRef parentOperation, MlirBlock block)
: parentOperation(std::move(parentOperation)), block(block) {}
@@ -1729,7 +1732,7 @@ class PyOperationList {
MlirBlock block;
};
-class PyOpOperand {
+class MLIR_PYTHON_API_EXPORTED PyOpOperand {
public:
PyOpOperand(MlirOpOperand opOperand) : opOperand(opOperand) {}
@@ -1754,7 +1757,7 @@ class PyOpOperand {
MlirOpOperand opOperand;
};
-class PyOpOperandIterator {
+class MLIR_PYTHON_API_EXPORTED PyOpOperandIterator {
public:
PyOpOperandIterator(MlirOpOperand opOperand) : opOperand(opOperand) {}
@@ -1785,7 +1788,7 @@ class PyOpOperandIterator {
/// castable from it. The value hierarchy is one level deep and is not supposed
/// to accommodate other levels unless core MLIR changes.
template <typename DerivedTy>
-class PyConcreteValue : public PyValue {
+class MLIR_PYTHON_API_EXPORTED PyConcreteValue : public PyValue {
public:
// Derived classes must define statics for:
// IsAFunctionTy isaFunction
@@ -1843,7 +1846,7 @@ class PyConcreteValue : public PyValue {
};
/// Python wrapper for MlirOpResult.
-class PyOpResult : public PyConcreteValue<PyOpResult> {
+class MLIR_PYTHON_API_EXPORTED PyOpResult : public PyConcreteValue<PyOpResult> {
public:
static constexpr IsAFunctionTy isaFunction = mlirValueIsAOpResult;
static constexpr const char *pyClassName = "OpResult";
@@ -1887,7 +1890,8 @@ getValueTypes(Container &container, PyMlirContextRef &context) {
/// elements, random access is cheap. The (returned) result list is associated
/// with the operation whose results these are, and thus extends the lifetime of
/// this operation.
-class PyOpResultList : public Sliceable<PyOpResultList, PyOpResult> {
+class MLIR_PYTHON_API_EXPORTED PyOpResultList
+ : public Sliceable<PyOpResultList, PyOpResult> {
public:
static constexpr const char *pyClassName = "OpResultList";
using SliceableT = Sliceable<PyOpResultList, PyOpResult>;
@@ -1940,7 +1944,8 @@ class PyOpResultList : public Sliceable<PyOpResultList, PyOpResult> {
};
/// Python wrapper for MlirBlockArgument.
-class PyBlockArgument : public PyConcreteValue<PyBlockArgument> {
+class MLIR_PYTHON_API_EXPORTED PyBlockArgument
+ : public PyConcreteValue<PyBlockArgument> {
public:
static constexpr IsAFunctionTy isaFunction = mlirValueIsABlockArgument;
static constexpr const char *pyClassName = "BlockArgument";
@@ -1979,7 +1984,7 @@ class PyBlockArgument : public PyConcreteValue<PyBlockArgument> {
/// elements, random access is cheap. The argument list is associated with the
/// operation that contains the block (detached blocks are not allowed in
/// Python bindings) and extends its lifetime.
-class PyBlockArgumentList
+class MLIR_PYTHON_API_EXPORTED PyBlockArgumentList
: public Sliceable<PyBlockArgumentList, PyBlockArgument> {
public:
static constexpr const char *pyClassName = "BlockArgumentList";
@@ -2032,7 +2037,8 @@ class PyBlockArgumentList
/// elements, random access is cheap. The (returned) operand list is associated
/// with the operation whose operands these are, and thus extends the lifetime
/// of this operation.
-class PyOpOperandList : public Sliceable<PyOpOperandList, PyValue> {
+class MLIR_PYTHON_API_EXPORTED PyOpOperandList
+ : public Sliceable<PyOpOperandList, PyValue> {
public:
static constexpr const char *pyClassName = "OpOperandList";
using SliceableT = Sliceable<PyOpOperandList, PyValue>;
@@ -2090,7 +2096,8 @@ class PyOpOperandList : public Sliceable<PyOpOperandList, PyValue> {
/// elements, random access is cheap. The (returned) successor list is
/// associated with the operation whose successors these are, and thus extends
/// the lifetime of this operation.
-class PyOpSuccessors : public Sliceable<PyOpSuccessors, PyBlock> {
+class MLIR_PYTHON_API_EXPORTED PyOpSuccessors
+ : public Sliceable<PyOpSuccessors, PyBlock> {
public:
static constexpr const char *pyClassName = "OpSuccessors";
@@ -2138,7 +2145,8 @@ class PyOpSuccessors : public Sliceable<PyOpSuccessors, PyBlock> {
/// elements, random access is cheap. The (returned) successor list is
/// associated with the operation and block whose successors these are, and thus
/// extends the lifetime of this operation and block.
-class PyBlockSuccessors : public Sliceable<PyBlockSuccessors, PyBlock> {
+class MLIR_PYTHON_API_EXPORTED PyBlockSuccessors
+ : public Sliceable<PyBlockSuccessors, PyBlock> {
public:
static constexpr const char *pyClassName = "BlockSuccessors";
@@ -2180,7 +2188,8 @@ class PyBlockSuccessors : public Sliceable<PyBlockSuccessors, PyBlock> {
/// WARNING: This Sliceable is more expensive than the others here because
/// mlirBlockGetPredecessor actually iterates the use-def chain (of block
/// operands) anew for each indexed access.
-class PyBlockPredecessors : public Sliceable<PyBlockPredecessors, PyBlock> {
+class MLIR_PYTHON_API_EXPORTED PyBlockPredecessors
+ : public Sliceable<PyBlockPredecessors, PyBlock> {
public:
static constexpr const char *pyClassName = "BlockPredecessors";
@@ -2218,7 +2227,7 @@ class PyBlockPredecessors : public Sliceable<PyBlockPredecessors, PyBlock> {
/// A list of operation attributes. Can be indexed by name, producing
/// attributes, or by index, producing named attributes.
-class PyOpAttributeMap {
+class MLIR_PYTHON_API_EXPORTED PyOpAttributeMap {
public:
PyOpAttributeMap(PyOperationRef operation)
: operation(std::move(operation)) {}
@@ -2354,7 +2363,7 @@ class PyOpAttributeMap {
PyOperationRef operation;
};
-MlirValue getUniqueResult(MlirOperation operation);
+MLIR_PYTHON_API_EXPORTED MlirValue getUniqueResult(MlirOperation operation);
} // namespace python
} // namespace mlir
diff --git a/mlir/include/mlir/Bindings/Python/IRTypes.h b/mlir/include/mlir/Bindings/Python/IRTypes.h
index ba9642cf2c6a2..cd0cfbc7d61d8 100644
--- a/mlir/include/mlir/Bindings/Python/IRTypes.h
+++ b/mlir/include/mlir/Bindings/Python/IRTypes.h
@@ -14,7 +14,8 @@
namespace mlir {
/// Shaped Type Interface - ShapedType
-class PyShapedType : public python::PyConcreteType<PyShapedType> {
+class MLIR_PYTHON_API_EXPORTED PyShapedType
+ : public python::PyConcreteType<PyShapedType> {
public:
static const IsAFunctionTy isaFunction;
static constexpr const char *pyClassName = "ShapedType";
>From d9df23fc7a5a5d84cefa5735eb48893dccc4aff0 Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Tue, 23 Dec 2025 13:37:11 -0800
Subject: [PATCH 2/3] globals doesn't work
---
mlir/cmake/modules/AddMLIRPython.cmake | 18 ++++++++++++------
mlir/examples/standalone/pyproject.toml | 3 +++
.../standalone/test/python/smoketest.py | 19 +++----------------
mlir/include/mlir/Bindings/Python/Globals.h | 2 --
mlir/lib/Bindings/Python/Globals.cpp | 18 ++++++++++++------
mlir/test/Examples/standalone/test.wheel.toy | 7 ++-----
6 files changed, 32 insertions(+), 35 deletions(-)
diff --git a/mlir/cmake/modules/AddMLIRPython.cmake b/mlir/cmake/modules/AddMLIRPython.cmake
index 8ec9304421b54..90b26aad03828 100644
--- a/mlir/cmake/modules/AddMLIRPython.cmake
+++ b/mlir/cmake/modules/AddMLIRPython.cmake
@@ -317,6 +317,10 @@ function(build_nanobind_lib)
set(NB_LIBRARY_TARGET_NAME "nanobind${_ft}-${MLIR_BINDINGS_PYTHON_NB_DOMAIN}")
set(NB_LIBRARY_TARGET_NAME "${NB_LIBRARY_TARGET_NAME}" PARENT_SCOPE)
nanobind_build_library(${NB_LIBRARY_TARGET_NAME} AS_SYSINCLUDE)
+ target_compile_definitions(${NB_LIBRARY_TARGET_NAME}
+ PRIVATE
+ NB_DOMAIN=${MLIR_BINDINGS_PYTHON_NB_DOMAIN}
+ )
# nanobind configures with LTO for shared build which doesn't work everywhere
# (see https://github.com/llvm/llvm-project/issues/139602).
if(NOT LLVM_ENABLE_LTO)
@@ -365,6 +369,10 @@ function(add_mlir_python_modules name)
"COMMON_CAPI_LINK_LIBS;DECLARED_SOURCES"
${ARGN})
+ if(NOT MLIR_BINDINGS_PYTHON_NB_DOMAIN)
+ set(MLIR_BINDINGS_PYTHON_NB_DOMAIN "mlir" CACHE STRING "" FORCE)
+ endif()
+
# This call sets NB_LIBRARY_TARGET_NAME.
build_nanobind_lib(
INSTALL_COMPONENT ${name}
@@ -420,6 +428,8 @@ function(add_mlir_python_modules name)
get_target_property(_source_type ${sources_target} mlir_python_SOURCES_TYPE)
if(_source_type STREQUAL "support")
get_target_property(_module_name ${sources_target} mlir_python_EXTENSION_MODULE_NAME)
+ # Use a similar mechanism as nanobind to help the runtime loader pick the correct lib.
+ set(_module_name "${_module_name}-${MLIR_BINDINGS_PYTHON_NB_DOMAIN}")
set(_extension_target "${name}.extension.${_module_name}.dso")
add_mlir_python_extension(${_extension_target} "${_module_name}" ${NB_LIBRARY_TARGET_NAME}
INSTALL_COMPONENT ${name}
@@ -844,10 +854,6 @@ function(add_mlir_python_extension libname extname nb_library_target_name)
set(eh_rtti_enable -frtti -fexceptions)
endif ()
- if(NOT MLIR_BINDINGS_PYTHON_NB_DOMAIN)
- set(MLIR_BINDINGS_PYTHON_NB_DOMAIN "mlir" CACHE STRING "" FORCE)
- endif()
-
if(ARG_SUPPORT_LIB)
add_library(${libname} SHARED ${ARG_SOURCES})
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
@@ -859,9 +865,9 @@ function(add_mlir_python_extension libname extname nb_library_target_name)
NB_DOMAIN=${MLIR_BINDINGS_PYTHON_NB_DOMAIN}
MLIR_CAPI_BUILDING_LIBRARY=1
)
- if (MSVC)
+ if(MSVC)
set_property(TARGET ${libname} PROPERTY WINDOWS_EXPORT_ALL_SYMBOLS ON)
- endif ()
+ endif()
else()
nanobind_add_module(${libname}
NB_DOMAIN ${MLIR_BINDINGS_PYTHON_NB_DOMAIN}
diff --git a/mlir/examples/standalone/pyproject.toml b/mlir/examples/standalone/pyproject.toml
index c4194153743ef..a90fb417eb426 100644
--- a/mlir/examples/standalone/pyproject.toml
+++ b/mlir/examples/standalone/pyproject.toml
@@ -56,8 +56,11 @@ MLIR_DIR = { env = "MLIR_DIR", default = "" }
# Non-optional
CMAKE_BUILD_TYPE = { env = "CMAKE_BUILD_TYPE", default = "Release" }
MLIR_ENABLE_BINDINGS_PYTHON = "ON"
+
# Effectively non-optional (any downstream project should specify this).
+MLIR_BINDINGS_PYTHON_NB_DOMAIN = "mlir_standalone"
MLIR_PYTHON_PACKAGE_PREFIX = "mlir_standalone"
+
# This specifies the directory in the install directory (i.e., /tmp/pip-wheel/platlib) where _mlir_libs, dialects, etc.
# are installed. Thus, this will be the package location (and the name of the package) that pip assumes is
# the root package.
diff --git a/mlir/examples/standalone/test/python/smoketest.py b/mlir/examples/standalone/test/python/smoketest.py
index 9c0ada92551af..ec75790fffeb4 100644
--- a/mlir/examples/standalone/test/python/smoketest.py
+++ b/mlir/examples/standalone/test/python/smoketest.py
@@ -1,20 +1,7 @@
# RUN: %python %s nanobind | FileCheck %s
-from mlir_standalone.ir import *
-from mlir_standalone.dialects import standalone_nanobind as standalone_d
-with Context():
- standalone_d.register_dialects()
- module = Module.parse(
- """
- %0 = arith.constant 2 : i32
- %1 = standalone.foo %0 : i32
- """
- )
- # CHECK: %[[C:.*]] = arith.constant 2 : i32
- # CHECK: standalone.foo %[[C]] : i32
- print(str(module))
- custom_type = standalone_d.CustomType.get("foo")
- # CHECK: !standalone.custom<"foo">
- print(custom_type)
+import mlir_standalone.ir
+
+import mlir.ir
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index 112c7b9b0547f..d9334cb35cc27 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -174,8 +174,6 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
MlirTypeID allocateTypeID() { return typeIDAllocator.allocate(); }
private:
- static PyGlobals *instance;
-
nanobind::ft_mutex mutex;
/// Module name prefixes to search under for dialect implementation modules.
diff --git a/mlir/lib/Bindings/Python/Globals.cpp b/mlir/lib/Bindings/Python/Globals.cpp
index ecac571a132f6..7e451c8009809 100644
--- a/mlir/lib/Bindings/Python/Globals.cpp
+++ b/mlir/lib/Bindings/Python/Globals.cpp
@@ -19,6 +19,8 @@
#include "mlir-c/Support.h"
#include "mlir/Bindings/Python/Nanobind.h"
+#include <iostream>
+
namespace nb = nanobind;
using namespace mlir;
@@ -26,22 +28,26 @@ using namespace mlir;
// PyGlobals
// -----------------------------------------------------------------------------
+namespace {
+python::PyGlobals *pyGlobalsInstance = nullptr;
+}
+
namespace mlir::python {
-PyGlobals *PyGlobals::instance = nullptr;
PyGlobals::PyGlobals() {
- assert(!instance && "PyGlobals already constructed");
- instance = this;
+ std::cerr << MAKE_MLIR_PYTHON_QUALNAME("dialects") << "\n";
+ assert(!pyGlobalsInstance && "PyGlobals already constructed");
+ pyGlobalsInstance = this;
// The default search path include {mlir.}dialects, where {mlir.} is the
// package prefix configured at compile time.
dialectSearchPrefixes.emplace_back(MAKE_MLIR_PYTHON_QUALNAME("dialects"));
}
-PyGlobals::~PyGlobals() { instance = nullptr; }
+PyGlobals::~PyGlobals() { pyGlobalsInstance = nullptr; }
PyGlobals &PyGlobals::get() {
- assert(instance && "PyGlobals is null");
- return *instance;
+ assert(pyGlobalsInstance && "PyGlobals is null");
+ return *pyGlobalsInstance;
}
bool PyGlobals::loadDialectModule(llvm::StringRef dialectNamespace) {
diff --git a/mlir/test/Examples/standalone/test.wheel.toy b/mlir/test/Examples/standalone/test.wheel.toy
index c8d188a3cacd0..55847f7430648 100644
--- a/mlir/test/Examples/standalone/test.wheel.toy
+++ b/mlir/test/Examples/standalone/test.wheel.toy
@@ -1,10 +1,6 @@
# There's no real issue with windows here, it's just that some CMake generated paths for targets end up being longer
# than 255 chars when combined with the fact that pip wants to install into a tmp directory buried under
# C/Users/ContainerAdministrator/AppData/Local/Temp.
-# UNSUPPORTED: target={{.*(windows).*}}
-# REQUIRES: expensive_checks
-# REQUIRES: non-shared-libs-build
-# REQUIRES: bindings-python
# RUN: export CMAKE_BUILD_TYPE=%cmake_build_type
# RUN: export CMAKE_CXX_COMPILER=%host_cxx
@@ -15,7 +11,8 @@
# RUN: export LLVM_USE_LINKER=%llvm_use_linker
# RUN: export MLIR_DIR="%mlir_cmake_dir"
-# RUN: %python -m pip wheel "%mlir_src_root/examples/standalone" -w "%mlir_obj_root/wheelhouse" -v | tee %t
+# RUN: %python -m pip install scikit-build-core
+# RUN: %python -m pip wheel "%mlir_src_root/examples/standalone" -w "%mlir_obj_root/wheelhouse" -v --no-build-isolation | tee %t
# RUN: rm -rf "%mlir_obj_root/standalone-python-bindings-install"
# RUN: %python -m pip install standalone_python_bindings -f "%mlir_obj_root/wheelhouse" --target "%mlir_obj_root/standalone-python-bindings-install" -v | tee -a %t
>From cf6a8251b852c5c03b47ef0b432c0f6b6a5a2a9a Mon Sep 17 00:00:00 2001
From: makslevental <maksim.levental at gmail.com>
Date: Tue, 23 Dec 2025 17:00:17 -0800
Subject: [PATCH 3/3] works
---
.../examples/standalone/python/CMakeLists.txt | 1 +
.../python/StandaloneExtensionNanobind.cpp | 6 +-
.../standalone/test/python/smoketest.py | 21 ++-
mlir/include/mlir/Bindings/Python/Globals.h | 5 +-
mlir/include/mlir/Bindings/Python/IRCore.h | 43 ++++--
mlir/include/mlir/Bindings/Python/IRTypes.h | 8 +-
mlir/lib/Bindings/Python/Globals.cpp | 26 ++--
mlir/lib/Bindings/Python/IRAffine.cpp | 34 +++--
mlir/lib/Bindings/Python/IRAttributes.cpp | 18 ++-
mlir/lib/Bindings/Python/IRCore.cpp | 28 ++--
mlir/lib/Bindings/Python/IRInterfaces.cpp | 4 +-
mlir/lib/Bindings/Python/IRTypes.cpp | 37 +++--
mlir/lib/Bindings/Python/MainModule.cpp | 133 ++++++++++--------
mlir/lib/Bindings/Python/Pass.cpp | 39 +++--
mlir/lib/Bindings/Python/Pass.h | 3 +-
mlir/lib/Bindings/Python/Rewrite.cpp | 43 +++---
mlir/lib/Bindings/Python/Rewrite.h | 4 +-
mlir/python/CMakeLists.txt | 1 +
mlir/test/Examples/standalone/test.wheel.toy | 14 +-
.../python/lib/PythonTestModuleNanobind.cpp | 13 +-
20 files changed, 303 insertions(+), 178 deletions(-)
diff --git a/mlir/examples/standalone/python/CMakeLists.txt b/mlir/examples/standalone/python/CMakeLists.txt
index edaedf18cc843..d3b3aeadb6396 100644
--- a/mlir/examples/standalone/python/CMakeLists.txt
+++ b/mlir/examples/standalone/python/CMakeLists.txt
@@ -3,6 +3,7 @@ include(AddMLIRPython)
# Specifies that all MLIR packages are co-located under the `mlir_standalone`
# top level package (the API has been embedded in a relocatable way).
add_compile_definitions("MLIR_PYTHON_PACKAGE_PREFIX=${MLIR_PYTHON_PACKAGE_PREFIX}.")
+add_compile_definitions("MLIR_BINDINGS_PYTHON_DOMAIN=${MLIR_BINDINGS_PYTHON_NB_DOMAIN}")
################################################################################
diff --git a/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp b/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp
index 37737cd89ee1e..c568369913595 100644
--- a/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp
+++ b/mlir/examples/standalone/python/StandaloneExtensionNanobind.cpp
@@ -17,7 +17,8 @@
namespace nb = nanobind;
-struct PyCustomType : mlir::python::PyConcreteType<PyCustomType> {
+struct PyCustomType
+ : mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyCustomType> {
static constexpr IsAFunctionTy isaFunction = mlirStandaloneTypeIsACustomType;
static constexpr GetTypeIDFunctionTy getTypeIdFunction =
mlirStandaloneCustomTypeGetTypeID;
@@ -28,7 +29,8 @@ struct PyCustomType : mlir::python::PyConcreteType<PyCustomType> {
c.def_static(
"get",
[](const std::string &value,
- mlir::python::DefaultingPyMlirContext context) {
+ mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyMlirContext
+ context) {
return PyCustomType(
context->getRef(),
mlirStandaloneCustomTypeGet(
diff --git a/mlir/examples/standalone/test/python/smoketest.py b/mlir/examples/standalone/test/python/smoketest.py
index ec75790fffeb4..9132bab75cfcc 100644
--- a/mlir/examples/standalone/test/python/smoketest.py
+++ b/mlir/examples/standalone/test/python/smoketest.py
@@ -1,7 +1,24 @@
# RUN: %python %s nanobind | FileCheck %s
+import sys
+from mlir_standalone.ir import *
+from mlir_standalone.dialects import standalone_nanobind as standalone_d
+with Context():
+ standalone_d.register_dialects()
+ module = Module.parse(
+ """
+ %0 = arith.constant 2 : i32
+ %1 = standalone.foo %0 : i32
+ """
+ )
+ # CHECK: %[[C:.*]] = arith.constant 2 : i32
+ # CHECK: standalone.foo %[[C]] : i32
+ print(str(module))
-import mlir_standalone.ir
+ custom_type = standalone_d.CustomType.get("foo")
+ # CHECK: !standalone.custom<"foo">
+ print(custom_type)
-import mlir.ir
+if sys.argv[1] == "test-upstream":
+ from mlir.ir import *
diff --git a/mlir/include/mlir/Bindings/Python/Globals.h b/mlir/include/mlir/Bindings/Python/Globals.h
index d9334cb35cc27..5548a716cbe21 100644
--- a/mlir/include/mlir/Bindings/Python/Globals.h
+++ b/mlir/include/mlir/Bindings/Python/Globals.h
@@ -28,7 +28,7 @@
namespace mlir {
namespace python {
-
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
/// Globals that are always accessible once the extension has been initialized.
/// Methods of this class are thread-safe.
class MLIR_PYTHON_API_EXPORTED PyGlobals {
@@ -174,6 +174,8 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
MlirTypeID allocateTypeID() { return typeIDAllocator.allocate(); }
private:
+ static PyGlobals *instance;
+
nanobind::ft_mutex mutex;
/// Module name prefixes to search under for dialect implementation modules.
@@ -195,6 +197,7 @@ class MLIR_PYTHON_API_EXPORTED PyGlobals {
TracebackLoc tracebackLoc;
TypeIDAllocator typeIDAllocator;
};
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
} // namespace python
} // namespace mlir
diff --git a/mlir/include/mlir/Bindings/Python/IRCore.h b/mlir/include/mlir/Bindings/Python/IRCore.h
index ceedeb691eb58..7ed0a9f63bfda 100644
--- a/mlir/include/mlir/Bindings/Python/IRCore.h
+++ b/mlir/include/mlir/Bindings/Python/IRCore.h
@@ -33,6 +33,7 @@
namespace mlir {
namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
class PyBlock;
class PyDiagnostic;
@@ -325,6 +326,26 @@ class MLIR_PYTHON_API_EXPORTED PyLocation : public BaseContextObject {
MlirLocation loc;
};
+enum PyMlirDiagnosticSeverity : std::underlying_type<
+ MlirDiagnosticSeverity>::type {
+ MlirDiagnosticError = MlirDiagnosticError,
+ MlirDiagnosticWarning = MlirDiagnosticWarning,
+ MlirDiagnosticNote = MlirDiagnosticNote,
+ MlirDiagnosticRemark = MlirDiagnosticRemark
+};
+
+enum PyMlirWalkResult : std::underlying_type<MlirWalkResult>::type {
+ MlirWalkResultAdvance = MlirWalkResultAdvance,
+ MlirWalkResultInterrupt = MlirWalkResultInterrupt,
+ MlirWalkResultSkip = MlirWalkResultSkip
+};
+
+/// Traversal order for operation walk.
+enum PyMlirWalkOrder : std::underlying_type<MlirWalkOrder>::type {
+ MlirWalkPreOrder = MlirWalkPreOrder,
+ MlirWalkPostOrder = MlirWalkPostOrder
+};
+
/// Python class mirroring the C MlirDiagnostic struct. Note that these structs
/// are only valid for the duration of a diagnostic callback and attempting
/// to access them outside of that will raise an exception. This applies to
@@ -334,7 +355,7 @@ class MLIR_PYTHON_API_EXPORTED PyDiagnostic {
PyDiagnostic(MlirDiagnostic diagnostic) : diagnostic(diagnostic) {}
void invalidate();
bool isValid() { return valid; }
- MlirDiagnosticSeverity getSeverity();
+ PyMlirDiagnosticSeverity getSeverity();
PyLocation getLocation();
nanobind::str getMessage();
nanobind::tuple getNotes();
@@ -342,7 +363,7 @@ class MLIR_PYTHON_API_EXPORTED PyDiagnostic {
/// Materialized diagnostic information. This is safe to access outside the
/// diagnostic callback.
struct DiagnosticInfo {
- MlirDiagnosticSeverity severity;
+ PyMlirDiagnosticSeverity severity;
PyLocation location;
std::string message;
std::vector<DiagnosticInfo> notes;
@@ -573,8 +594,8 @@ class MLIR_PYTHON_API_EXPORTED PyOperationBase {
std::optional<int64_t> bytecodeVersion);
// Implement the walk method.
- void walk(std::function<MlirWalkResult(MlirOperation)> callback,
- MlirWalkOrder walkOrder);
+ void walk(std::function<PyMlirWalkResult(MlirOperation)> callback,
+ PyMlirWalkOrder walkOrder);
/// Moves the operation before or after the other operation.
void moveAfter(PyOperationBase &other);
@@ -2364,6 +2385,7 @@ class MLIR_PYTHON_API_EXPORTED PyOpAttributeMap {
};
MLIR_PYTHON_API_EXPORTED MlirValue getUniqueResult(MlirOperation operation);
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
} // namespace python
} // namespace mlir
@@ -2371,11 +2393,16 @@ namespace nanobind {
namespace detail {
template <>
-struct type_caster<mlir::python::DefaultingPyMlirContext>
- : MlirDefaultingCaster<mlir::python::DefaultingPyMlirContext> {};
+struct type_caster<
+ mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyMlirContext>
+ : MlirDefaultingCaster<
+ mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyMlirContext> {
+};
template <>
-struct type_caster<mlir::python::DefaultingPyLocation>
- : MlirDefaultingCaster<mlir::python::DefaultingPyLocation> {};
+struct type_caster<
+ mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyLocation>
+ : MlirDefaultingCaster<
+ mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyLocation> {};
} // namespace detail
} // namespace nanobind
diff --git a/mlir/include/mlir/Bindings/Python/IRTypes.h b/mlir/include/mlir/Bindings/Python/IRTypes.h
index cd0cfbc7d61d8..87e0e10764bd8 100644
--- a/mlir/include/mlir/Bindings/Python/IRTypes.h
+++ b/mlir/include/mlir/Bindings/Python/IRTypes.h
@@ -12,10 +12,11 @@
#include "mlir/Bindings/Python/NanobindAdaptors.h"
namespace mlir {
-
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
/// Shaped Type Interface - ShapedType
class MLIR_PYTHON_API_EXPORTED PyShapedType
- : public python::PyConcreteType<PyShapedType> {
+ : public PyConcreteType<PyShapedType> {
public:
static const IsAFunctionTy isaFunction;
static constexpr const char *pyClassName = "ShapedType";
@@ -26,7 +27,8 @@ class MLIR_PYTHON_API_EXPORTED PyShapedType
private:
void requireHasRank();
};
-
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
} // namespace mlir
#endif // MLIR_BINDINGS_PYTHON_IRTYPES_H
diff --git a/mlir/lib/Bindings/Python/Globals.cpp b/mlir/lib/Bindings/Python/Globals.cpp
index 7e451c8009809..e2e8693ba45f3 100644
--- a/mlir/lib/Bindings/Python/Globals.cpp
+++ b/mlir/lib/Bindings/Python/Globals.cpp
@@ -19,8 +19,6 @@
#include "mlir-c/Support.h"
#include "mlir/Bindings/Python/Nanobind.h"
-#include <iostream>
-
namespace nb = nanobind;
using namespace mlir;
@@ -28,26 +26,24 @@ using namespace mlir;
// PyGlobals
// -----------------------------------------------------------------------------
-namespace {
-python::PyGlobals *pyGlobalsInstance = nullptr;
-}
-
-namespace mlir::python {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
+PyGlobals *PyGlobals::instance = nullptr;
PyGlobals::PyGlobals() {
- std::cerr << MAKE_MLIR_PYTHON_QUALNAME("dialects") << "\n";
- assert(!pyGlobalsInstance && "PyGlobals already constructed");
- pyGlobalsInstance = this;
+ assert(!instance && "PyGlobals already constructed");
+ instance = this;
// The default search path include {mlir.}dialects, where {mlir.} is the
// package prefix configured at compile time.
dialectSearchPrefixes.emplace_back(MAKE_MLIR_PYTHON_QUALNAME("dialects"));
}
-PyGlobals::~PyGlobals() { pyGlobalsInstance = nullptr; }
+PyGlobals::~PyGlobals() { instance = nullptr; }
PyGlobals &PyGlobals::get() {
- assert(pyGlobalsInstance && "PyGlobals is null");
- return *pyGlobalsInstance;
+ assert(instance && "PyGlobals is null");
+ return *instance;
}
bool PyGlobals::loadDialectModule(llvm::StringRef dialectNamespace) {
@@ -278,4 +274,6 @@ bool PyGlobals::TracebackLoc::isUserTracebackFilename(
}
return isUserTracebackFilenameCache[file];
}
-} // namespace mlir::python
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/IRAffine.cpp b/mlir/lib/Bindings/Python/IRAffine.cpp
index 624d8f0fa57ce..ce235470bbdc7 100644
--- a/mlir/lib/Bindings/Python/IRAffine.cpp
+++ b/mlir/lib/Bindings/Python/IRAffine.cpp
@@ -30,7 +30,7 @@
namespace nb = nanobind;
using namespace mlir;
-using namespace mlir::python;
+using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
using llvm::SmallVector;
using llvm::StringRef;
@@ -80,7 +80,9 @@ static bool isPermutation(const std::vector<PermutationTy> &permutation) {
return true;
}
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
/// CRTP base class for Python MLIR affine expressions that subclass AffineExpr
/// and should be castable from it. Intermediate hierarchy classes can be
@@ -358,7 +360,9 @@ class PyAffineCeilDivExpr
}
};
-} // namespace
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
bool PyAffineExpr::operator==(const PyAffineExpr &other) const {
return mlirAffineExprEqual(affineExpr, other.affineExpr);
@@ -380,7 +384,9 @@ PyAffineExpr PyAffineExpr::createFromCapsule(const nb::object &capsule) {
//------------------------------------------------------------------------------
// PyAffineMap and utilities.
//------------------------------------------------------------------------------
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
/// A list of expressions contained in an affine map. Internally these are
/// stored as a consecutive array leading to inexpensive random access. Both
@@ -416,7 +422,9 @@ class PyAffineMapExprList
PyAffineMap affineMap;
};
-} // namespace
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
bool PyAffineMap::operator==(const PyAffineMap &other) const {
return mlirAffineMapEqual(affineMap, other.affineMap);
@@ -438,7 +446,9 @@ PyAffineMap PyAffineMap::createFromCapsule(const nb::object &capsule) {
//------------------------------------------------------------------------------
// PyIntegerSet and utilities.
//------------------------------------------------------------------------------
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
class PyIntegerSetConstraint {
public:
@@ -492,7 +502,9 @@ class PyIntegerSetConstraintList
PyIntegerSet set;
};
-} // namespace
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
bool PyIntegerSet::operator==(const PyIntegerSet &other) const {
return mlirIntegerSetEqual(integerSet, other.integerSet);
@@ -511,7 +523,9 @@ PyIntegerSet PyIntegerSet::createFromCapsule(const nb::object &capsule) {
rawIntegerSet);
}
-namespace mlir::python {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
void populateIRAffine(nb::module_ &m) {
//----------------------------------------------------------------------------
// Mapping of PyAffineExpr and derived classes.
@@ -998,4 +1012,6 @@ void populateIRAffine(nb::module_ &m) {
PyIntegerSetConstraint::bind(m);
PyIntegerSetConstraintList::bind(m);
}
-} // namespace mlir::python
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/IRAttributes.cpp b/mlir/lib/Bindings/Python/IRAttributes.cpp
index e39eabdb136b8..a4d308bf049d8 100644
--- a/mlir/lib/Bindings/Python/IRAttributes.cpp
+++ b/mlir/lib/Bindings/Python/IRAttributes.cpp
@@ -24,7 +24,7 @@
namespace nb = nanobind;
using namespace nanobind::literals;
using namespace mlir;
-using namespace mlir::python;
+using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
using llvm::SmallVector;
@@ -121,7 +121,9 @@ subsequent processing.
type or if the buffer does not meet expectations.
)";
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
struct nb_buffer_info {
void *ptr = nullptr;
@@ -1745,7 +1747,9 @@ nb::object symbolRefOrFlatSymbolRefAttributeCaster(PyAttribute &pyAttribute) {
throw nb::type_error(msg.c_str());
}
-} // namespace
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
void PyStringAttribute::bindDerived(ClassTy &c) {
c.def_static(
@@ -1791,7 +1795,9 @@ void PyStringAttribute::bindDerived(ClassTy &c) {
"Returns the value of the string attribute as `bytes`");
}
-namespace mlir::python {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
void populateIRAttributes(nb::module_ &m) {
PyAffineMapAttribute::bind(m);
PyDenseBoolArrayAttribute::bind(m);
@@ -1846,4 +1852,6 @@ void populateIRAttributes(nb::module_ &m) {
PyStridedLayoutAttribute::bind(m);
registerMLIRError();
}
-} // namespace mlir::python
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index fc8743599508d..069e177708afc 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -31,13 +31,14 @@
namespace nb = nanobind;
using namespace nb::literals;
using namespace mlir;
-using namespace mlir::python;
using llvm::SmallVector;
using llvm::StringRef;
using llvm::Twine;
-namespace mlir::python {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
//------------------------------------------------------------------------------
// PyMlirContext
//------------------------------------------------------------------------------
@@ -169,7 +170,8 @@ MlirLogicalResult PyMlirContext::ErrorCapture::handler(MlirDiagnostic diag,
if (self->ctx->emitErrorDiagnostics)
return mlirLogicalResultFailure();
- if (mlirDiagnosticGetSeverity(diag) != MlirDiagnosticError)
+ if (mlirDiagnosticGetSeverity(diag) !=
+ MlirDiagnosticSeverity::MlirDiagnosticError)
return mlirLogicalResultFailure();
self->errors.emplace_back(PyDiagnostic(diag).getInfo());
@@ -356,9 +358,10 @@ void PyDiagnostic::checkValid() {
}
}
-MlirDiagnosticSeverity PyDiagnostic::getSeverity() {
+PyMlirDiagnosticSeverity PyDiagnostic::getSeverity() {
checkValid();
- return mlirDiagnosticGetSeverity(diagnostic);
+ return static_cast<PyMlirDiagnosticSeverity>(
+ mlirDiagnosticGetSeverity(diagnostic));
}
PyLocation PyDiagnostic::getLocation() {
@@ -672,12 +675,12 @@ void PyOperationBase::writeBytecode(const nb::object &fileOrStringObject,
}
void PyOperationBase::walk(
- std::function<MlirWalkResult(MlirOperation)> callback,
- MlirWalkOrder walkOrder) {
+ std::function<PyMlirWalkResult(MlirOperation)> callback,
+ PyMlirWalkOrder walkOrder) {
PyOperation &operation = getOperation();
operation.checkValid();
struct UserData {
- std::function<MlirWalkResult(MlirOperation)> callback;
+ std::function<PyMlirWalkResult(MlirOperation)> callback;
bool gotException;
std::string exceptionWhat;
nb::object exceptionType;
@@ -687,7 +690,7 @@ void PyOperationBase::walk(
void *userData) {
UserData *calleeUserData = static_cast<UserData *>(userData);
try {
- return (calleeUserData->callback)(op);
+ return static_cast<MlirWalkResult>((calleeUserData->callback)(op));
} catch (nb::python_error &e) {
calleeUserData->gotException = true;
calleeUserData->exceptionWhat = std::string(e.what());
@@ -695,7 +698,8 @@ void PyOperationBase::walk(
return MlirWalkResult::MlirWalkResultInterrupt;
}
};
- mlirOperationWalk(operation, walkCallback, &userData, walkOrder);
+ mlirOperationWalk(operation, walkCallback, &userData,
+ static_cast<MlirWalkOrder>(walkOrder));
if (userData.gotException) {
std::string message("Exception raised in callback: ");
message.append(userData.exceptionWhat);
@@ -1685,4 +1689,6 @@ void registerMLIRErrorInCore() {
}
});
}
-} // namespace mlir::python
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/IRInterfaces.cpp b/mlir/lib/Bindings/Python/IRInterfaces.cpp
index 78d1f977b2ebc..09112d4989ae4 100644
--- a/mlir/lib/Bindings/Python/IRInterfaces.cpp
+++ b/mlir/lib/Bindings/Python/IRInterfaces.cpp
@@ -25,7 +25,7 @@ namespace nb = nanobind;
namespace mlir {
namespace python {
-
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
constexpr static const char *constructorDoc =
R"(Creates an interface from a given operation/opview object or from a
subclass of OpView. Raises ValueError if the operation does not implement the
@@ -469,6 +469,6 @@ void populateIRInterfaces(nb::module_ &m) {
PyShapedTypeComponents::bind(m);
PyInferShapedTypeOpInterface::bind(m);
}
-
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
} // namespace python
} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/IRTypes.cpp b/mlir/lib/Bindings/Python/IRTypes.cpp
index 7d9a0f16c913a..62fb2ef207d58 100644
--- a/mlir/lib/Bindings/Python/IRTypes.cpp
+++ b/mlir/lib/Bindings/Python/IRTypes.cpp
@@ -20,12 +20,14 @@
namespace nb = nanobind;
using namespace mlir;
-using namespace mlir::python;
+using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
using llvm::SmallVector;
using llvm::Twine;
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
/// Checks whether the given type is an integer or float type.
static int mlirTypeIsAIntegerOrFloat(MlirType type) {
@@ -508,10 +510,12 @@ class PyComplexType : public PyConcreteType<PyComplexType> {
}
};
-} // namespace
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
// Shaped Type Interface - ShapedType
-void mlir::PyShapedType::bindDerived(ClassTy &c) {
+void PyShapedType::bindDerived(ClassTy &c) {
c.def_prop_ro(
"element_type",
[](PyShapedType &self) -> nb::typed<nb::object, PyType> {
@@ -616,17 +620,18 @@ void mlir::PyShapedType::bindDerived(ClassTy &c) {
"shaped types.");
}
-void mlir::PyShapedType::requireHasRank() {
+void PyShapedType::requireHasRank() {
if (!mlirShapedTypeHasRank(*this)) {
throw nb::value_error(
"calling this method requires that the type has a rank.");
}
}
-const mlir::PyShapedType::IsAFunctionTy mlir::PyShapedType::isaFunction =
- mlirTypeIsAShaped;
+const PyShapedType::IsAFunctionTy PyShapedType::isaFunction = mlirTypeIsAShaped;
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
/// Vector Type subclass - VectorType.
class PyVectorType : public PyConcreteType<PyVectorType, PyShapedType> {
@@ -1098,10 +1103,6 @@ class PyFunctionType : public PyConcreteType<PyFunctionType> {
}
};
-static MlirStringRef toMlirStringRef(const std::string &s) {
- return mlirStringRefCreate(s.data(), s.size());
-}
-
/// Opaque Type subclass - OpaqueType.
class PyOpaqueType : public PyConcreteType<PyOpaqueType> {
public:
@@ -1141,9 +1142,13 @@ class PyOpaqueType : public PyConcreteType<PyOpaqueType> {
}
};
-} // namespace
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
-namespace mlir::python {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
void populateIRTypes(nb::module_ &m) {
PyIntegerType::bind(m);
PyFloatType::bind(m);
@@ -1177,4 +1182,6 @@ void populateIRTypes(nb::module_ &m) {
PyOpaqueType::bind(m);
registerMLIRError();
}
-} // namespace mlir::python
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/MainModule.cpp b/mlir/lib/Bindings/Python/MainModule.cpp
index f72775cc0b83a..392144ec5f0b7 100644
--- a/mlir/lib/Bindings/Python/MainModule.cpp
+++ b/mlir/lib/Bindings/Python/MainModule.cpp
@@ -16,7 +16,7 @@
namespace nb = nanobind;
using namespace mlir;
using namespace nb::literals;
-using namespace mlir::python;
+using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
static const char kModuleParseDocstring[] =
R"(Parses a module's assembly format from a string.
@@ -35,6 +35,56 @@ in `exceptions`. `exceptions` can be either a single operation or a list of
operations.
)";
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
+/// Wrapper for the global LLVM debugging flag.
+struct PyGlobalDebugFlag {
+ static void set(nanobind::object &o, bool enable) {
+ nanobind::ft_lock_guard lock(mutex);
+ mlirEnableGlobalDebug(enable);
+ }
+
+ static bool get(const nanobind::object &) {
+ nanobind::ft_lock_guard lock(mutex);
+ return mlirIsGlobalDebugEnabled();
+ }
+
+ static void bind(nanobind::module_ &m) {
+ // Debug flags.
+ nanobind::class_<PyGlobalDebugFlag>(m, "_GlobalDebug")
+ .def_prop_rw_static("flag", &PyGlobalDebugFlag::get,
+ &PyGlobalDebugFlag::set, "LLVM-wide debug flag.")
+ .def_static(
+ "set_types",
+ [](const std::string &type) {
+ nanobind::ft_lock_guard lock(mutex);
+ mlirSetGlobalDebugType(type.c_str());
+ },
+ nanobind::arg("types"),
+ "Sets specific debug types to be produced by LLVM.")
+ .def_static(
+ "set_types",
+ [](const std::vector<std::string> &types) {
+ std::vector<const char *> pointers;
+ pointers.reserve(types.size());
+ for (const std::string &str : types)
+ pointers.push_back(str.c_str());
+ nanobind::ft_lock_guard lock(mutex);
+ mlirSetGlobalDebugTypes(pointers.data(), pointers.size());
+ },
+ nanobind::arg("types"),
+ "Sets multiple specific debug types to be produced by LLVM.");
+ }
+
+private:
+ static nanobind::ft_mutex mutex;
+};
+nanobind::ft_mutex PyGlobalDebugFlag::mutex;
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
+
namespace {
// see
// https://raw.githubusercontent.com/python/pythoncapi_compat/master/pythoncapi_compat.h
@@ -185,51 +235,6 @@ maybeGetTracebackLocation(const std::optional<PyLocation> &location) {
PyMlirContextRef ref = PyMlirContext::forContext(ctx.get());
return {ref, mlirLoc};
}
-
-/// Wrapper for the global LLVM debugging flag.
-struct PyGlobalDebugFlag {
- static void set(nanobind::object &o, bool enable) {
- nanobind::ft_lock_guard lock(mutex);
- mlirEnableGlobalDebug(enable);
- }
-
- static bool get(const nanobind::object &) {
- nanobind::ft_lock_guard lock(mutex);
- return mlirIsGlobalDebugEnabled();
- }
-
- static void bind(nanobind::module_ &m) {
- // Debug flags.
- nanobind::class_<PyGlobalDebugFlag>(m, "_GlobalDebug")
- .def_prop_rw_static("flag", &PyGlobalDebugFlag::get,
- &PyGlobalDebugFlag::set, "LLVM-wide debug flag.")
- .def_static(
- "set_types",
- [](const std::string &type) {
- nanobind::ft_lock_guard lock(mutex);
- mlirSetGlobalDebugType(type.c_str());
- },
- nanobind::arg("types"),
- "Sets specific debug types to be produced by LLVM.")
- .def_static(
- "set_types",
- [](const std::vector<std::string> &types) {
- std::vector<const char *> pointers;
- pointers.reserve(types.size());
- for (const std::string &str : types)
- pointers.push_back(str.c_str());
- nanobind::ft_lock_guard lock(mutex);
- mlirSetGlobalDebugTypes(pointers.data(), pointers.size());
- },
- nanobind::arg("types"),
- "Sets multiple specific debug types to be produced by LLVM.");
- }
-
-private:
- static nanobind::ft_mutex mutex;
-};
-
-nanobind::ft_mutex PyGlobalDebugFlag::mutex;
} // namespace
//------------------------------------------------------------------------------
@@ -242,20 +247,20 @@ static void populateIRCore(nb::module_ &m) {
//----------------------------------------------------------------------------
// Enums.
//----------------------------------------------------------------------------
- nb::enum_<MlirDiagnosticSeverity>(m, "DiagnosticSeverity")
- .value("ERROR", MlirDiagnosticError)
- .value("WARNING", MlirDiagnosticWarning)
- .value("NOTE", MlirDiagnosticNote)
- .value("REMARK", MlirDiagnosticRemark);
+ nb::enum_<PyMlirDiagnosticSeverity>(m, "DiagnosticSeverity")
+ .value("ERROR", PyMlirDiagnosticSeverity::MlirDiagnosticError)
+ .value("WARNING", PyMlirDiagnosticSeverity::MlirDiagnosticWarning)
+ .value("NOTE", PyMlirDiagnosticSeverity::MlirDiagnosticNote)
+ .value("REMARK", PyMlirDiagnosticSeverity::MlirDiagnosticRemark);
- nb::enum_<MlirWalkOrder>(m, "WalkOrder")
- .value("PRE_ORDER", MlirWalkPreOrder)
- .value("POST_ORDER", MlirWalkPostOrder);
+ nb::enum_<PyMlirWalkOrder>(m, "WalkOrder")
+ .value("PRE_ORDER", PyMlirWalkOrder::MlirWalkPreOrder)
+ .value("POST_ORDER", PyMlirWalkOrder::MlirWalkPostOrder);
- nb::enum_<MlirWalkResult>(m, "WalkResult")
- .value("ADVANCE", MlirWalkResultAdvance)
- .value("INTERRUPT", MlirWalkResultInterrupt)
- .value("SKIP", MlirWalkResultSkip);
+ nb::enum_<PyMlirWalkResult>(m, "WalkResult")
+ .value("ADVANCE", PyMlirWalkResult::MlirWalkResultAdvance)
+ .value("INTERRUPT", PyMlirWalkResult::MlirWalkResultInterrupt)
+ .value("SKIP", PyMlirWalkResult::MlirWalkResultSkip);
//----------------------------------------------------------------------------
// Mapping of Diagnostics.
@@ -1186,7 +1191,7 @@ static void populateIRCore(nb::module_ &m) {
Note:
After erasing, any Python references to the operation become invalid.)")
.def("walk", &PyOperationBase::walk, nb::arg("callback"),
- nb::arg("walk_order") = MlirWalkPostOrder,
+ nb::arg("walk_order") = PyMlirWalkOrder::MlirWalkPostOrder,
// clang-format off
nb::sig("def walk(self, callback: Callable[[Operation], WalkResult], walk_order: WalkOrder) -> None"),
// clang-format on
@@ -2305,12 +2310,16 @@ static void populateIRCore(nb::module_ &m) {
PyAttrBuilderMap::bind(m);
}
-namespace mlir::python {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
void populateIRAffine(nb::module_ &m);
void populateIRAttributes(nb::module_ &m);
void populateIRInterfaces(nb::module_ &m);
void populateIRTypes(nb::module_ &m);
-} // namespace mlir::python
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
// -----------------------------------------------------------------------------
// Module initialization.
@@ -2453,5 +2462,5 @@ NB_MODULE(_mlir, m) {
m.def_submodule("passmanager", "MLIR Pass Management Bindings");
populatePassManagerSubmodule(passManagerModule);
registerMLIRError();
- registerMLIRErrorInCore();
+ // registerMLIRErrorInCore();
}
diff --git a/mlir/lib/Bindings/Python/Pass.cpp b/mlir/lib/Bindings/Python/Pass.cpp
index 3cfdfe49b4e3e..e35923553e0a1 100644
--- a/mlir/lib/Bindings/Python/Pass.cpp
+++ b/mlir/lib/Bindings/Python/Pass.cpp
@@ -19,9 +19,11 @@
namespace nb = nanobind;
using namespace nb::literals;
using namespace mlir;
-using namespace mlir::python;
+using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
/// Owning Wrapper around a PassManager.
class PyPassManager {
@@ -53,23 +55,29 @@ class PyPassManager {
MlirPassManager passManager;
};
-} // namespace
+enum PyMlirPassDisplayMode : std::underlying_type<MlirPassDisplayMode>::type {
+ MLIR_PASS_DISPLAY_MODE_LIST = MLIR_PASS_DISPLAY_MODE_LIST,
+ MLIR_PASS_DISPLAY_MODE_PIPELINE = MLIR_PASS_DISPLAY_MODE_PIPELINE
+};
+
+struct PyMlirExternalPass : MlirExternalPass {};
/// Create the `mlir.passmanager` here.
-void mlir::python::populatePassManagerSubmodule(nb::module_ &m) {
+void populatePassManagerSubmodule(nb::module_ &m) {
//----------------------------------------------------------------------------
// Mapping of enumerated types
//----------------------------------------------------------------------------
- nb::enum_<MlirPassDisplayMode>(m, "PassDisplayMode")
+ nb::enum_<PyMlirPassDisplayMode>(m, "PassDisplayMode")
.value("LIST", MLIR_PASS_DISPLAY_MODE_LIST)
.value("PIPELINE", MLIR_PASS_DISPLAY_MODE_PIPELINE);
//----------------------------------------------------------------------------
// Mapping of MlirExternalPass
//----------------------------------------------------------------------------
- nb::class_<MlirExternalPass>(m, "ExternalPass")
- .def("signal_pass_failure",
- [](MlirExternalPass pass) { mlirExternalPassSignalFailure(pass); });
+ nb::class_<PyMlirExternalPass>(m, "ExternalPass")
+ .def("signal_pass_failure", [](PyMlirExternalPass pass) {
+ mlirExternalPassSignalFailure(pass);
+ });
//----------------------------------------------------------------------------
// Mapping of the top-level PassManager
@@ -148,11 +156,12 @@ void mlir::python::populatePassManagerSubmodule(nb::module_ &m) {
"Enable pass timing.")
.def(
"enable_statistics",
- [](PyPassManager &passManager, MlirPassDisplayMode displayMode) {
- mlirPassManagerEnableStatistics(passManager.get(), displayMode);
+ [](PyPassManager &passManager, PyMlirPassDisplayMode displayMode) {
+ mlirPassManagerEnableStatistics(
+ passManager.get(),
+ static_cast<MlirPassDisplayMode>(displayMode));
},
- "displayMode"_a =
- MlirPassDisplayMode::MLIR_PASS_DISPLAY_MODE_PIPELINE,
+ "displayMode"_a = MLIR_PASS_DISPLAY_MODE_PIPELINE,
"Enable pass statistics.")
.def_static(
"parse",
@@ -211,7 +220,8 @@ void mlir::python::populatePassManagerSubmodule(nb::module_ &m) {
};
callbacks.run = [](MlirOperation op, MlirExternalPass pass,
void *userData) {
- nb::handle(static_cast<PyObject *>(userData))(op, pass);
+ nb::handle(static_cast<PyObject *>(userData))(
+ op, PyMlirExternalPass{pass.ptr});
};
auto externalPass = mlirCreateExternalPass(
passID, mlirStringRefCreate(name->data(), name->length()),
@@ -256,3 +266,6 @@ void mlir::python::populatePassManagerSubmodule(nb::module_ &m) {
"be passed to `parse` for round-tripping.");
registerMLIRError();
}
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/Pass.h b/mlir/lib/Bindings/Python/Pass.h
index 0221bd10e723e..1a311666ebecd 100644
--- a/mlir/lib/Bindings/Python/Pass.h
+++ b/mlir/lib/Bindings/Python/Pass.h
@@ -13,8 +13,9 @@
namespace mlir {
namespace python {
-
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
void populatePassManagerSubmodule(nanobind::module_ &m);
+}
} // namespace python
} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/Rewrite.cpp b/mlir/lib/Bindings/Python/Rewrite.cpp
index 89092b768c6ca..cfe3dd9434e3b 100644
--- a/mlir/lib/Bindings/Python/Rewrite.cpp
+++ b/mlir/lib/Bindings/Python/Rewrite.cpp
@@ -22,9 +22,11 @@
namespace nb = nanobind;
using namespace mlir;
using namespace nb::literals;
-using namespace mlir::python;
+using namespace mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN;
-namespace {
+namespace mlir {
+namespace python {
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
class PyPatternRewriter {
public:
@@ -60,6 +62,8 @@ class PyPatternRewriter {
PyMlirContextRef ctx;
};
+struct PyMlirPDLResultList : MlirPDLResultList {};
+
#if MLIR_ENABLE_PDL_IN_PATTERNMATCH
static nb::object objectFromPDLValue(MlirPDLValue value) {
if (MlirValue v = mlirPDLValueAsValue(value); !mlirValueIsNull(v))
@@ -118,7 +122,7 @@ class PyPDLPatternModule {
void *userData) -> MlirLogicalResult {
nb::handle f = nb::handle(static_cast<PyObject *>(userData));
return logicalResultFromObject(
- f(PyPatternRewriter(rewriter), results,
+ f(PyPatternRewriter(rewriter), PyMlirPDLResultList{results.ptr},
objectsFromPDLValues(nValues, values)));
},
fn.ptr());
@@ -133,7 +137,7 @@ class PyPDLPatternModule {
void *userData) -> MlirLogicalResult {
nb::handle f = nb::handle(static_cast<PyObject *>(userData));
return logicalResultFromObject(
- f(PyPatternRewriter(rewriter), results,
+ f(PyPatternRewriter(rewriter), PyMlirPDLResultList{results.ptr},
objectsFromPDLValues(nValues, values)));
},
fn.ptr());
@@ -223,10 +227,8 @@ class PyRewritePatternSet {
MlirContext ctx;
};
-} // namespace
-
/// Create the `mlir.rewrite` here.
-void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
+void populateRewriteSubmodule(nb::module_ &m) {
//----------------------------------------------------------------------------
// Mapping of the PatternRewriter
//----------------------------------------------------------------------------
@@ -293,10 +295,10 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
// Mapping of the PDLResultList and PDLModule
//----------------------------------------------------------------------------
#if MLIR_ENABLE_PDL_IN_PATTERNMATCH
- nb::class_<MlirPDLResultList>(m, "PDLResultList")
+ nb::class_<PyMlirPDLResultList>(m, "PDLResultList")
.def(
"append",
- [](MlirPDLResultList results, const PyValue &value) {
+ [](PyMlirPDLResultList results, const PyValue &value) {
mlirPDLResultListPushBackValue(results, value);
},
// clang-format off
@@ -305,7 +307,7 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
)
.def(
"append",
- [](MlirPDLResultList results, const PyOperation &op) {
+ [](PyMlirPDLResultList results, const PyOperation &op) {
mlirPDLResultListPushBackOperation(results, op);
},
// clang-format off
@@ -314,7 +316,7 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
)
.def(
"append",
- [](MlirPDLResultList results, const PyType &type) {
+ [](PyMlirPDLResultList results, const PyType &type) {
mlirPDLResultListPushBackType(results, type);
},
// clang-format off
@@ -323,7 +325,7 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
)
.def(
"append",
- [](MlirPDLResultList results, const PyAttribute &attr) {
+ [](PyMlirPDLResultList results, const PyAttribute &attr) {
mlirPDLResultListPushBackAttribute(results, attr);
},
// clang-format off
@@ -333,9 +335,9 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
nb::class_<PyPDLPatternModule>(m, "PDLModule")
.def(
"__init__",
- [](PyPDLPatternModule &self, MlirModule module) {
- new (&self)
- PyPDLPatternModule(mlirPDLPatternModuleFromModule(module));
+ [](PyPDLPatternModule &self, PyModule &module) {
+ new (&self) PyPDLPatternModule(
+ mlirPDLPatternModuleFromModule(module.get()));
},
// clang-format off
nb::sig("def __init__(self, module: " MAKE_MLIR_PYTHON_QUALNAME("ir.Module") ") -> None"),
@@ -394,9 +396,9 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
"results.")
.def(
"apply_patterns_and_fold_greedily",
- [](PyModule &module, MlirFrozenRewritePatternSet set) {
+ [](PyModule &module, PyFrozenRewritePatternSet &set) {
auto status =
- mlirApplyPatternsAndFoldGreedily(module.get(), set, {});
+ mlirApplyPatternsAndFoldGreedily(module.get(), set.get(), {});
if (mlirLogicalResultIsFailure(status))
throw std::runtime_error(
"pattern application failed to converge");
@@ -425,9 +427,9 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
"results.")
.def(
"apply_patterns_and_fold_greedily",
- [](PyOperationBase &op, MlirFrozenRewritePatternSet set) {
+ [](PyOperationBase &op, PyFrozenRewritePatternSet &set) {
auto status = mlirApplyPatternsAndFoldGreedilyWithOp(
- op.getOperation(), set, {});
+ op.getOperation(), set.get(), {});
if (mlirLogicalResultIsFailure(status))
throw std::runtime_error(
"pattern application failed to converge");
@@ -439,3 +441,6 @@ void mlir::python::populateRewriteSubmodule(nb::module_ &m) {
"Applys the given patterns to the given op greedily while folding "
"results.");
}
+} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
+} // namespace python
+} // namespace mlir
diff --git a/mlir/lib/Bindings/Python/Rewrite.h b/mlir/lib/Bindings/Python/Rewrite.h
index f8ffdc7bdc458..d287f19187708 100644
--- a/mlir/lib/Bindings/Python/Rewrite.h
+++ b/mlir/lib/Bindings/Python/Rewrite.h
@@ -13,9 +13,9 @@
namespace mlir {
namespace python {
-
+namespace MLIR_BINDINGS_PYTHON_DOMAIN {
void populateRewriteSubmodule(nanobind::module_ &m);
-
+}
} // namespace python
} // namespace mlir
diff --git a/mlir/python/CMakeLists.txt b/mlir/python/CMakeLists.txt
index b22d2ec75b3ba..2d2ae26bf3b28 100644
--- a/mlir/python/CMakeLists.txt
+++ b/mlir/python/CMakeLists.txt
@@ -3,6 +3,7 @@ include(AddMLIRPython)
# Specifies that all MLIR packages are co-located under the `MLIR_PYTHON_PACKAGE_PREFIX.`
# top level package (the API has been embedded in a relocatable way).
add_compile_definitions("MLIR_PYTHON_PACKAGE_PREFIX=${MLIR_PYTHON_PACKAGE_PREFIX}.")
+add_compile_definitions("MLIR_BINDINGS_PYTHON_DOMAIN=${MLIR_BINDINGS_PYTHON_NB_DOMAIN}")
set(MLIRPythonModules_ROOT_PREFIX "${MLIR_BINARY_DIR}/${MLIR_BINDINGS_PYTHON_INSTALL_PREFIX}")
set(PYTHON_SOURCE_DIR "${MLIR_SOURCE_DIR}/lib/Bindings/Python")
diff --git a/mlir/test/Examples/standalone/test.wheel.toy b/mlir/test/Examples/standalone/test.wheel.toy
index 55847f7430648..91fed38e28612 100644
--- a/mlir/test/Examples/standalone/test.wheel.toy
+++ b/mlir/test/Examples/standalone/test.wheel.toy
@@ -1,6 +1,10 @@
# There's no real issue with windows here, it's just that some CMake generated paths for targets end up being longer
# than 255 chars when combined with the fact that pip wants to install into a tmp directory buried under
# C/Users/ContainerAdministrator/AppData/Local/Temp.
+# UNSUPPORTED: target={{.*(windows).*}}
+# REQUIRES: expensive_checks
+# REQUIRES: non-shared-libs-build
+# REQUIRES: bindings-python
# RUN: export CMAKE_BUILD_TYPE=%cmake_build_type
# RUN: export CMAKE_CXX_COMPILER=%host_cxx
@@ -11,21 +15,21 @@
# RUN: export LLVM_USE_LINKER=%llvm_use_linker
# RUN: export MLIR_DIR="%mlir_cmake_dir"
-# RUN: %python -m pip install scikit-build-core
-# RUN: %python -m pip wheel "%mlir_src_root/examples/standalone" -w "%mlir_obj_root/wheelhouse" -v --no-build-isolation | tee %t
+# RUN: %python -m pip wheel "%mlir_src_root/examples/standalone" -w "%mlir_obj_root/wheelhouse" -v | tee %t
# RUN: rm -rf "%mlir_obj_root/standalone-python-bindings-install"
# RUN: %python -m pip install standalone_python_bindings -f "%mlir_obj_root/wheelhouse" --target "%mlir_obj_root/standalone-python-bindings-install" -v | tee -a %t
-# RUN: export PYTHONPATH="%mlir_obj_root/standalone-python-bindings-install"
-# RUN: %python "%mlir_src_root/examples/standalone/test/python/smoketest.py" nanobind | tee -a %t
+# RUN: export PYTHONPATH="%mlir_obj_root/standalone-python-bindings-install:%mlir_obj_root/python_packages/mlir_core"
+# RUN: %python "%mlir_src_root/examples/standalone/test/python/smoketest.py" test-upstream 2>&1 | tee -a %t
# RUN: FileCheck --input-file=%t %s
# CHECK: Successfully built standalone-python-bindings
+# CHECK-NOT: RuntimeWarning: nanobind: type '{{.*}}' was already registered!
+
# CHECK: module {
# CHECK: %[[C2:.*]] = arith.constant 2 : i32
# CHECK: %[[V0:.*]] = standalone.foo %[[C2]] : i32
# CHECK: }
-
diff --git a/mlir/test/python/lib/PythonTestModuleNanobind.cpp b/mlir/test/python/lib/PythonTestModuleNanobind.cpp
index c8b95e2316778..43573cbc305fa 100644
--- a/mlir/test/python/lib/PythonTestModuleNanobind.cpp
+++ b/mlir/test/python/lib/PythonTestModuleNanobind.cpp
@@ -27,7 +27,8 @@ static bool mlirTypeIsARankedIntegerTensor(MlirType t) {
mlirTypeIsAInteger(mlirShapedTypeGetElementType(t));
}
-struct PyTestType : mlir::python::PyConcreteType<PyTestType> {
+struct PyTestType
+ : mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteType<PyTestType> {
static constexpr IsAFunctionTy isaFunction = mlirTypeIsAPythonTestTestType;
static constexpr GetTypeIDFunctionTy getTypeIdFunction =
mlirPythonTestTestTypeGetTypeID;
@@ -37,7 +38,8 @@ struct PyTestType : mlir::python::PyConcreteType<PyTestType> {
static void bindDerived(ClassTy &c) {
c.def_static(
"get",
- [](mlir::python::DefaultingPyMlirContext context) {
+ [](mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyMlirContext
+ context) {
return PyTestType(context->getRef(),
mlirPythonTestTestTypeGet(context.get()->get()));
},
@@ -45,7 +47,9 @@ struct PyTestType : mlir::python::PyConcreteType<PyTestType> {
}
};
-class PyTestAttr : public mlir::python::PyConcreteAttribute<PyTestAttr> {
+class PyTestAttr
+ : public mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::PyConcreteAttribute<
+ PyTestAttr> {
public:
static constexpr IsAFunctionTy isaFunction =
mlirAttributeIsAPythonTestTestAttribute;
@@ -57,7 +61,8 @@ class PyTestAttr : public mlir::python::PyConcreteAttribute<PyTestAttr> {
static void bindDerived(ClassTy &c) {
c.def_static(
"get",
- [](mlir::python::DefaultingPyMlirContext context) {
+ [](mlir::python::MLIR_BINDINGS_PYTHON_DOMAIN::DefaultingPyMlirContext
+ context) {
return PyTestAttr(context->getRef(), mlirPythonTestTestAttributeGet(
context.get()->get()));
},
More information about the llvm-branch-commits
mailing list