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> {
119 NB_TYPE_CASTER(MlirAffineMap, const_name(
"MlirAffineMap"))
120 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
128 cleanup_list *cleanup) noexcept {
129 nanobind::object capsule =
131 return mlir::python::irModule()
140 struct type_caster<MlirAttribute> {
141 NB_TYPE_CASTER(MlirAttribute, const_name(
"MlirAttribute"))
142 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
150 cleanup_list *cleanup) noexcept {
151 nanobind::object capsule =
153 return mlir::python::irModule()
163 struct type_caster<MlirBlock> {
164 NB_TYPE_CASTER(MlirBlock, const_name(
"MlirBlock"))
165 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
176 struct type_caster<MlirContext> {
177 NB_TYPE_CASTER(MlirContext, const_name(
"MlirContext"))
178 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
184 src = mlir::python::irModule().attr(
"Context").attr(
"current");
194 struct type_caster<MlirDialectRegistry> {
195 NB_TYPE_CASTER(MlirDialectRegistry, const_name(
"MlirDialectRegistry"))
196 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
203 static handle
from_cpp(MlirDialectRegistry v, rv_policy,
204 cleanup_list *cleanup) noexcept {
205 nanobind::object capsule = nanobind::steal<nanobind::object>(
207 return mlir::python::irModule()
208 .attr(
"DialectRegistry")
216 struct type_caster<MlirLocation> {
217 NB_TYPE_CASTER(MlirLocation, const_name(
"MlirLocation"))
218 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
221 src = mlir::python::irModule().attr(
"Location").attr(
"current");
230 cleanup_list *cleanup) noexcept {
231 nanobind::object capsule =
233 return mlir::python::irModule()
242 struct type_caster<MlirModule> {
243 NB_TYPE_CASTER(MlirModule, const_name(
"MlirModule"))
244 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
252 cleanup_list *cleanup) noexcept {
253 nanobind::object capsule =
255 return mlir::python::irModule()
264 struct type_caster<MlirFrozenRewritePatternSet> {
266 const_name(
"MlirFrozenRewritePatternSet"))
267 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
270 return value.ptr !=
nullptr;
274 static handle
from_cpp(MlirFrozenRewritePatternSet v, rv_policy,
276 nanobind::object capsule = nanobind::steal<nanobind::object>(
279 .attr(
"FrozenRewritePatternSet")
287 struct type_caster<MlirOperation> {
288 NB_TYPE_CASTER(MlirOperation, const_name(
"MlirOperation"))
289 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
297 cleanup_list *cleanup) noexcept {
298 if (v.ptr ==
nullptr)
299 return nanobind::none();
300 nanobind::object capsule =
302 return mlir::python::irModule()
311 struct type_caster<MlirValue> {
312 NB_TYPE_CASTER(MlirValue, const_name(
"MlirValue"))
313 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
321 cleanup_list *cleanup) noexcept {
322 if (v.ptr ==
nullptr)
323 return nanobind::none();
324 nanobind::object capsule =
326 return mlir::python::irModule()
336 struct type_caster<MlirPassManager> {
337 NB_TYPE_CASTER(MlirPassManager, const_name(
"MlirPassManager"))
338 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
349 struct type_caster<MlirTypeID> {
350 NB_TYPE_CASTER(MlirTypeID, const_name(
"MlirTypeID"))
351 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
359 cleanup_list *cleanup) noexcept {
360 if (v.ptr ==
nullptr)
361 return nanobind::none();
362 nanobind::object capsule =
364 return mlir::python::irModule()
373 struct type_caster<MlirType> {
374 NB_TYPE_CASTER(MlirType, const_name(
"MlirType"))
375 bool from_python(handle src, uint8_t flags, cleanup_list *cleanup) noexcept {
383 cleanup_list *cleanup) noexcept {
384 nanobind::object capsule =
386 return mlir::python::irModule()
399 cleanup_list *cleanup) noexcept {
400 return nanobind::str(s.data, s.length).release();
409 namespace nanobind_adaptors {
426 nanobind::object pyType =
427 nanobind::borrow<nanobind::object>((PyObject *)&PyType_Type);
428 nanobind::object metaclass = pyType(
superClass);
429 nanobind::dict attributes;
433 scope.attr(derivedClassName) =
thisClass;
434 thisClass.attr(
"__module__") = scope.attr(
"__name__");
437 template <
typename Func,
typename... Extra>
439 nanobind::object cf = nanobind::cpp_function(
440 std::forward<Func>(f), nanobind::name(name), nanobind::is_method(),
446 template <
typename Func,
typename... Extra>
448 const Extra &...extra) {
449 nanobind::object cf = nanobind::cpp_function(
450 std::forward<Func>(f), nanobind::name(name), nanobind::is_method(),
452 auto builtinProperty =
453 nanobind::borrow<nanobind::object>((PyObject *)&PyProperty_Type);
454 thisClass.attr(name) = builtinProperty(cf);
458 template <
typename Func,
typename... Extra>
460 const Extra &...extra) {
461 static_assert(!std::is_member_function_pointer<Func>::value,
462 "def_staticmethod(...) called with a non-static member "
464 nanobind::object cf = nanobind::cpp_function(
465 std::forward<Func>(f),
466 nanobind::name(name),
472 template <
typename Func,
typename... Extra>
474 const Extra &...extra) {
475 static_assert(!std::is_member_function_pointer<Func>::value,
476 "def_classmethod(...) called with a non-static member "
478 nanobind::object cf = nanobind::cpp_function(
479 std::forward<Func>(f),
480 nanobind::name(name),
483 nanobind::borrow<nanobind::object>(PyClassMethod_New(cf.ptr()));
506 irModule().attr(
"Attribute"),
507 getTypeIDFunction) {}
515 const nanobind::object &superCls,
526 std::string captureTypeName(
528 nanobind::object newCf = nanobind::cpp_function(
529 [superCls, isaFunction, captureTypeName](
530 nanobind::object cls, nanobind::object otherAttribute) {
531 MlirAttribute rawAttribute;
532 if (!nanobind::try_cast<MlirAttribute>(otherAttribute,
534 !isaFunction(rawAttribute)) {
536 nanobind::cast<std::string>(nanobind::repr(otherAttribute));
537 throw std::invalid_argument(
538 (llvm::Twine(
"Cannot cast attribute to ") + captureTypeName +
539 " (from " + origRepr +
")")
542 nanobind::object
self = superCls.attr(
"__new__")(cls, otherAttribute);
545 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
546 nanobind::arg(
"cast_from_attr"));
550 static const char kIsinstanceSig[] =
552 "ir")
".Attribute) -> bool";
555 [isaFunction](MlirAttribute other) {
return isaFunction(other); },
556 nanobind::arg(
"other_attribute"), nanobind::sig(kIsinstanceSig));
557 def(
"__repr__", [superCls, captureTypeName](nanobind::object
self) {
558 return nanobind::repr(superCls(
self))
559 .attr(
"replace")(superCls.attr(
"__name__"), captureTypeName);
561 if (getTypeIDFunction) {
564 [getTypeIDFunction]() {
return getTypeIDFunction(); },
571 getTypeIDFunction())(nanobind::cpp_function(
591 irModule().attr(
"Type"), getTypeIDFunction) {}
599 const nanobind::object &superCls,
610 std::string captureTypeName(
612 nanobind::object newCf = nanobind::cpp_function(
613 [superCls, isaFunction, captureTypeName](nanobind::object cls,
614 nanobind::object otherType) {
616 if (!nanobind::try_cast<MlirType>(otherType, rawType) ||
617 !isaFunction(rawType)) {
619 nanobind::cast<std::string>(nanobind::repr(otherType));
620 throw std::invalid_argument((llvm::Twine(
"Cannot cast type to ") +
621 captureTypeName +
" (from " +
625 nanobind::object
self = superCls.attr(
"__new__")(cls, otherType);
628 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
629 nanobind::arg(
"cast_from_type"));
633 static const char kIsinstanceSig[] =
639 [isaFunction](MlirType other) {
return isaFunction(other); },
640 nanobind::arg(
"other_type"), nanobind::sig(kIsinstanceSig));
641 def(
"__repr__", [superCls, captureTypeName](nanobind::object
self) {
642 return nanobind::cast<std::string>(
643 nanobind::repr(superCls(
self))
644 .attr(
"replace")(superCls.attr(
"__name__"), captureTypeName));
646 if (getTypeIDFunction) {
654 [getTypeIDFunction]() {
return getTypeIDFunction(); },
661 getTypeIDFunction())(nanobind::cpp_function(
679 irModule().attr(
"Value")) {}
687 const nanobind::object &superCls)
697 std::string captureValueName(
699 nanobind::object newCf = nanobind::cpp_function(
700 [superCls, isaFunction, captureValueName](nanobind::object cls,
701 nanobind::object otherValue) {
703 if (!nanobind::try_cast<MlirValue>(otherValue, rawValue) ||
704 !isaFunction(rawValue)) {
706 nanobind::cast<std::string>(nanobind::repr(otherValue));
707 throw std::invalid_argument((llvm::Twine(
"Cannot cast value to ") +
708 captureValueName +
" (from " +
712 nanobind::object
self = superCls.attr(
"__new__")(cls, otherValue);
715 nanobind::name(
"__new__"), nanobind::arg(
"cls"),
716 nanobind::arg(
"cast_from_value"));
720 static const char kIsinstanceSig[] =
726 [isaFunction](MlirValue other) {
return isaFunction(other); },
727 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
static handle from_cpp(MlirAttribute v, rv_policy, cleanup_list *cleanup) noexcept
static handle from_cpp(MlirDialectRegistry v, rv_policy, cleanup_list *cleanup) noexcept
NB_TYPE_CASTER(MlirFrozenRewritePatternSet, const_name("MlirFrozenRewritePatternSet")) 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
static handle from_cpp(MlirModule v, rv_policy, cleanup_list *cleanup) noexcept
static handle from_cpp(MlirOperation v, rv_policy, cleanup_list *cleanup) noexcept
static handle from_cpp(MlirTypeID v, rv_policy, cleanup_list *cleanup) noexcept
static handle from_cpp(MlirType t, rv_policy, cleanup_list *cleanup) noexcept
static handle from_cpp(MlirValue v, rv_policy, cleanup_list *cleanup) noexcept