| 1 | //===-- mlir-c/Interop.h - Constants for Python/C-API interop -----*- C -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM |
| 4 | // Exceptions. |
| 5 | // See https://llvm.org/LICENSE.txt for license information. |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This header declares constants and helpers necessary for C-level |
| 11 | // interop with the MLIR Python extension module. Since the Python bindings |
| 12 | // are a thin wrapper around the MLIR C-API, a further C-API is not provided |
| 13 | // specifically for the Python extension. Instead, simple facilities are |
| 14 | // provided for translating between Python types and corresponding MLIR C-API |
| 15 | // types. |
| 16 | // |
| 17 | // This header is standalone, requiring nothing beyond normal linking against |
| 18 | // the Python implementation. |
| 19 | //===----------------------------------------------------------------------===// |
| 20 | |
| 21 | #ifndef MLIR_C_BINDINGS_PYTHON_INTEROP_H |
| 22 | #define MLIR_C_BINDINGS_PYTHON_INTEROP_H |
| 23 | |
| 24 | // We *should*, in theory, include Python.h here in order to import the correct |
| 25 | // definitions for what we need below, however, importing Python.h directly on |
| 26 | // Windows results in the enforcement of either pythonX.lib or pythonX_d.lib |
| 27 | // depending on the build flavor. Instead, we rely on the fact that this file |
| 28 | // (Interop.h) is always included AFTER pybind11 and will therefore have access |
| 29 | // to the definitions from Python.h in addition to having a workaround applied |
| 30 | // through the pybind11 headers that allows us to control which python library |
| 31 | // is used. |
| 32 | #if !defined(_MSC_VER) |
| 33 | #include <Python.h> |
| 34 | #endif |
| 35 | |
| 36 | #include "mlir-c/AffineExpr.h" |
| 37 | #include "mlir-c/AffineMap.h" |
| 38 | #include "mlir-c/ExecutionEngine.h" |
| 39 | #include "mlir-c/IR.h" |
| 40 | #include "mlir-c/IntegerSet.h" |
| 41 | #include "mlir-c/Pass.h" |
| 42 | #include "mlir-c/Rewrite.h" |
| 43 | |
| 44 | // The 'mlir' Python package is relocatable and supports co-existing in multiple |
| 45 | // projects. Each project must define its outer package prefix with this define |
| 46 | // in order to provide proper isolation and local name resolution. |
| 47 | // The default is for the upstream "import mlir" package layout. |
| 48 | // Note that this prefix is internally stringified, allowing it to be passed |
| 49 | // unquoted on the compiler command line without shell quote escaping issues. |
| 50 | #ifndef MLIR_PYTHON_PACKAGE_PREFIX |
| 51 | #define MLIR_PYTHON_PACKAGE_PREFIX mlir. |
| 52 | #endif |
| 53 | |
| 54 | // Makes a fully-qualified name relative to the MLIR python package. |
| 55 | #define MLIR_PYTHON_STRINGIZE(s) #s |
| 56 | #define MLIR_PYTHON_STRINGIZE_ARG(arg) MLIR_PYTHON_STRINGIZE(arg) |
| 57 | #define MAKE_MLIR_PYTHON_QUALNAME(local) \ |
| 58 | MLIR_PYTHON_STRINGIZE_ARG(MLIR_PYTHON_PACKAGE_PREFIX) local |
| 59 | |
| 60 | #define MLIR_PYTHON_CAPSULE_AFFINE_EXPR \ |
| 61 | MAKE_MLIR_PYTHON_QUALNAME("ir.AffineExpr._CAPIPtr") |
| 62 | #define MLIR_PYTHON_CAPSULE_AFFINE_MAP \ |
| 63 | MAKE_MLIR_PYTHON_QUALNAME("ir.AffineMap._CAPIPtr") |
| 64 | #define MLIR_PYTHON_CAPSULE_ATTRIBUTE \ |
| 65 | MAKE_MLIR_PYTHON_QUALNAME("ir.Attribute._CAPIPtr") |
| 66 | #define MLIR_PYTHON_CAPSULE_BLOCK MAKE_MLIR_PYTHON_QUALNAME("ir.Block._CAPIPtr") |
| 67 | #define MLIR_PYTHON_CAPSULE_CONTEXT \ |
| 68 | MAKE_MLIR_PYTHON_QUALNAME("ir.Context._CAPIPtr") |
| 69 | #define MLIR_PYTHON_CAPSULE_DIALECT_REGISTRY \ |
| 70 | MAKE_MLIR_PYTHON_QUALNAME("ir.DialectRegistry._CAPIPtr") |
| 71 | #define MLIR_PYTHON_CAPSULE_EXECUTION_ENGINE \ |
| 72 | MAKE_MLIR_PYTHON_QUALNAME("execution_engine.ExecutionEngine._CAPIPtr") |
| 73 | #define MLIR_PYTHON_CAPSULE_INTEGER_SET \ |
| 74 | MAKE_MLIR_PYTHON_QUALNAME("ir.IntegerSet._CAPIPtr") |
| 75 | #define MLIR_PYTHON_CAPSULE_LOCATION \ |
| 76 | MAKE_MLIR_PYTHON_QUALNAME("ir.Location._CAPIPtr") |
| 77 | #define MLIR_PYTHON_CAPSULE_MODULE \ |
| 78 | MAKE_MLIR_PYTHON_QUALNAME("ir.Module._CAPIPtr") |
| 79 | #define MLIR_PYTHON_CAPSULE_OPERATION \ |
| 80 | MAKE_MLIR_PYTHON_QUALNAME("ir.Operation._CAPIPtr") |
| 81 | #define MLIR_PYTHON_CAPSULE_TYPE MAKE_MLIR_PYTHON_QUALNAME("ir.Type._CAPIPtr") |
| 82 | #define MLIR_PYTHON_CAPSULE_PASS_MANAGER \ |
| 83 | MAKE_MLIR_PYTHON_QUALNAME("passmanager.PassManager._CAPIPtr") |
| 84 | #define MLIR_PYTHON_CAPSULE_VALUE MAKE_MLIR_PYTHON_QUALNAME("ir.Value._CAPIPtr") |
| 85 | #define MLIR_PYTHON_CAPSULE_TYPEID \ |
| 86 | MAKE_MLIR_PYTHON_QUALNAME("ir.TypeID._CAPIPtr") |
| 87 | |
| 88 | /** Attribute on MLIR Python objects that expose their C-API pointer. |
| 89 | * This will be a type-specific capsule created as per one of the helpers |
| 90 | * below. |
| 91 | * |
| 92 | * Ownership is not transferred by acquiring a capsule in this way: the |
| 93 | * validity of the pointer wrapped by the capsule will be bounded by the |
| 94 | * lifetime of the Python object that produced it. Only the name and pointer |
| 95 | * of the capsule are set. The caller is free to set a destructor and context |
| 96 | * as needed to manage anything further. */ |
| 97 | #define MLIR_PYTHON_CAPI_PTR_ATTR "_CAPIPtr" |
| 98 | |
| 99 | /** Attribute on MLIR Python objects that exposes a factory function for |
| 100 | * constructing the corresponding Python object from a type-specific |
| 101 | * capsule wrapping the C-API pointer. The signature of the function is: |
| 102 | * def _CAPICreate(capsule) -> object |
| 103 | * Calling such a function implies a transfer of ownership of the object the |
| 104 | * capsule wraps: after such a call, the capsule should be considered invalid, |
| 105 | * and its wrapped pointer must not be destroyed. |
| 106 | * |
| 107 | * Only a very small number of Python objects can be created in such a fashion |
| 108 | * (i.e. top-level types such as Context where the lifetime can be cleanly |
| 109 | * delineated). */ |
| 110 | #define MLIR_PYTHON_CAPI_FACTORY_ATTR "_CAPICreate" |
| 111 | |
| 112 | /** Attribute on MLIR Python objects that expose a function for downcasting the |
| 113 | * corresponding Python object to a subclass if the object is in fact a subclass |
| 114 | * (Concrete or mlir_type_subclass) of ir.Type. The signature of the function |
| 115 | * is: def maybe_downcast(self) -> object where the resulting object will |
| 116 | * (possibly) be an instance of the subclass. |
| 117 | */ |
| 118 | #define MLIR_PYTHON_MAYBE_DOWNCAST_ATTR "maybe_downcast" |
| 119 | |
| 120 | /** Attribute on main C extension module (_mlir) that corresponds to the |
| 121 | * type caster registration binding. The signature of the function is: |
| 122 | * def register_type_caster(MlirTypeID mlirTypeID, *, bool replace) |
| 123 | * which then takes a typeCaster (register_type_caster is meant to be used as a |
| 124 | * decorator from python), and where replace indicates the typeCaster should |
| 125 | * replace any existing registered type casters (such as those for upstream |
| 126 | * ConcreteTypes). The interface of the typeCaster is: def type_caster(ir.Type) |
| 127 | * -> SubClassTypeT where SubClassTypeT indicates the result should be a |
| 128 | * subclass (inherit from) ir.Type. |
| 129 | */ |
| 130 | #define MLIR_PYTHON_CAPI_TYPE_CASTER_REGISTER_ATTR "register_type_caster" |
| 131 | |
| 132 | /** Attribute on main C extension module (_mlir) that corresponds to the |
| 133 | * value caster registration binding. The signature of the function is: |
| 134 | * def register_value_caster(MlirTypeID mlirTypeID, *, bool replace) |
| 135 | * which then takes a valueCaster (register_value_caster is meant to be used as |
| 136 | * a decorator, from python), and where replace indicates the valueCaster should |
| 137 | * replace any existing registered value casters. The interface of the |
| 138 | * valueCaster is: def value_caster(ir.Value) -> SubClassValueT where |
| 139 | * SubClassValueT indicates the result should be a subclass (inherit from) |
| 140 | * ir.Value. |
| 141 | */ |
| 142 | #define MLIR_PYTHON_CAPI_VALUE_CASTER_REGISTER_ATTR "register_value_caster" |
| 143 | |
| 144 | /// Gets a void* from a wrapped struct. Needed because const cast is different |
| 145 | /// between C/C++. |
| 146 | #ifdef __cplusplus |
| 147 | #define MLIR_PYTHON_GET_WRAPPED_POINTER(object) \ |
| 148 | (const_cast<void *>((object).ptr)) |
| 149 | #else |
| 150 | #define MLIR_PYTHON_GET_WRAPPED_POINTER(object) (void *)(object.ptr) |
| 151 | #endif |
| 152 | |
| 153 | #ifdef __cplusplus |
| 154 | extern "C" { |
| 155 | #endif |
| 156 | |
| 157 | /** Creates a capsule object encapsulating the raw C-API MlirAffineExpr. The |
| 158 | * returned capsule does not extend or affect ownership of any Python objects |
| 159 | * that reference the expression in any way. |
| 160 | */ |
| 161 | static inline PyObject *mlirPythonAffineExprToCapsule(MlirAffineExpr expr) { |
| 162 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(expr), |
| 163 | MLIR_PYTHON_CAPSULE_AFFINE_EXPR, NULL); |
| 164 | } |
| 165 | |
| 166 | /** Extracts an MlirAffineExpr from a capsule as produced from |
| 167 | * mlirPythonAffineExprToCapsule. If the capsule is not of the right type, then |
| 168 | * a null expression is returned (as checked via mlirAffineExprIsNull). In such |
| 169 | * a case, the Python APIs will have already set an error. */ |
| 170 | static inline MlirAffineExpr mlirPythonCapsuleToAffineExpr(PyObject *capsule) { |
| 171 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_AFFINE_EXPR); |
| 172 | MlirAffineExpr expr = {.ptr: ptr}; |
| 173 | return expr; |
| 174 | } |
| 175 | |
| 176 | /** Creates a capsule object encapsulating the raw C-API MlirAttribute. |
| 177 | * The returned capsule does not extend or affect ownership of any Python |
| 178 | * objects that reference the attribute in any way. |
| 179 | */ |
| 180 | static inline PyObject *mlirPythonAttributeToCapsule(MlirAttribute attribute) { |
| 181 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(attribute), |
| 182 | MLIR_PYTHON_CAPSULE_ATTRIBUTE, NULL); |
| 183 | } |
| 184 | |
| 185 | /** Extracts an MlirAttribute from a capsule as produced from |
| 186 | * mlirPythonAttributeToCapsule. If the capsule is not of the right type, then |
| 187 | * a null attribute is returned (as checked via mlirAttributeIsNull). In such a |
| 188 | * case, the Python APIs will have already set an error. */ |
| 189 | static inline MlirAttribute mlirPythonCapsuleToAttribute(PyObject *capsule) { |
| 190 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_ATTRIBUTE); |
| 191 | MlirAttribute attr = {.ptr: ptr}; |
| 192 | return attr; |
| 193 | } |
| 194 | |
| 195 | /** Creates a capsule object encapsulating the raw C-API MlirBlock. |
| 196 | * The returned capsule does not extend or affect ownership of any Python |
| 197 | * objects that reference the module in any way. */ |
| 198 | static inline PyObject *mlirPythonBlockToCapsule(MlirBlock block) { |
| 199 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(block), |
| 200 | MLIR_PYTHON_CAPSULE_BLOCK, NULL); |
| 201 | } |
| 202 | |
| 203 | /** Extracts an MlirBlock from a capsule as produced from |
| 204 | * mlirPythonBlockToCapsule. If the capsule is not of the right type, then |
| 205 | * a null pass manager is returned (as checked via mlirBlockIsNull). */ |
| 206 | static inline MlirBlock mlirPythonCapsuleToBlock(PyObject *capsule) { |
| 207 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_BLOCK); |
| 208 | MlirBlock block = {.ptr: ptr}; |
| 209 | return block; |
| 210 | } |
| 211 | |
| 212 | /** Creates a capsule object encapsulating the raw C-API MlirContext. |
| 213 | * The returned capsule does not extend or affect ownership of any Python |
| 214 | * objects that reference the context in any way. |
| 215 | */ |
| 216 | static inline PyObject *mlirPythonContextToCapsule(MlirContext context) { |
| 217 | return PyCapsule_New(context.ptr, MLIR_PYTHON_CAPSULE_CONTEXT, NULL); |
| 218 | } |
| 219 | |
| 220 | /** Extracts a MlirContext from a capsule as produced from |
| 221 | * mlirPythonContextToCapsule. If the capsule is not of the right type, then |
| 222 | * a null context is returned (as checked via mlirContextIsNull). In such a |
| 223 | * case, the Python APIs will have already set an error. */ |
| 224 | static inline MlirContext mlirPythonCapsuleToContext(PyObject *capsule) { |
| 225 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_CONTEXT); |
| 226 | MlirContext context = {.ptr: ptr}; |
| 227 | return context; |
| 228 | } |
| 229 | |
| 230 | /** Creates a capsule object encapsulating the raw C-API MlirDialectRegistry. |
| 231 | * The returned capsule does not extend or affect ownership of any Python |
| 232 | * objects that reference the context in any way. |
| 233 | */ |
| 234 | static inline PyObject * |
| 235 | mlirPythonDialectRegistryToCapsule(MlirDialectRegistry registry) { |
| 236 | return PyCapsule_New(registry.ptr, MLIR_PYTHON_CAPSULE_DIALECT_REGISTRY, |
| 237 | NULL); |
| 238 | } |
| 239 | |
| 240 | /** Extracts an MlirDialectRegistry from a capsule as produced from |
| 241 | * mlirPythonDialectRegistryToCapsule. If the capsule is not of the right type, |
| 242 | * then a null context is returned (as checked via mlirContextIsNull). In such a |
| 243 | * case, the Python APIs will have already set an error. */ |
| 244 | static inline MlirDialectRegistry |
| 245 | mlirPythonCapsuleToDialectRegistry(PyObject *capsule) { |
| 246 | void *ptr = |
| 247 | PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_DIALECT_REGISTRY); |
| 248 | MlirDialectRegistry registry = {.ptr: ptr}; |
| 249 | return registry; |
| 250 | } |
| 251 | |
| 252 | /** Creates a capsule object encapsulating the raw C-API MlirLocation. |
| 253 | * The returned capsule does not extend or affect ownership of any Python |
| 254 | * objects that reference the location in any way. */ |
| 255 | static inline PyObject *mlirPythonLocationToCapsule(MlirLocation loc) { |
| 256 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(loc), |
| 257 | MLIR_PYTHON_CAPSULE_LOCATION, NULL); |
| 258 | } |
| 259 | |
| 260 | /** Extracts an MlirLocation from a capsule as produced from |
| 261 | * mlirPythonLocationToCapsule. If the capsule is not of the right type, then |
| 262 | * a null module is returned (as checked via mlirLocationIsNull). In such a |
| 263 | * case, the Python APIs will have already set an error. */ |
| 264 | static inline MlirLocation mlirPythonCapsuleToLocation(PyObject *capsule) { |
| 265 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_LOCATION); |
| 266 | MlirLocation loc = {.ptr: ptr}; |
| 267 | return loc; |
| 268 | } |
| 269 | |
| 270 | /** Creates a capsule object encapsulating the raw C-API MlirModule. |
| 271 | * The returned capsule does not extend or affect ownership of any Python |
| 272 | * objects that reference the module in any way. */ |
| 273 | static inline PyObject *mlirPythonModuleToCapsule(MlirModule module) { |
| 274 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(module), |
| 275 | MLIR_PYTHON_CAPSULE_MODULE, NULL); |
| 276 | } |
| 277 | |
| 278 | /** Extracts an MlirModule from a capsule as produced from |
| 279 | * mlirPythonModuleToCapsule. If the capsule is not of the right type, then |
| 280 | * a null module is returned (as checked via mlirModuleIsNull). In such a |
| 281 | * case, the Python APIs will have already set an error. */ |
| 282 | static inline MlirModule mlirPythonCapsuleToModule(PyObject *capsule) { |
| 283 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_MODULE); |
| 284 | MlirModule module = {.ptr: ptr}; |
| 285 | return module; |
| 286 | } |
| 287 | |
| 288 | /** Creates a capsule object encapsulating the raw C-API |
| 289 | * MlirFrozenRewritePatternSet. |
| 290 | * The returned capsule does not extend or affect ownership of any Python |
| 291 | * objects that reference the module in any way. */ |
| 292 | static inline PyObject * |
| 293 | mlirPythonFrozenRewritePatternSetToCapsule(MlirFrozenRewritePatternSet pm) { |
| 294 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(pm), |
| 295 | MLIR_PYTHON_CAPSULE_PASS_MANAGER, NULL); |
| 296 | } |
| 297 | |
| 298 | /** Extracts an MlirFrozenRewritePatternSet from a capsule as produced from |
| 299 | * mlirPythonFrozenRewritePatternSetToCapsule. If the capsule is not of the |
| 300 | * right type, then a null module is returned. */ |
| 301 | static inline MlirFrozenRewritePatternSet |
| 302 | mlirPythonCapsuleToFrozenRewritePatternSet(PyObject *capsule) { |
| 303 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_PASS_MANAGER); |
| 304 | MlirFrozenRewritePatternSet pm = {.ptr: ptr}; |
| 305 | return pm; |
| 306 | } |
| 307 | |
| 308 | /** Creates a capsule object encapsulating the raw C-API MlirPassManager. |
| 309 | * The returned capsule does not extend or affect ownership of any Python |
| 310 | * objects that reference the module in any way. */ |
| 311 | static inline PyObject *mlirPythonPassManagerToCapsule(MlirPassManager pm) { |
| 312 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(pm), |
| 313 | MLIR_PYTHON_CAPSULE_PASS_MANAGER, NULL); |
| 314 | } |
| 315 | |
| 316 | /** Extracts an MlirPassManager from a capsule as produced from |
| 317 | * mlirPythonPassManagerToCapsule. If the capsule is not of the right type, then |
| 318 | * a null pass manager is returned (as checked via mlirPassManagerIsNull). */ |
| 319 | static inline MlirPassManager |
| 320 | mlirPythonCapsuleToPassManager(PyObject *capsule) { |
| 321 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_PASS_MANAGER); |
| 322 | MlirPassManager pm = {.ptr: ptr}; |
| 323 | return pm; |
| 324 | } |
| 325 | |
| 326 | /** Creates a capsule object encapsulating the raw C-API MlirOperation. |
| 327 | * The returned capsule does not extend or affect ownership of any Python |
| 328 | * objects that reference the operation in any way. |
| 329 | */ |
| 330 | static inline PyObject *mlirPythonOperationToCapsule(MlirOperation operation) { |
| 331 | return PyCapsule_New(operation.ptr, MLIR_PYTHON_CAPSULE_OPERATION, NULL); |
| 332 | } |
| 333 | |
| 334 | /** Extracts an MlirOperations from a capsule as produced from |
| 335 | * mlirPythonOperationToCapsule. If the capsule is not of the right type, then |
| 336 | * a null type is returned (as checked via mlirOperationIsNull). In such a |
| 337 | * case, the Python APIs will have already set an error. */ |
| 338 | static inline MlirOperation mlirPythonCapsuleToOperation(PyObject *capsule) { |
| 339 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_OPERATION); |
| 340 | MlirOperation op = {.ptr: ptr}; |
| 341 | return op; |
| 342 | } |
| 343 | |
| 344 | /** Creates a capsule object encapsulating the raw C-API MlirTypeID. |
| 345 | * The returned capsule does not extend or affect ownership of any Python |
| 346 | * objects that reference the type in any way. |
| 347 | */ |
| 348 | static inline PyObject *mlirPythonTypeIDToCapsule(MlirTypeID typeID) { |
| 349 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(typeID), |
| 350 | MLIR_PYTHON_CAPSULE_TYPEID, NULL); |
| 351 | } |
| 352 | |
| 353 | /** Extracts an MlirTypeID from a capsule as produced from |
| 354 | * mlirPythonTypeIDToCapsule. If the capsule is not of the right type, then |
| 355 | * a null type is returned (as checked via mlirTypeIDIsNull). In such a |
| 356 | * case, the Python APIs will have already set an error. */ |
| 357 | static inline MlirTypeID mlirPythonCapsuleToTypeID(PyObject *capsule) { |
| 358 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_TYPEID); |
| 359 | MlirTypeID typeID = {.ptr: ptr}; |
| 360 | return typeID; |
| 361 | } |
| 362 | |
| 363 | /** Creates a capsule object encapsulating the raw C-API MlirType. |
| 364 | * The returned capsule does not extend or affect ownership of any Python |
| 365 | * objects that reference the type in any way. |
| 366 | */ |
| 367 | static inline PyObject *mlirPythonTypeToCapsule(MlirType type) { |
| 368 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(type), |
| 369 | MLIR_PYTHON_CAPSULE_TYPE, NULL); |
| 370 | } |
| 371 | |
| 372 | /** Extracts an MlirType from a capsule as produced from |
| 373 | * mlirPythonTypeToCapsule. If the capsule is not of the right type, then |
| 374 | * a null type is returned (as checked via mlirTypeIsNull). In such a |
| 375 | * case, the Python APIs will have already set an error. */ |
| 376 | static inline MlirType mlirPythonCapsuleToType(PyObject *capsule) { |
| 377 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_TYPE); |
| 378 | MlirType type = {.ptr: ptr}; |
| 379 | return type; |
| 380 | } |
| 381 | |
| 382 | /** Creates a capsule object encapsulating the raw C-API MlirAffineMap. |
| 383 | * The returned capsule does not extend or affect ownership of any Python |
| 384 | * objects that reference the type in any way. |
| 385 | */ |
| 386 | static inline PyObject *mlirPythonAffineMapToCapsule(MlirAffineMap affineMap) { |
| 387 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(affineMap), |
| 388 | MLIR_PYTHON_CAPSULE_AFFINE_MAP, NULL); |
| 389 | } |
| 390 | |
| 391 | /** Extracts an MlirAffineMap from a capsule as produced from |
| 392 | * mlirPythonAffineMapToCapsule. If the capsule is not of the right type, then |
| 393 | * a null type is returned (as checked via mlirAffineMapIsNull). In such a |
| 394 | * case, the Python APIs will have already set an error. */ |
| 395 | static inline MlirAffineMap mlirPythonCapsuleToAffineMap(PyObject *capsule) { |
| 396 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_AFFINE_MAP); |
| 397 | MlirAffineMap affineMap = {.ptr: ptr}; |
| 398 | return affineMap; |
| 399 | } |
| 400 | |
| 401 | /** Creates a capsule object encapsulating the raw C-API MlirIntegerSet. |
| 402 | * The returned capsule does not extend or affect ownership of any Python |
| 403 | * objects that reference the set in any way. */ |
| 404 | static inline PyObject * |
| 405 | mlirPythonIntegerSetToCapsule(MlirIntegerSet integerSet) { |
| 406 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(integerSet), |
| 407 | MLIR_PYTHON_CAPSULE_INTEGER_SET, NULL); |
| 408 | } |
| 409 | |
| 410 | /** Extracts an MlirIntegerSet from a capsule as produced from |
| 411 | * mlirPythonIntegerSetToCapsule. If the capsule is not of the right type, then |
| 412 | * a null set is returned (as checked via mlirIntegerSetIsNull). In such a |
| 413 | * case, the Python APIs will have already set an error. */ |
| 414 | static inline MlirIntegerSet mlirPythonCapsuleToIntegerSet(PyObject *capsule) { |
| 415 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_INTEGER_SET); |
| 416 | MlirIntegerSet integerSet = {.ptr: ptr}; |
| 417 | return integerSet; |
| 418 | } |
| 419 | |
| 420 | /** Creates a capsule object encapsulating the raw C-API MlirExecutionEngine. |
| 421 | * The returned capsule does not extend or affect ownership of any Python |
| 422 | * objects that reference the set in any way. */ |
| 423 | static inline PyObject * |
| 424 | mlirPythonExecutionEngineToCapsule(MlirExecutionEngine jit) { |
| 425 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(jit), |
| 426 | MLIR_PYTHON_CAPSULE_EXECUTION_ENGINE, NULL); |
| 427 | } |
| 428 | |
| 429 | /** Extracts an MlirExecutionEngine from a capsule as produced from |
| 430 | * mlirPythonIntegerSetToCapsule. If the capsule is not of the right type, then |
| 431 | * a null set is returned (as checked via mlirExecutionEngineIsNull). In such a |
| 432 | * case, the Python APIs will have already set an error. */ |
| 433 | static inline MlirExecutionEngine |
| 434 | mlirPythonCapsuleToExecutionEngine(PyObject *capsule) { |
| 435 | void *ptr = |
| 436 | PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_EXECUTION_ENGINE); |
| 437 | MlirExecutionEngine jit = {.ptr: ptr}; |
| 438 | return jit; |
| 439 | } |
| 440 | |
| 441 | /** Creates a capsule object encapsulating the raw C-API MlirValue. |
| 442 | * The returned capsule does not extend or affect ownership of any Python |
| 443 | * objects that reference the operation in any way. |
| 444 | */ |
| 445 | static inline PyObject *mlirPythonValueToCapsule(MlirValue value) { |
| 446 | return PyCapsule_New(MLIR_PYTHON_GET_WRAPPED_POINTER(value), |
| 447 | MLIR_PYTHON_CAPSULE_VALUE, NULL); |
| 448 | } |
| 449 | |
| 450 | /** Extracts an MlirValue from a capsule as produced from |
| 451 | * mlirPythonValueToCapsule. If the capsule is not of the right type, then a |
| 452 | * null type is returned (as checked via mlirValueIsNull). In such a case, the |
| 453 | * Python APIs will have already set an error. */ |
| 454 | static inline MlirValue mlirPythonCapsuleToValue(PyObject *capsule) { |
| 455 | void *ptr = PyCapsule_GetPointer(capsule, MLIR_PYTHON_CAPSULE_VALUE); |
| 456 | MlirValue value = {.ptr: ptr}; |
| 457 | return value; |
| 458 | } |
| 459 | |
| 460 | #ifdef __cplusplus |
| 461 | } |
| 462 | #endif |
| 463 | |
| 464 | #endif // MLIR_C_BINDINGS_PYTHON_INTEROP_H |
| 465 | |