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};
74 nanobind::module_ &irModule() {
75 static SafeInit<nanobind::module_> init([]() {
76 return std::make_unique<nanobind::module_>(
100 static std::optional<nanobind::object>
102 if (PyCapsule_CheckExact(apiObject.ptr()))
103 return nanobind::borrow<nanobind::object>(apiObject);
104 nanobind::object api =
118 struct type_caster<MlirAffineMap> {
121 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
129 cleanup_list *cleanup) noexcept {
130 nanobind::object capsule =
132 return mlir::python::irModule()
141 struct type_caster<MlirAttribute> {
144 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
152 cleanup_list *cleanup) noexcept {
153 nanobind::object capsule =
155 return mlir::python::irModule()
165 struct type_caster<MlirBlock> {
167 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
178 struct type_caster<MlirContext> {
181 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
187 src = mlir::python::irModule().attr(
"Context").attr(
"current");
197 struct type_caster<MlirDialectRegistry> {
200 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
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")
220 struct type_caster<MlirLocation> {
223 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
226 src = mlir::python::irModule().attr(
"Location").attr(
"current");
235 cleanup_list *cleanup) noexcept {
236 nanobind::object capsule =
238 return mlir::python::irModule()
247 struct type_caster<MlirModule> {
249 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
257 cleanup_list *cleanup) noexcept {
258 nanobind::object capsule =
260 return mlir::python::irModule()
269 struct type_caster<MlirFrozenRewritePatternSet> {
271 MlirFrozenRewritePatternSet,
273 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
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")
293 struct type_caster<MlirOperation> {
296 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
304 cleanup_list *cleanup) noexcept {
305 if (v.ptr ==
nullptr)
306 return nanobind::none();
307 nanobind::object capsule =
309 return mlir::python::irModule()
318 struct type_caster<MlirValue> {
320 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
328 cleanup_list *cleanup) noexcept {
329 if (v.ptr ==
nullptr)
330 return nanobind::none();
331 nanobind::object capsule =
333 return mlir::python::irModule()
343 struct type_caster<MlirPassManager> {
345 "passmanager.PassManager")))
346 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
357 struct type_caster<MlirTypeID> {
359 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
367 cleanup_list *cleanup) noexcept {
368 if (v.ptr ==
nullptr)
369 return nanobind::none();
370 nanobind::object capsule =
372 return mlir::python::irModule()
381 struct type_caster<MlirType> {
383 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
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();
417 namespace nanobind_adaptors {
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);
462 thisClass.attr(name) = builtinProperty(cf);
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 * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
#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 PyObject * mlirPythonTypeIDToCapsule(MlirTypeID typeID)
Creates a capsule object encapsulating the raw C-API MlirTypeID.
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 * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
static MlirAffineMap mlirPythonCapsuleToAffineMap(PyObject *capsule)
Extracts an MlirAffineMap from a capsule as produced from mlirPythonAffineMapToCapsule.
#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 * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
#define MAKE_MLIR_PYTHON_QUALNAME(local)
static PyObject * mlirPythonFrozenRewritePatternSetToCapsule(MlirFrozenRewritePatternSet pm)
Creates a capsule object encapsulating the raw C-API MlirFrozenRewritePatternSet.
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 * mlirPythonAffineMapToCapsule(MlirAffineMap affineMap)
Creates a capsule object encapsulating the raw C-API MlirAffineMap.
static MlirPassManager mlirPythonCapsuleToPassManager(PyObject *capsule)
Extracts an MlirPassManager from a capsule as produced from mlirPythonPassManagerToCapsule.
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
#define MLIR_PYTHON_CAPI_TYPE_CASTER_REGISTER_ATTR
Attribute on main C extension module (_mlir) that corresponds to the type caster registration binding...
Creates a custom subclass of mlir.ir.Attribute, implementing a casting constructor and type checking ...
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.
Creates a custom subclass of mlir.ir.Type, implementing a casting constructor and type checking metho...
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
Creates a custom subclass of mlir.ir.Value, implementing a casting constructor and type checking meth...
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.
Provides a facility like nanobind::class_ for defining a new class in a scope, but this allows extens...
pure_subclass & def(const char *name, Func &&f, const Extra &...extra)
pure_subclass & def_classmethod(const char *name, Func &&f, const Extra &...extra)
pure_subclass(nanobind::handle scope, const char *derivedClassName, const nanobind::object &superClass)
pure_subclass & def_property_readonly(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 mlirAttributeIsNull(MlirAttribute attr)
Checks whether an attribute is null.
static bool mlirModuleIsNull(MlirModule module)
Checks whether a module is null.
static bool mlirValueIsNull(MlirValue value)
Returns whether the value 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 mlirOperationIsNull(MlirOperation op)
Checks whether the underlying operation 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
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
NB_TYPE_CASTER(MlirAttribute, const_name(MAKE_MLIR_PYTHON_QUALNAME("ir.Attribute"))) bool from_python(handle src
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
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
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
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
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
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
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