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