19#ifndef MLIR_BINDINGS_PYTHON_NANOBINDADAPTORS_H
20#define MLIR_BINDINGS_PYTHON_NANOBINDADAPTORS_H
33#include "llvm/ADT/Twine.h"
43 typedef std::unique_ptr<T> (*F)();
45 explicit SafeInit(F init_fn) : initFn(init_fn) {}
48 if (T *
result = output.load()) {
56 std::unique_ptr<T> m = initFn();
58 nanobind::ft_lock_guard lock(mu);
59 if (T *
result = output.load()) {
69 nanobind::ft_mutex mu;
70 std::atomic<T *> output{
nullptr};
74nanobind::module_ &irModule() {
75 static SafeInit<nanobind::module_> init([]() {
76 return std::make_unique<nanobind::module_>(
100static std::optional<nanobind::object>
102 if (PyCapsule_CheckExact(apiObject.ptr()))
103 return nanobind::borrow<nanobind::object>(apiObject);
104 nanobind::object api =
118struct type_caster<MlirAffineMap> {
129 cleanup_list *cleanup)
noexcept {
130 nanobind::object capsule =
132 return mlir::python::irModule()
141struct type_caster<MlirAttribute> {
147 return !mlirAttributeIsNull(value);
152 cleanup_list *cleanup)
noexcept {
153 nanobind::object capsule =
155 return mlir::python::irModule()
165struct type_caster<MlirBlock> {
178struct type_caster<MlirContext> {
184 src = mlir::python::irModule().attr(
"Context").attr(
"current");
190 PyExc_RuntimeWarning,
191 "Passing None as MLIR Context is only allowed inside "
192 "the " MAKE_MLIR_PYTHON_QUALNAME(
"ir.Context")
" context manager.");
205struct type_caster<MlirDialectRegistry> {
215 static handle
from_cpp(MlirDialectRegistry v, rv_policy,
216 cleanup_list *cleanup)
noexcept {
217 nanobind::object capsule = nanobind::steal<nanobind::object>(
219 return mlir::python::irModule()
220 .attr(
"DialectRegistry")
228struct type_caster<MlirLocation> {
234 src = mlir::python::irModule().attr(
"Location").attr(
"current");
243 cleanup_list *cleanup)
noexcept {
244 nanobind::object capsule =
246 return mlir::python::irModule()
255struct type_caster<MlirModule> {
260 return !mlirModuleIsNull(value);
265 cleanup_list *cleanup)
noexcept {
266 nanobind::object capsule =
268 return mlir::python::irModule()
277struct type_caster<MlirFrozenRewritePatternSet> {
279 MlirFrozenRewritePatternSet,
284 return value.ptr !=
nullptr;
288 static handle
from_cpp(MlirFrozenRewritePatternSet v, rv_policy,
290 nanobind::object capsule = nanobind::steal<nanobind::object>(
293 .attr(
"FrozenRewritePatternSet")
301struct type_caster<MlirOperation> {
307 return !mlirOperationIsNull(value);
312 cleanup_list *cleanup)
noexcept {
313 if (v.ptr ==
nullptr)
314 return nanobind::none();
315 nanobind::object capsule =
317 return mlir::python::irModule()
326struct type_caster<MlirValue> {
331 return !mlirValueIsNull(value);
336 cleanup_list *cleanup)
noexcept {
337 if (v.ptr ==
nullptr)
338 return nanobind::none();
339 nanobind::object capsule =
341 return mlir::python::irModule()
351struct type_caster<MlirPassManager> {
353 "passmanager.PassManager")))
365struct type_caster<MlirTypeID> {
375 cleanup_list *cleanup)
noexcept {
376 if (v.ptr ==
nullptr)
377 return nanobind::none();
378 nanobind::object capsule =
380 return mlir::python::irModule()
389struct type_caster<MlirType> {
399 cleanup_list *cleanup)
noexcept {
400 nanobind::object capsule =
402 return mlir::python::irModule()
415 cleanup_list *cleanup) noexcept {
416 return nanobind::str(s.data, s.length).release();
442 nanobind::object pyType =
443 nanobind::borrow<nanobind::object>((PyObject *)&PyType_Type);
444 nanobind::object metaclass = pyType(
superClass);
445 nanobind::dict attributes;
449 scope.attr(derivedClassName) =
thisClass;
450 thisClass.attr(
"__module__") = scope.attr(
"__name__");
453 template <
typename Func,
typename... Extra>
455 nanobind::object
cf = nanobind::cpp_function(
456 std::forward<Func>(f), nanobind::name(name), nanobind::is_method(),
462 template <
typename Func,
typename... Extra>
464 const Extra &...extra) {
465 nanobind::object
cf = nanobind::cpp_function(
466 std::forward<Func>(f), nanobind::name(name), nanobind::is_method(),
468 auto builtinProperty =
469 nanobind::borrow<nanobind::object>((PyObject *)&PyProperty_Type);
474 template <
typename Func,
typename... Extra>
476 const Extra &...extra) {
477 static_assert(!std::is_member_function_pointer<Func>::value,
478 "def_staticmethod(...) called with a non-static member "
480 nanobind::object
cf = nanobind::cpp_function(
481 std::forward<Func>(f),
482 nanobind::name(name),
488 template <
typename Func,
typename... Extra>
490 const Extra &...extra) {
491 static_assert(!std::is_member_function_pointer<Func>::value,
492 "def_classmethod(...) called with a non-static member "
494 nanobind::object
cf = nanobind::cpp_function(
495 std::forward<Func>(f),
496 nanobind::name(name),
499 nanobind::borrow<nanobind::object>(PyClassMethod_New(
cf.ptr()));
522 irModule().attr(
"Attribute"),
523 getTypeIDFunction) {}
531 const nanobind::object &superCls,
542 std::string captureTypeName(
544 nanobind::object newCf = nanobind::cpp_function(
545 [superCls, isaFunction, captureTypeName](
546 nanobind::object cls, nanobind::object otherAttribute) {
547 MlirAttribute rawAttribute;
548 if (!nanobind::try_cast<MlirAttribute>(otherAttribute,
550 !isaFunction(rawAttribute)) {
552 nanobind::cast<std::string>(nanobind::repr(otherAttribute));
553 throw std::invalid_argument(
554 (llvm::Twine(
"Cannot cast attribute to ") + captureTypeName +
555 " (from " + origRepr +
")")
558 nanobind::object self = superCls.attr(
"__new__")(cls, otherAttribute);
561 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
562 nanobind::arg(
"cast_from_attr"));
566 static const char kIsinstanceSig[] =
568 "ir")
".Attribute) -> bool";
571 [isaFunction](MlirAttribute other) {
return isaFunction(other); },
572 nanobind::arg(
"other_attribute"), nanobind::sig(kIsinstanceSig));
573 def(
"__repr__", [superCls, captureTypeName](nanobind::object self) {
574 return nanobind::repr(superCls(self))
575 .attr(
"replace")(superCls.attr(
"__name__"), captureTypeName);
577 if (getTypeIDFunction) {
580 [getTypeIDFunction]() {
return getTypeIDFunction(); },
587 getTypeIDFunction())(nanobind::cpp_function(
607 irModule().attr(
"Type"), getTypeIDFunction) {}
615 const nanobind::object &superCls,
626 std::string captureTypeName(
628 nanobind::object newCf = nanobind::cpp_function(
629 [superCls, isaFunction, captureTypeName](nanobind::object cls,
630 nanobind::object otherType) {
632 if (!nanobind::try_cast<MlirType>(otherType, rawType) ||
633 !isaFunction(rawType)) {
635 nanobind::cast<std::string>(nanobind::repr(otherType));
636 throw std::invalid_argument((llvm::Twine(
"Cannot cast type to ") +
637 captureTypeName +
" (from " +
641 nanobind::object self = superCls.attr(
"__new__")(cls, otherType);
644 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
645 nanobind::arg(
"cast_from_type"));
649 static const char kIsinstanceSig[] =
655 [isaFunction](MlirType other) {
return isaFunction(other); },
656 nanobind::arg(
"other_type"), nanobind::sig(kIsinstanceSig));
657 def(
"__repr__", [superCls, captureTypeName](nanobind::object self) {
658 return nanobind::cast<std::string>(
659 nanobind::repr(superCls(self))
660 .attr(
"replace")(superCls.attr(
"__name__"), captureTypeName));
662 if (getTypeIDFunction) {
670 [getTypeIDFunction]() {
return getTypeIDFunction(); },
677 getTypeIDFunction())(nanobind::cpp_function(
695 irModule().attr(
"Value")) {}
703 const nanobind::object &superCls)
713 std::string captureValueName(
715 nanobind::object newCf = nanobind::cpp_function(
716 [superCls, isaFunction, captureValueName](nanobind::object cls,
717 nanobind::object otherValue) {
719 if (!nanobind::try_cast<MlirValue>(otherValue, rawValue) ||
720 !isaFunction(rawValue)) {
722 nanobind::cast<std::string>(nanobind::repr(otherValue));
723 throw std::invalid_argument((llvm::Twine(
"Cannot cast value to ") +
724 captureValueName +
" (from " +
728 nanobind::object self = superCls.attr(
"__new__")(cls, otherValue);
731 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
732 nanobind::arg(
"cast_from_value"));
736 static const char kIsinstanceSig[] =
742 [isaFunction](MlirValue other) {
return isaFunction(other); },
743 nanobind::arg(
"other_value"), nanobind::sig(kIsinstanceSig));
static PyObject * mlirPythonTypeIDToCapsule(MlirTypeID typeID)
Creates a capsule object encapsulating the raw C-API MlirTypeID.
#define MLIR_PYTHON_MAYBE_DOWNCAST_ATTR
Attribute on MLIR Python objects that expose a function for downcasting the corresponding Python obje...
static MlirBlock mlirPythonCapsuleToBlock(PyObject *capsule)
Extracts an MlirBlock from a capsule as produced from mlirPythonBlockToCapsule.
static MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule)
Extracts an MlirOperations from a capsule as produced from mlirPythonOperationToCapsule.
static MlirFrozenRewritePatternSet mlirPythonCapsuleToFrozenRewritePatternSet(PyObject *capsule)
Extracts an MlirFrozenRewritePatternSet from a capsule as produced from mlirPythonFrozenRewritePatter...
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
static MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule)
Extracts an MlirAttribute from a capsule as produced from mlirPythonAttributeToCapsule.
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
static MlirAffineMap mlirPythonCapsuleToAffineMap(PyObject *capsule)
Extracts an MlirAffineMap from a capsule as produced from mlirPythonAffineMapToCapsule.
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
static PyObject * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
static MlirModule mlirPythonCapsuleToModule(PyObject *capsule)
Extracts an MlirModule from a capsule as produced from mlirPythonModuleToCapsule.
static MlirContext mlirPythonCapsuleToContext(PyObject *capsule)
Extracts a MlirContext from a capsule as produced from mlirPythonContextToCapsule.
static MlirTypeID mlirPythonCapsuleToTypeID(PyObject *capsule)
Extracts an MlirTypeID from a capsule as produced from mlirPythonTypeIDToCapsule.
static PyObject * mlirPythonAffineMapToCapsule(MlirAffineMap affineMap)
Creates a capsule object encapsulating the raw C-API MlirAffineMap.
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
#define MAKE_MLIR_PYTHON_QUALNAME(local)
static MlirType mlirPythonCapsuleToType(PyObject *capsule)
Extracts an MlirType from a capsule as produced from mlirPythonTypeToCapsule.
static MlirValue mlirPythonCapsuleToValue(PyObject *capsule)
Extracts an MlirValue from a capsule as produced from mlirPythonValueToCapsule.
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
static MlirPassManager mlirPythonCapsuleToPassManager(PyObject *capsule)
Extracts an MlirPassManager from a capsule as produced from mlirPythonPassManagerToCapsule.
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
static PyObject * mlirPythonFrozenRewritePatternSetToCapsule(MlirFrozenRewritePatternSet pm)
Creates a capsule object encapsulating the raw C-API MlirFrozenRewritePatternSet.
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
#define MLIR_PYTHON_CAPI_TYPE_CASTER_REGISTER_ATTR
Attribute on main C extension module (_mlir) that corresponds to the type caster registration binding...
static PyObject * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
bool(*)(MlirAttribute) IsAFunctionTy
mlir_attribute_subclass(nanobind::handle scope, const char *attrClassName, IsAFunctionTy isaFunction, GetTypeIDFunctionTy getTypeIDFunction=nullptr)
Subclasses by looking up the super-class dynamically.
MlirTypeID(*)() GetTypeIDFunctionTy
mlir_attribute_subclass(nanobind::handle scope, const char *typeClassName, IsAFunctionTy isaFunction, const nanobind::object &superCls, GetTypeIDFunctionTy getTypeIDFunction=nullptr)
Subclasses with a provided mlir.ir.Attribute super-class.
mlir_type_subclass(nanobind::handle scope, const char *typeClassName, IsAFunctionTy isaFunction, const nanobind::object &superCls, GetTypeIDFunctionTy getTypeIDFunction=nullptr)
Subclasses with a provided mlir.ir.Type super-class.
MlirTypeID(*)() GetTypeIDFunctionTy
mlir_type_subclass(nanobind::handle scope, const char *typeClassName, IsAFunctionTy isaFunction, GetTypeIDFunctionTy getTypeIDFunction=nullptr)
Subclasses by looking up the super-class dynamically.
bool(*)(MlirType) IsAFunctionTy
mlir_value_subclass(nanobind::handle scope, const char *valueClassName, IsAFunctionTy isaFunction, const nanobind::object &superCls)
Subclasses with a provided mlir.ir.Value super-class.
bool(*)(MlirValue) IsAFunctionTy
mlir_value_subclass(nanobind::handle scope, const char *valueClassName, IsAFunctionTy isaFunction)
Subclasses by looking up the super-class dynamically.
pure_subclass & def(const char *name, Func &&f, const Extra &...extra)
pure_subclass & def_property_readonly(const char *name, Func &&f, const Extra &...extra)
pure_subclass(nanobind::handle scope, const char *derivedClassName, const nanobind::object &superClass)
pure_subclass & def_classmethod(const char *name, Func &&f, const Extra &...extra)
pure_subclass & def_staticmethod(const char *name, Func &&f, const Extra &...extra)
nanobind::object thisClass
nanobind::object get_class() const
nanobind::object superClass
static bool mlirPassManagerIsNull(MlirPassManager passManager)
Checks if a PassManager is null.
static bool mlirAffineMapIsNull(MlirAffineMap affineMap)
Checks whether an affine map is null.
static bool mlirTypeIsNull(MlirType type)
Checks whether a type is null.
static bool mlirContextIsNull(MlirContext context)
Checks whether a context is null.
static bool mlirBlockIsNull(MlirBlock block)
Checks whether a block is null.
static bool mlirLocationIsNull(MlirLocation location)
Checks if the location is null.
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
static bool mlirTypeIDIsNull(MlirTypeID typeID)
Checks whether a type id is null.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
static std::optional< nanobind::object > mlirApiObjectToCapsule(nanobind::handle apiObject)
Helper to convert a presumed MLIR API object to a capsule, accepting either an explicit Capsule (whic...
A pointer to a sized fragment of a string, not necessarily null-terminated.
static handle from_cpp(MlirAffineMap v, rv_policy, cleanup_list *cleanup) noexcept
uint8_t cleanup_list *cleanup noexcept
NB_TYPE_CASTER(MlirAffineMap, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.AffineMap"))) bool from_python(handle src
static handle from_cpp(MlirAttribute v, rv_policy, cleanup_list *cleanup) noexcept
uint8_t cleanup_list *cleanup noexcept
NB_TYPE_CASTER(MlirAttribute, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Attribute"))) bool from_python(handle src
uint8_t cleanup_list *cleanup noexcept
NB_TYPE_CASTER(MlirBlock, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Block"))) bool from_python(handle src
NB_TYPE_CASTER(MlirContext, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Context"))) bool from_python(handle src
uint8_t cleanup_list *cleanup noexcept
uint8_t cleanup_list *cleanup noexcept
NB_TYPE_CASTER(MlirDialectRegistry, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.DialectRegistry"))) bool from_python(handle src
static handle from_cpp(MlirDialectRegistry v, rv_policy, cleanup_list *cleanup) noexcept
NB_TYPE_CASTER(MlirFrozenRewritePatternSet, const_name(MAKE_MLIR_PYTHON_QUALNAME("rewrite.FrozenRewritePatternSet"))) bool from_python(handle src
static handle from_cpp(MlirFrozenRewritePatternSet v, rv_policy, handle) noexcept
uint8_t cleanup_list *cleanup noexcept
static handle from_cpp(MlirLocation v, rv_policy, cleanup_list *cleanup) noexcept
NB_TYPE_CASTER(MlirLocation, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Location"))) bool from_python(handle src
uint8_t cleanup_list *cleanup noexcept
uint8_t cleanup_list *cleanup noexcept
NB_TYPE_CASTER(MlirModule, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Module"))) bool from_python(handle src
static handle from_cpp(MlirModule v, rv_policy, cleanup_list *cleanup) noexcept
NB_TYPE_CASTER(MlirOperation, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Operation"))) bool from_python(handle src
uint8_t cleanup_list *cleanup noexcept
static handle from_cpp(MlirOperation v, rv_policy, cleanup_list *cleanup) noexcept
NB_TYPE_CASTER(MlirPassManager, const_name(MAKE_MLIR_PYTHON_QUALNAME("passmanager.PassManager"))) bool from_python(handle src
uint8_t cleanup_list *cleanup noexcept
static handle from_cpp(MlirStringRef s, rv_policy, cleanup_list *cleanup) noexcept
uint8_t cleanup_list *cleanup noexcept
static handle from_cpp(MlirTypeID v, rv_policy, cleanup_list *cleanup) noexcept
NB_TYPE_CASTER(MlirTypeID, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.TypeID"))) bool from_python(handle src
NB_TYPE_CASTER(MlirType, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Type"))) bool from_python(handle src
static handle from_cpp(MlirType t, rv_policy, cleanup_list *cleanup) noexcept
uint8_t cleanup_list *cleanup noexcept
uint8_t cleanup_list *cleanup noexcept
NB_TYPE_CASTER(MlirValue, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Value"))) bool from_python(handle src
static handle from_cpp(MlirValue v, rv_policy, cleanup_list *cleanup) noexcept