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 | |