MLIR  16.0.0git
PybindAdaptors.h
Go to the documentation of this file.
1 //===- PybindAdaptors.h - Adaptors for interop with MLIR APIs -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 // This file contains adaptors for clients of the core MLIR Python APIs to
9 // interop via MLIR CAPI types. The facilities here do not depend on
10 // implementation details of the MLIR Python API and do not introduce C++-level
11 // dependencies with it (requiring only Python and CAPI-level dependencies).
12 //
13 // It is encouraged to be used both in-tree and out-of-tree. For in-tree use
14 // cases, it should be used for dialect implementations (versus relying on
15 // Pybind-based internals of the core libraries).
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef MLIR_BINDINGS_PYTHON_PYBINDADAPTORS_H
19 #define MLIR_BINDINGS_PYTHON_PYBINDADAPTORS_H
20 
21 #include <pybind11/pybind11.h>
22 #include <pybind11/pytypes.h>
23 #include <pybind11/stl.h>
24 
26 #include "mlir-c/IR.h"
27 
28 #include "llvm/ADT/Optional.h"
29 #include "llvm/ADT/Twine.h"
30 
31 namespace py = pybind11;
32 
33 // Raw CAPI type casters need to be declared before use, so always include them
34 // first.
35 namespace pybind11 {
36 namespace detail {
37 
38 template <typename T>
39 struct type_caster<llvm::Optional<T>> : optional_caster<llvm::Optional<T>> {};
40 
41 /// Helper to convert a presumed MLIR API object to a capsule, accepting either
42 /// an explicit Capsule (which can happen when two C APIs are communicating
43 /// directly via Python) or indirectly by querying the MLIR_PYTHON_CAPI_PTR_ATTR
44 /// attribute (through which supported MLIR Python API objects export their
45 /// contained API pointer as a capsule). Throws a type error if the object is
46 /// neither. This is intended to be used from type casters, which are invoked
47 /// with a raw handle (unowned). The returned object's lifetime may not extend
48 /// beyond the apiObject handle without explicitly having its refcount increased
49 /// (i.e. on return).
50 static py::object mlirApiObjectToCapsule(py::handle apiObject) {
51  if (PyCapsule_CheckExact(apiObject.ptr()))
52  return py::reinterpret_borrow<py::object>(apiObject);
53  if (!py::hasattr(apiObject, MLIR_PYTHON_CAPI_PTR_ATTR)) {
54  auto repr = py::repr(apiObject).cast<std::string>();
55  throw py::type_error(
56  (llvm::Twine("Expected an MLIR object (got ") + repr + ").").str());
57  }
58  return apiObject.attr(MLIR_PYTHON_CAPI_PTR_ATTR);
59 }
60 
61 // Note: Currently all of the following support cast from py::object to the
62 // Mlir* C-API type, but only a few light-weight, context-bound ones
63 // implicitly cast the other way because the use case has not yet emerged and
64 // ownership is unclear.
65 
66 /// Casts object <-> MlirAffineMap.
67 template <>
68 struct type_caster<MlirAffineMap> {
69  PYBIND11_TYPE_CASTER(MlirAffineMap, _("MlirAffineMap"));
70  bool load(handle src, bool) {
71  py::object capsule = mlirApiObjectToCapsule(src);
72  value = mlirPythonCapsuleToAffineMap(capsule.ptr());
74  return false;
75  }
76  return !mlirAffineMapIsNull(value);
77  }
78  static handle cast(MlirAffineMap v, return_value_policy, handle) {
79  py::object capsule =
80  py::reinterpret_steal<py::object>(mlirPythonAffineMapToCapsule(v));
81  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
82  .attr("AffineMap")
83  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
84  .release();
85  }
86 };
87 
88 /// Casts object <-> MlirAttribute.
89 template <>
90 struct type_caster<MlirAttribute> {
91  PYBIND11_TYPE_CASTER(MlirAttribute, _("MlirAttribute"));
92  bool load(handle src, bool) {
93  py::object capsule = mlirApiObjectToCapsule(src);
94  value = mlirPythonCapsuleToAttribute(capsule.ptr());
95  return !mlirAttributeIsNull(value);
96  }
97  static handle cast(MlirAttribute v, return_value_policy, handle) {
98  py::object capsule =
99  py::reinterpret_steal<py::object>(mlirPythonAttributeToCapsule(v));
100  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
101  .attr("Attribute")
102  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
103  .release();
104  }
105 };
106 
107 /// Casts object -> MlirContext.
108 template <>
109 struct type_caster<MlirContext> {
110  PYBIND11_TYPE_CASTER(MlirContext, _("MlirContext"));
111  bool load(handle src, bool) {
112  if (src.is_none()) {
113  // Gets the current thread-bound context.
114  // TODO: This raises an error of "No current context" currently.
115  // Update the implementation to pretty-print the helpful error that the
116  // core implementations print in this case.
117  src = py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
118  .attr("Context")
119  .attr("current");
120  }
121  py::object capsule = mlirApiObjectToCapsule(src);
122  value = mlirPythonCapsuleToContext(capsule.ptr());
123  return !mlirContextIsNull(value);
124  }
125 };
126 
127 /// Casts object <-> MlirDialectRegistry.
128 template <>
129 struct type_caster<MlirDialectRegistry> {
130  PYBIND11_TYPE_CASTER(MlirDialectRegistry, _("MlirDialectRegistry"));
131  bool load(handle src, bool) {
132  py::object capsule = mlirApiObjectToCapsule(src);
133  value = mlirPythonCapsuleToDialectRegistry(capsule.ptr());
135  }
136  static handle cast(MlirDialectRegistry v, return_value_policy, handle) {
137  py::object capsule = py::reinterpret_steal<py::object>(
139  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
140  .attr("DialectRegistry")
141  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
142  .release();
143  }
144 };
145 
146 /// Casts object <-> MlirLocation.
147 template <>
148 struct type_caster<MlirLocation> {
149  PYBIND11_TYPE_CASTER(MlirLocation, _("MlirLocation"));
150  bool load(handle src, bool) {
151  if (src.is_none()) {
152  // Gets the current thread-bound context.
153  src = py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
154  .attr("Location")
155  .attr("current");
156  }
157  py::object capsule = mlirApiObjectToCapsule(src);
158  value = mlirPythonCapsuleToLocation(capsule.ptr());
159  return !mlirLocationIsNull(value);
160  }
161  static handle cast(MlirLocation v, return_value_policy, handle) {
162  py::object capsule =
163  py::reinterpret_steal<py::object>(mlirPythonLocationToCapsule(v));
164  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
165  .attr("Location")
166  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
167  .release();
168  }
169 };
170 
171 /// Casts object <-> MlirModule.
172 template <>
173 struct type_caster<MlirModule> {
174  PYBIND11_TYPE_CASTER(MlirModule, _("MlirModule"));
175  bool load(handle src, bool) {
176  py::object capsule = mlirApiObjectToCapsule(src);
177  value = mlirPythonCapsuleToModule(capsule.ptr());
178  return !mlirModuleIsNull(value);
179  }
180  static handle cast(MlirModule v, return_value_policy, handle) {
181  py::object capsule =
182  py::reinterpret_steal<py::object>(mlirPythonModuleToCapsule(v));
183  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
184  .attr("Module")
185  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
186  .release();
187  };
188 };
189 
190 /// Casts object <-> MlirOperation.
191 template <>
192 struct type_caster<MlirOperation> {
193  PYBIND11_TYPE_CASTER(MlirOperation, _("MlirOperation"));
194  bool load(handle src, bool) {
195  py::object capsule = mlirApiObjectToCapsule(src);
196  value = mlirPythonCapsuleToOperation(capsule.ptr());
197  return !mlirOperationIsNull(value);
198  }
199  static handle cast(MlirOperation v, return_value_policy, handle) {
200  if (v.ptr == nullptr)
201  return py::none();
202  py::object capsule =
203  py::reinterpret_steal<py::object>(mlirPythonOperationToCapsule(v));
204  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
205  .attr("Operation")
206  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
207  .release();
208  };
209 };
210 
211 /// Casts object <-> MlirValue.
212 template <>
213 struct type_caster<MlirValue> {
214  PYBIND11_TYPE_CASTER(MlirValue, _("MlirValue"));
215  bool load(handle src, bool) {
216  py::object capsule = mlirApiObjectToCapsule(src);
217  value = mlirPythonCapsuleToValue(capsule.ptr());
218  return !mlirValueIsNull(value);
219  }
220  static handle cast(MlirValue v, return_value_policy, handle) {
221  if (v.ptr == nullptr)
222  return py::none();
223  py::object capsule =
224  py::reinterpret_steal<py::object>(mlirPythonValueToCapsule(v));
225  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
226  .attr("Value")
227  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
228  .release();
229  };
230 };
231 
232 /// Casts object -> MlirPassManager.
233 template <>
234 struct type_caster<MlirPassManager> {
235  PYBIND11_TYPE_CASTER(MlirPassManager, _("MlirPassManager"));
236  bool load(handle src, bool) {
237  py::object capsule = mlirApiObjectToCapsule(src);
238  value = mlirPythonCapsuleToPassManager(capsule.ptr());
239  return !mlirPassManagerIsNull(value);
240  }
241 };
242 
243 /// Casts object <-> MlirType.
244 template <>
245 struct type_caster<MlirType> {
246  PYBIND11_TYPE_CASTER(MlirType, _("MlirType"));
247  bool load(handle src, bool) {
248  py::object capsule = mlirApiObjectToCapsule(src);
249  value = mlirPythonCapsuleToType(capsule.ptr());
250  return !mlirTypeIsNull(value);
251  }
252  static handle cast(MlirType t, return_value_policy, handle) {
253  py::object capsule =
254  py::reinterpret_steal<py::object>(mlirPythonTypeToCapsule(t));
255  return py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
256  .attr("Type")
257  .attr(MLIR_PYTHON_CAPI_FACTORY_ATTR)(capsule)
258  .release();
259  }
260 };
261 
262 } // namespace detail
263 } // namespace pybind11
264 
265 namespace mlir {
266 namespace python {
267 namespace adaptors {
268 
269 /// Provides a facility like py::class_ for defining a new class in a scope,
270 /// but this allows extension of an arbitrary Python class, defining methods
271 /// on it is a similar way. Classes defined in this way are very similar to
272 /// if defined in Python in the usual way but use Pybind11 machinery to do
273 /// it. These are not "real" Pybind11 classes but pure Python classes with no
274 /// relation to a concrete C++ class.
275 ///
276 /// Derived from a discussion upstream:
277 /// https://github.com/pybind/pybind11/issues/1193
278 /// (plus a fair amount of extra curricular poking)
279 /// TODO: If this proves useful, see about including it in pybind11.
281 public:
282  pure_subclass(py::handle scope, const char *derivedClassName,
283  const py::object &superClass) {
284  py::object pyType =
285  py::reinterpret_borrow<py::object>((PyObject *)&PyType_Type);
286  py::object metaclass = pyType(superClass);
287  py::dict attributes;
288 
289  thisClass =
290  metaclass(derivedClassName, py::make_tuple(superClass), attributes);
291  scope.attr(derivedClassName) = thisClass;
292  }
293 
294  template <typename Func, typename... Extra>
295  pure_subclass &def(const char *name, Func &&f, const Extra &...extra) {
296  py::cpp_function cf(
297  std::forward<Func>(f), py::name(name), py::is_method(thisClass),
298  py::sibling(py::getattr(thisClass, name, py::none())), extra...);
299  thisClass.attr(cf.name()) = cf;
300  return *this;
301  }
302 
303  template <typename Func, typename... Extra>
304  pure_subclass &def_property_readonly(const char *name, Func &&f,
305  const Extra &...extra) {
306  py::cpp_function cf(
307  std::forward<Func>(f), py::name(name), py::is_method(thisClass),
308  py::sibling(py::getattr(thisClass, name, py::none())), extra...);
309  auto builtinProperty =
310  py::reinterpret_borrow<py::object>((PyObject *)&PyProperty_Type);
311  thisClass.attr(name) = builtinProperty(cf);
312  return *this;
313  }
314 
315  template <typename Func, typename... Extra>
316  pure_subclass &def_staticmethod(const char *name, Func &&f,
317  const Extra &...extra) {
319  "def_staticmethod(...) called with a non-static member "
320  "function pointer");
321  py::cpp_function cf(
322  std::forward<Func>(f), py::name(name), py::scope(thisClass),
323  py::sibling(py::getattr(thisClass, name, py::none())), extra...);
324  thisClass.attr(cf.name()) = py::staticmethod(cf);
325  return *this;
326  }
327 
328  template <typename Func, typename... Extra>
329  pure_subclass &def_classmethod(const char *name, Func &&f,
330  const Extra &...extra) {
332  "def_classmethod(...) called with a non-static member "
333  "function pointer");
334  py::cpp_function cf(
335  std::forward<Func>(f), py::name(name), py::scope(thisClass),
336  py::sibling(py::getattr(thisClass, name, py::none())), extra...);
337  thisClass.attr(cf.name()) =
338  py::reinterpret_borrow<py::object>(PyClassMethod_New(cf.ptr()));
339  return *this;
340  }
341 
342  py::object get_class() const { return thisClass; }
343 
344 protected:
345  py::object superClass;
346  py::object thisClass;
347 };
348 
349 /// Creates a custom subclass of mlir.ir.Attribute, implementing a casting
350 /// constructor and type checking methods.
352 public:
353  using IsAFunctionTy = bool (*)(MlirAttribute);
354 
355  /// Subclasses by looking up the super-class dynamically.
356  mlir_attribute_subclass(py::handle scope, const char *attrClassName,
357  IsAFunctionTy isaFunction)
359  scope, attrClassName, isaFunction,
360  py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir"))
361  .attr("Attribute")) {}
362 
363  /// Subclasses with a provided mlir.ir.Attribute super-class. This must
364  /// be used if the subclass is being defined in the same extension module
365  /// as the mlir.ir class (otherwise, it will trigger a recursive
366  /// initialization).
367  mlir_attribute_subclass(py::handle scope, const char *typeClassName,
368  IsAFunctionTy isaFunction, const py::object &superCls)
369  : pure_subclass(scope, typeClassName, superCls) {
370  // Casting constructor. Note that it hard, if not impossible, to properly
371  // call chain to parent `__init__` in pybind11 due to its special handling
372  // for init functions that don't have a fully constructed self-reference,
373  // which makes it impossible to forward it to `__init__` of a superclass.
374  // Instead, provide a custom `__new__` and call that of a superclass, which
375  // eventually calls `__init__` of the superclass. Since attribute subclasses
376  // have no additional members, we can just return the instance thus created
377  // without amending it.
378  std::string captureTypeName(
379  typeClassName); // As string in case if typeClassName is not static.
380  py::cpp_function newCf(
381  [superCls, isaFunction, captureTypeName](py::object cls,
382  py::object otherAttribute) {
383  MlirAttribute rawAttribute = py::cast<MlirAttribute>(otherAttribute);
384  if (!isaFunction(rawAttribute)) {
385  auto origRepr = py::repr(otherAttribute).cast<std::string>();
386  throw std::invalid_argument(
387  (llvm::Twine("Cannot cast attribute to ") + captureTypeName +
388  " (from " + origRepr + ")")
389  .str());
390  }
391  py::object self = superCls.attr("__new__")(cls, otherAttribute);
392  return self;
393  },
394  py::name("__new__"), py::arg("cls"), py::arg("cast_from_attr"));
395  thisClass.attr("__new__") = newCf;
396 
397  // 'isinstance' method.
399  "isinstance",
400  [isaFunction](MlirAttribute other) { return isaFunction(other); },
401  py::arg("other_attribute"));
402  }
403 };
404 
405 /// Creates a custom subclass of mlir.ir.Type, implementing a casting
406 /// constructor and type checking methods.
408 public:
409  using IsAFunctionTy = bool (*)(MlirType);
410 
411  /// Subclasses by looking up the super-class dynamically.
412  mlir_type_subclass(py::handle scope, const char *typeClassName,
413  IsAFunctionTy isaFunction)
415  scope, typeClassName, isaFunction,
416  py::module::import(MAKE_MLIR_PYTHON_QUALNAME("ir")).attr("Type")) {}
417 
418  /// Subclasses with a provided mlir.ir.Type super-class. This must
419  /// be used if the subclass is being defined in the same extension module
420  /// as the mlir.ir class (otherwise, it will trigger a recursive
421  /// initialization).
422  mlir_type_subclass(py::handle scope, const char *typeClassName,
423  IsAFunctionTy isaFunction, const py::object &superCls)
424  : pure_subclass(scope, typeClassName, superCls) {
425  // Casting constructor. Note that it hard, if not impossible, to properly
426  // call chain to parent `__init__` in pybind11 due to its special handling
427  // for init functions that don't have a fully constructed self-reference,
428  // which makes it impossible to forward it to `__init__` of a superclass.
429  // Instead, provide a custom `__new__` and call that of a superclass, which
430  // eventually calls `__init__` of the superclass. Since attribute subclasses
431  // have no additional members, we can just return the instance thus created
432  // without amending it.
433  std::string captureTypeName(
434  typeClassName); // As string in case if typeClassName is not static.
435  py::cpp_function newCf(
436  [superCls, isaFunction, captureTypeName](py::object cls,
437  py::object otherType) {
438  MlirType rawType = py::cast<MlirType>(otherType);
439  if (!isaFunction(rawType)) {
440  auto origRepr = py::repr(otherType).cast<std::string>();
441  throw std::invalid_argument((llvm::Twine("Cannot cast type to ") +
442  captureTypeName + " (from " +
443  origRepr + ")")
444  .str());
445  }
446  py::object self = superCls.attr("__new__")(cls, otherType);
447  return self;
448  },
449  py::name("__new__"), py::arg("cls"), py::arg("cast_from_type"));
450  thisClass.attr("__new__") = newCf;
451 
452  // 'isinstance' method.
454  "isinstance",
455  [isaFunction](MlirType other) { return isaFunction(other); },
456  py::arg("other_type"));
457  }
458 };
459 
460 } // namespace adaptors
461 } // namespace python
462 } // namespace mlir
463 
464 #endif // MLIR_BINDINGS_PYTHON_PYBINDADAPTORS_H
static constexpr const bool value
static PyObject * mlirPythonModuleToCapsule(MlirModule module)
Creates a capsule object encapsulating the raw C-API MlirModule.
Definition: Interop.h:220
static MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule)
Extracts an MlirOperations from a capsule as produced from mlirPythonOperationToCapsule.
Definition: Interop.h:265
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
Definition: Interop.h:93
static MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule)
Extracts an MlirAttribute from a capsule as produced from mlirPythonAttributeToCapsule.
Definition: Interop.h:153
static PyObject * mlirPythonAttributeToCapsule(MlirAttribute attribute)
Creates a capsule object encapsulating the raw C-API MlirAttribute.
Definition: Interop.h:144
static PyObject * mlirPythonLocationToCapsule(MlirLocation loc)
Creates a capsule object encapsulating the raw C-API MlirLocation.
Definition: Interop.h:202
static MlirAffineMap mlirPythonCapsuleToAffineMap(PyObject *capsule)
Extracts an MlirAffineMap from a capsule as produced from mlirPythonAffineMapToCapsule.
Definition: Interop.h:303
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
Definition: Interop.h:106
static MlirModule mlirPythonCapsuleToModule(PyObject *capsule)
Extracts an MlirModule from a capsule as produced from mlirPythonModuleToCapsule.
Definition: Interop.h:229
static MlirContext mlirPythonCapsuleToContext(PyObject *capsule)
Extracts a MlirContext from a capsule as produced from mlirPythonContextToCapsule.
Definition: Interop.h:171
static PyObject * mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry)
Creates a capsule object encapsulating the raw C-API MlirDialectRegistry.
Definition: Interop.h:182
static PyObject * mlirPythonTypeToCapsule(MlirType type)
Creates a capsule object encapsulating the raw C-API MlirType.
Definition: Interop.h:275
static MlirDialectRegistry mlirPythonCapsuleToDialectRegistry(PyObject *capsule)
Extracts an MlirDialectRegistry from a capsule as produced from mlirPythonDialectRegistryToCapsule.
Definition: Interop.h:192
#define MAKE_MLIR_PYTHON_QUALNAME(local)
Definition: Interop.h:56
static MlirType mlirPythonCapsuleToType(PyObject *capsule)
Extracts an MlirType from a capsule as produced from mlirPythonTypeToCapsule.
Definition: Interop.h:284
static MlirValue mlirPythonCapsuleToValue(PyObject *capsule)
Extracts an MlirValue from a capsule as produced from mlirPythonValueToCapsule.
Definition: Interop.h:362
static PyObject * mlirPythonAffineMapToCapsule(MlirAffineMap affineMap)
Creates a capsule object encapsulating the raw C-API MlirAffineMap.
Definition: Interop.h:294
static MlirPassManager mlirPythonCapsuleToPassManager(PyObject *capsule)
Extracts an MlirPassManager from a capsule as produced from mlirPythonPassManagerToCapsule.
Definition: Interop.h:247
static PyObject * mlirPythonOperationToCapsule(MlirOperation operation)
Creates a capsule object encapsulating the raw C-API MlirOperation.
Definition: Interop.h:257
static MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule)
Extracts an MlirLocation from a capsule as produced from mlirPythonLocationToCapsule.
Definition: Interop.h:211
static PyObject * mlirPythonValueToCapsule(MlirValue value)
Creates a capsule object encapsulating the raw C-API MlirValue.
Definition: Interop.h:353
Creates a custom subclass of mlir.ir.Attribute, implementing a casting constructor and type checking ...
mlir_attribute_subclass(py::handle scope, const char *typeClassName, IsAFunctionTy isaFunction, const py::object &superCls)
Subclasses with a provided mlir.ir.Attribute super-class.
mlir_attribute_subclass(py::handle scope, const char *attrClassName, IsAFunctionTy isaFunction)
Subclasses by looking up the super-class dynamically.
Creates a custom subclass of mlir.ir.Type, implementing a casting constructor and type checking metho...
mlir_type_subclass(py::handle scope, const char *typeClassName, IsAFunctionTy isaFunction)
Subclasses by looking up the super-class dynamically.
mlir_type_subclass(py::handle scope, const char *typeClassName, IsAFunctionTy isaFunction, const py::object &superCls)
Subclasses with a provided mlir.ir.Type super-class.
Provides a facility like py::class_ for defining a new class in a scope, but this allows extension of...
pure_subclass & def_classmethod(const char *name, Func &&f, const Extra &...extra)
pure_subclass & def(const char *name, Func &&f, const Extra &...extra)
pure_subclass(py::handle scope, const char *derivedClassName, const py::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)
static bool mlirPassManagerIsNull(MlirPassManager passManager)
Checks if a PassManager is null.
Definition: Pass.h:65
static bool mlirAffineMapIsNull(MlirAffineMap affineMap)
Checks whether an affine map is null.
Definition: AffineMap.h:47
static bool mlirAttributeIsNull(MlirAttribute attr)
Checks whether an attribute is null.
Definition: IR.h:777
static bool mlirModuleIsNull(MlirModule module)
Checks whether a module is null.
Definition: IR.h:285
static bool mlirValueIsNull(MlirValue value)
Returns whether the value is null.
Definition: IR.h:688
static bool mlirTypeIsNull(MlirType type)
Checks whether a type is null.
Definition: IR.h:745
static bool mlirContextIsNull(MlirContext context)
Checks whether a context is null.
Definition: IR.h:91
static bool mlirLocationIsNull(MlirLocation location)
Checks if the location is null.
Definition: IR.h:253
static bool mlirDialectRegistryIsNull(MlirDialectRegistry registry)
Checks if the dialect registry is null.
Definition: IR.h:214
static bool mlirOperationIsNull(MlirOperation op)
Checks whether the underlying operation is null.
Definition: IR.h:423
Include the generated interface declarations.
Definition: CallGraph.h:229
Include the generated interface declarations.
static py::object mlirApiObjectToCapsule(py::handle apiObject)
Helper to convert a presumed MLIR API object to a capsule, accepting either an explicit Capsule (whic...
PYBIND11_TYPE_CASTER(MlirAffineMap, _("MlirAffineMap"))
static handle cast(MlirAffineMap v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirAttribute, _("MlirAttribute"))
static handle cast(MlirAttribute v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirContext, _("MlirContext"))
PYBIND11_TYPE_CASTER(MlirDialectRegistry, _("MlirDialectRegistry"))
static handle cast(MlirDialectRegistry v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirLocation, _("MlirLocation"))
static handle cast(MlirLocation v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirModule, _("MlirModule"))
static handle cast(MlirModule v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirOperation, _("MlirOperation"))
static handle cast(MlirOperation v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirPassManager, _("MlirPassManager"))
static handle cast(MlirType t, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirType, _("MlirType"))
static handle cast(MlirValue v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirValue, _("MlirValue"))