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> {
187 src = mlir::python::irModule().attr(
"Context").attr(
"current");
197struct type_caster<MlirDialectRegistry> {
207 static handle
from_cpp(MlirDialectRegistry v, rv_policy,
208 cleanup_list *cleanup)
noexcept {
209 nanobind::object capsule = nanobind::steal<nanobind::object>(
211 return mlir::python::irModule()
212 .attr(
"DialectRegistry")
220struct type_caster<MlirLocation> {
226 src = mlir::python::irModule().attr(
"Location").attr(
"current");
235 cleanup_list *cleanup)
noexcept {
236 nanobind::object capsule =
238 return mlir::python::irModule()
247struct type_caster<MlirModule> {
252 return !mlirModuleIsNull(value);
257 cleanup_list *cleanup)
noexcept {
258 nanobind::object capsule =
260 return mlir::python::irModule()
269struct type_caster<MlirFrozenRewritePatternSet> {
271 MlirFrozenRewritePatternSet,
276 return value.ptr !=
nullptr;
280 static handle
from_cpp(MlirFrozenRewritePatternSet v, rv_policy,
282 nanobind::object capsule = nanobind::steal<nanobind::object>(
285 .attr(
"FrozenRewritePatternSet")
293struct type_caster<MlirOperation> {
299 return !mlirOperationIsNull(value);
304 cleanup_list *cleanup)
noexcept {
305 if (v.ptr ==
nullptr)
306 return nanobind::none();
307 nanobind::object capsule =
309 return mlir::python::irModule()
318struct type_caster<MlirValue> {
323 return !mlirValueIsNull(value);
328 cleanup_list *cleanup)
noexcept {
329 if (v.ptr ==
nullptr)
330 return nanobind::none();
331 nanobind::object capsule =
333 return mlir::python::irModule()
343struct type_caster<MlirPassManager> {
345 "passmanager.PassManager")))
357struct type_caster<MlirTypeID> {
367 cleanup_list *cleanup)
noexcept {
368 if (v.ptr ==
nullptr)
369 return nanobind::none();
370 nanobind::object capsule =
372 return mlir::python::irModule()
381struct type_caster<MlirType> {
391 cleanup_list *cleanup)
noexcept {
392 nanobind::object capsule =
394 return mlir::python::irModule()
407 cleanup_list *cleanup) noexcept {
408 return nanobind::str(s.data, s.length).release();
434 nanobind::object pyType =
435 nanobind::borrow<nanobind::object>((PyObject *)&PyType_Type);
436 nanobind::object metaclass = pyType(
superClass);
437 nanobind::dict attributes;
441 scope.attr(derivedClassName) =
thisClass;
442 thisClass.attr(
"__module__") = scope.attr(
"__name__");
445 template <
typename Func,
typename... Extra>
447 nanobind::object
cf = nanobind::cpp_function(
448 std::forward<Func>(f), nanobind::name(name), nanobind::is_method(),
454 template <
typename Func,
typename... Extra>
456 const Extra &...extra) {
457 nanobind::object
cf = nanobind::cpp_function(
458 std::forward<Func>(f), nanobind::name(name), nanobind::is_method(),
460 auto builtinProperty =
461 nanobind::borrow<nanobind::object>((PyObject *)&PyProperty_Type);
466 template <
typename Func,
typename... Extra>
468 const Extra &...extra) {
469 static_assert(!std::is_member_function_pointer<Func>::value,
470 "def_staticmethod(...) called with a non-static member "
472 nanobind::object
cf = nanobind::cpp_function(
473 std::forward<Func>(f),
474 nanobind::name(name),
480 template <
typename Func,
typename... Extra>
482 const Extra &...extra) {
483 static_assert(!std::is_member_function_pointer<Func>::value,
484 "def_classmethod(...) called with a non-static member "
486 nanobind::object
cf = nanobind::cpp_function(
487 std::forward<Func>(f),
488 nanobind::name(name),
491 nanobind::borrow<nanobind::object>(PyClassMethod_New(
cf.ptr()));
514 irModule().attr(
"Attribute"),
515 getTypeIDFunction) {}
523 const nanobind::object &superCls,
534 std::string captureTypeName(
536 nanobind::object newCf = nanobind::cpp_function(
537 [superCls, isaFunction, captureTypeName](
538 nanobind::object cls, nanobind::object otherAttribute) {
539 MlirAttribute rawAttribute;
540 if (!nanobind::try_cast<MlirAttribute>(otherAttribute,
542 !isaFunction(rawAttribute)) {
544 nanobind::cast<std::string>(nanobind::repr(otherAttribute));
545 throw std::invalid_argument(
546 (llvm::Twine(
"Cannot cast attribute to ") + captureTypeName +
547 " (from " + origRepr +
")")
550 nanobind::object self = superCls.attr(
"__new__")(cls, otherAttribute);
553 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
554 nanobind::arg(
"cast_from_attr"));
558 static const char kIsinstanceSig[] =
560 "ir")
".Attribute) -> bool";
563 [isaFunction](MlirAttribute other) {
return isaFunction(other); },
564 nanobind::arg(
"other_attribute"), nanobind::sig(kIsinstanceSig));
565 def(
"__repr__", [superCls, captureTypeName](nanobind::object self) {
566 return nanobind::repr(superCls(self))
567 .attr(
"replace")(superCls.attr(
"__name__"), captureTypeName);
569 if (getTypeIDFunction) {
572 [getTypeIDFunction]() {
return getTypeIDFunction(); },
579 getTypeIDFunction())(nanobind::cpp_function(
599 irModule().attr(
"Type"), getTypeIDFunction) {}
607 const nanobind::object &superCls,
618 std::string captureTypeName(
620 nanobind::object newCf = nanobind::cpp_function(
621 [superCls, isaFunction, captureTypeName](nanobind::object cls,
622 nanobind::object otherType) {
624 if (!nanobind::try_cast<MlirType>(otherType, rawType) ||
625 !isaFunction(rawType)) {
627 nanobind::cast<std::string>(nanobind::repr(otherType));
628 throw std::invalid_argument((llvm::Twine(
"Cannot cast type to ") +
629 captureTypeName +
" (from " +
633 nanobind::object self = superCls.attr(
"__new__")(cls, otherType);
636 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
637 nanobind::arg(
"cast_from_type"));
641 static const char kIsinstanceSig[] =
647 [isaFunction](MlirType other) {
return isaFunction(other); },
648 nanobind::arg(
"other_type"), nanobind::sig(kIsinstanceSig));
649 def(
"__repr__", [superCls, captureTypeName](nanobind::object self) {
650 return nanobind::cast<std::string>(
651 nanobind::repr(superCls(self))
652 .attr(
"replace")(superCls.attr(
"__name__"), captureTypeName));
654 if (getTypeIDFunction) {
662 [getTypeIDFunction]() {
return getTypeIDFunction(); },
669 getTypeIDFunction())(nanobind::cpp_function(
687 irModule().attr(
"Value")) {}
695 const nanobind::object &superCls)
705 std::string captureValueName(
707 nanobind::object newCf = nanobind::cpp_function(
708 [superCls, isaFunction, captureValueName](nanobind::object cls,
709 nanobind::object otherValue) {
711 if (!nanobind::try_cast<MlirValue>(otherValue, rawValue) ||
712 !isaFunction(rawValue)) {
714 nanobind::cast<std::string>(nanobind::repr(otherValue));
715 throw std::invalid_argument((llvm::Twine(
"Cannot cast value to ") +
716 captureValueName +
" (from " +
720 nanobind::object self = superCls.attr(
"__new__")(cls, otherValue);
723 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
724 nanobind::arg(
"cast_from_value"));
728 static const char kIsinstanceSig[] =
734 [isaFunction](MlirValue other) {
return isaFunction(other); },
735 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