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