18 #ifndef MLIR_BINDINGS_PYTHON_PYBINDADAPTORS_H
19 #define MLIR_BINDINGS_PYTHON_PYBINDADAPTORS_H
21 #include <pybind11/functional.h>
22 #include <pybind11/pybind11.h>
23 #include <pybind11/pytypes.h>
24 #include <pybind11/stl.h>
30 #include "llvm/ADT/Twine.h"
33 using namespace py::literals;
50 if (PyCapsule_CheckExact(apiObject.ptr()))
51 return py::reinterpret_borrow<py::object>(apiObject);
53 auto repr = py::repr(apiObject).cast<std::string>();
55 (llvm::Twine(
"Expected an MLIR object (got ") + repr +
").").str());
67 struct type_caster<MlirAffineMap> {
69 bool load(handle src,
bool) {
77 static handle
cast(MlirAffineMap v, return_value_policy, handle) {
89 struct type_caster<MlirAttribute> {
91 bool load(handle src,
bool) {
96 static handle
cast(MlirAttribute v, return_value_policy, handle) {
109 struct type_caster<MlirBlock> {
120 struct type_caster<MlirContext> {
140 struct type_caster<MlirDialectRegistry> {
147 static handle
cast(MlirDialectRegistry v, return_value_policy, handle) {
148 py::object capsule = py::reinterpret_steal<py::object>(
151 .attr(
"DialectRegistry")
159 struct type_caster<MlirLocation> {
172 static handle
cast(MlirLocation v, return_value_policy, handle) {
184 struct type_caster<MlirModule> {
191 static handle
cast(MlirModule v, return_value_policy, handle) {
203 struct type_caster<MlirOperation> {
210 static handle
cast(MlirOperation v, return_value_policy, handle) {
211 if (v.ptr ==
nullptr)
224 struct type_caster<MlirValue> {
231 static handle
cast(MlirValue v, return_value_policy, handle) {
232 if (v.ptr ==
nullptr)
246 struct type_caster<MlirPassManager> {
257 struct type_caster<MlirTypeID> {
264 static handle
cast(MlirTypeID v, return_value_policy, handle) {
265 if (v.ptr ==
nullptr)
278 struct type_caster<MlirType> {
285 static handle
cast(MlirType t, return_value_policy, handle) {
317 const py::object &superClass) {
319 py::reinterpret_borrow<py::object>((PyObject *)&PyType_Type);
320 py::object metaclass = pyType(superClass);
324 metaclass(derivedClassName, py::make_tuple(superClass), attributes);
325 scope.attr(derivedClassName) = thisClass;
328 template <
typename Func,
typename... Extra>
331 std::forward<Func>(f), py::name(name), py::is_method(thisClass),
332 py::sibling(py::getattr(thisClass, name, py::none())), extra...);
333 thisClass.attr(cf.name()) = cf;
337 template <
typename Func,
typename... Extra>
339 const Extra &...extra) {
341 std::forward<Func>(f), py::name(name), py::is_method(thisClass),
342 py::sibling(py::getattr(thisClass, name, py::none())), extra...);
343 auto builtinProperty =
344 py::reinterpret_borrow<py::object>((PyObject *)&PyProperty_Type);
345 thisClass.attr(name) = builtinProperty(cf);
349 template <
typename Func,
typename... Extra>
351 const Extra &...extra) {
352 static_assert(!std::is_member_function_pointer<Func>::value,
353 "def_staticmethod(...) called with a non-static member "
356 std::forward<Func>(f), py::name(name), py::scope(thisClass),
357 py::sibling(py::getattr(thisClass, name, py::none())), extra...);
358 thisClass.attr(cf.name()) = py::staticmethod(cf);
362 template <
typename Func,
typename... Extra>
364 const Extra &...extra) {
365 static_assert(!std::is_member_function_pointer<Func>::value,
366 "def_classmethod(...) called with a non-static member "
369 std::forward<Func>(f), py::name(name), py::scope(thisClass),
370 py::sibling(py::getattr(thisClass, name, py::none())), extra...);
371 thisClass.attr(cf.name()) =
372 py::reinterpret_borrow<py::object>(PyClassMethod_New(cf.ptr()));
393 scope, attrClassName, isaFunction,
395 .attr(
"Attribute")) {}
412 std::string captureTypeName(
414 py::cpp_function newCf(
415 [superCls, isaFunction, captureTypeName](py::object cls,
416 py::object otherAttribute) {
417 MlirAttribute rawAttribute = py::cast<MlirAttribute>(otherAttribute);
418 if (!isaFunction(rawAttribute)) {
419 auto origRepr = py::repr(otherAttribute).cast<std::string>();
420 throw std::invalid_argument(
421 (llvm::Twine(
"Cannot cast attribute to ") + captureTypeName +
422 " (from " + origRepr +
")")
425 py::object
self = superCls.attr(
"__new__")(cls, otherAttribute);
428 py::name(
"__new__"), py::arg(
"cls"), py::arg(
"cast_from_attr"));
429 thisClass.attr(
"__new__") = newCf;
434 [isaFunction](MlirAttribute other) {
return isaFunction(other); },
435 py::arg(
"other_attribute"));
451 scope, typeClassName, isaFunction,
453 getTypeIDFunction) {}
471 std::string captureTypeName(
473 py::cpp_function newCf(
474 [superCls, isaFunction, captureTypeName](py::object cls,
475 py::object otherType) {
476 MlirType rawType = py::cast<MlirType>(otherType);
477 if (!isaFunction(rawType)) {
478 auto origRepr = py::repr(otherType).cast<std::string>();
479 throw std::invalid_argument((llvm::Twine(
"Cannot cast type to ") +
480 captureTypeName +
" (from " +
484 py::object
self = superCls.attr(
"__new__")(cls, otherType);
487 py::name(
"__new__"), py::arg(
"cls"), py::arg(
"cast_from_type"));
488 thisClass.attr(
"__new__") = newCf;
493 [isaFunction](MlirType other) {
return isaFunction(other); },
494 py::arg(
"other_type"));
495 def(
"__repr__", [superCls, captureTypeName](py::object
self) {
496 return py::repr(superCls(
self))
497 .attr(
"replace")(superCls.attr(
"__name__"), captureTypeName);
499 if (getTypeIDFunction) {
505 def_staticmethod(
"get_static_typeid",
506 [getTypeIDFunction]() {
return getTypeIDFunction(); });
509 getTypeIDFunction())(pybind11::cpp_function(
510 [thisClass = thisClass](
const py::object &mlirType) {
511 return thisClass(mlirType);
527 scope, valueClassName, isaFunction,
546 std::string captureValueName(
548 py::cpp_function newCf(
549 [superCls, isaFunction, captureValueName](py::object cls,
550 py::object otherValue) {
551 MlirValue rawValue = py::cast<MlirValue>(otherValue);
552 if (!isaFunction(rawValue)) {
553 auto origRepr = py::repr(otherValue).cast<std::string>();
554 throw std::invalid_argument((llvm::Twine(
"Cannot cast value to ") +
555 captureValueName +
" (from " +
559 py::object
self = superCls.attr(
"__new__")(cls, otherValue);
562 py::name(
"__new__"), py::arg(
"cls"), py::arg(
"cast_from_value"));
563 thisClass.attr(
"__new__") = newCf;
568 [isaFunction](MlirValue other) {
return isaFunction(other); },
569 py::arg(
"other_value"));
584 assert(errorMessage.empty() &&
"unchecked error message");
588 [[nodiscard]] std::string
takeMessage() {
return std::move(errorMessage); }
593 *
static_cast<std::string *
>(data) +=
594 llvm::StringRef(message.
data, message.
length);
597 *
static_cast<std::string *
>(data) +=
"at ";
599 *
static_cast<std::string *
>(data) +=
": ";
606 std::string errorMessage =
"";
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.
#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 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...
static std::string diag(const llvm::Value &value)
RAII scope intercepting all diagnostics into a string.
std::string takeMessage()
~CollectDiagnosticsToStringScope()
CollectDiagnosticsToStringScope(MlirContext ctx)
Creates a custom subclass of mlir.ir.Attribute, implementing a casting constructor and type checking ...
bool(*)(MlirAttribute) IsAFunctionTy
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, const py::object &superCls, GetTypeIDFunctionTy getTypeIDFunction=nullptr)
Subclasses with a provided mlir.ir.Type super-class.
MlirTypeID(*)() GetTypeIDFunctionTy
mlir_type_subclass(py::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(py::handle scope, const char *valueClassName, IsAFunctionTy isaFunction, const py::object &superCls)
Subclasses with a provided mlir.ir.Value super-class.
mlir_value_subclass(py::handle scope, const char *valueClassName, IsAFunctionTy isaFunction)
Subclasses by looking up the super-class dynamically.
bool(*)(MlirValue) IsAFunctionTy
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)
py::object get_class() const
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)
MLIR_CAPI_EXPORTED void mlirDiagnosticPrint(MlirDiagnostic diagnostic, MlirStringCallback callback, void *userData)
Prints a diagnostic using the provided callback.
MLIR_CAPI_EXPORTED MlirDiagnosticHandlerID mlirContextAttachDiagnosticHandler(MlirContext context, MlirDiagnosticHandler handler, void *userData, void(*deleteUserData)(void *))
Attaches the diagnostic handler to the context.
MLIR_CAPI_EXPORTED void mlirContextDetachDiagnosticHandler(MlirContext context, MlirDiagnosticHandlerID id)
Detaches an attached diagnostic handler from the context given its identifier.
uint64_t MlirDiagnosticHandlerID
Opaque identifier of a diagnostic handler, useful to detach a handler.
MLIR_CAPI_EXPORTED MlirLocation mlirDiagnosticGetLocation(MlirDiagnostic diagnostic)
Returns the location at which the diagnostic is reported.
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.
MLIR_CAPI_EXPORTED void mlirLocationPrint(MlirLocation location, MlirStringCallback callback, void *userData)
Prints a location by sending chunks of the string representation and forwarding userData tocallback`.
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 MlirLogicalResult mlirLogicalResultSuccess(void)
Creates a logical result representing a success.
static bool mlirTypeIDIsNull(MlirTypeID typeID)
Checks whether a type id is null.
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...
An opaque reference to a diagnostic, always owned by the diagnostics engine (context).
A logical result value, essentially a boolean with named states.
A pointer to a sized fragment of a string, not necessarily null-terminated.
const char * data
Pointer to the first symbol.
size_t length
Length of the fragment.
PYBIND11_TYPE_CASTER(MlirAffineMap, _("MlirAffineMap"))
static handle cast(MlirAffineMap v, return_value_policy, handle)
bool load(handle src, bool)
bool load(handle src, bool)
PYBIND11_TYPE_CASTER(MlirAttribute, _("MlirAttribute"))
static handle cast(MlirAttribute v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirBlock, _("MlirBlock"))
bool load(handle src, bool)
PYBIND11_TYPE_CASTER(MlirContext, _("MlirContext"))
bool load(handle src, bool)
PYBIND11_TYPE_CASTER(MlirDialectRegistry, _("MlirDialectRegistry"))
static handle cast(MlirDialectRegistry v, return_value_policy, handle)
bool load(handle src, bool)
PYBIND11_TYPE_CASTER(MlirLocation, _("MlirLocation"))
bool load(handle src, bool)
static handle cast(MlirLocation v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirModule, _("MlirModule"))
static handle cast(MlirModule v, return_value_policy, handle)
bool load(handle src, bool)
PYBIND11_TYPE_CASTER(MlirOperation, _("MlirOperation"))
bool load(handle src, bool)
static handle cast(MlirOperation v, return_value_policy, handle)
bool load(handle src, bool)
PYBIND11_TYPE_CASTER(MlirPassManager, _("MlirPassManager"))
PYBIND11_TYPE_CASTER(MlirTypeID, _("MlirTypeID"))
bool load(handle src, bool)
static handle cast(MlirTypeID v, return_value_policy, handle)
static handle cast(MlirType t, return_value_policy, handle)
bool load(handle src, bool)
PYBIND11_TYPE_CASTER(MlirType, _("MlirType"))
bool load(handle src, bool)
static handle cast(MlirValue v, return_value_policy, handle)
PYBIND11_TYPE_CASTER(MlirValue, _("MlirValue"))