MLIR 24.0.0git
IRInterfaces.cpp
Go to the documentation of this file.
1//===- IRInterfaces.cpp - MLIR IR interfaces pybind -----------------------===//
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
9#include <cstdint>
10#include <optional>
11#include <string>
12#include <utility>
13#include <vector>
14
16#include "mlir-c/IR.h"
17#include "mlir-c/Interfaces.h"
18#include "mlir-c/Support.h"
21
22namespace nb = nanobind;
23
24namespace mlir {
25namespace python {
27constexpr static const char *inferReturnTypesDoc =
28 R"(Given the arguments required to build an operation, attempts to infer
29its return types. Raises ValueError on failure.)";
30
31constexpr static const char *inferReturnTypeComponentsDoc =
32 R"(Given the arguments required to build an operation, attempts to infer
33its return shaped type components. Raises ValueError on failure.)";
34
35namespace {
36
37MlirAttribute unwrapOptionalAttribute(const nb::object &attribute) {
38 if (attribute.is_none())
39 return mlirAttributeGetNull();
40
41 PyAttribute *pyAttribute = nullptr;
42 if (!nb::try_cast<PyAttribute *>(attribute, pyAttribute) || !pyAttribute)
43 throw nb::type_error("parameters must be an Attribute or None");
44 return pyAttribute->get();
45}
46
47MlirMemoryEffectInstance createMemoryEffectInstance(
48 const PyMemoryEffect &effect, const nb::object &target,
49 const nb::object &parameters, int stage, bool effectOnFullRegion,
50 const PySideEffectResource &resource) {
51 MlirAttribute unwrappedParameters = unwrapOptionalAttribute(parameters);
52
53 MlirMemoryEffectInstance rawInstance{nullptr};
54 if (target.is_none()) {
55 rawInstance =
56 mlirMemoryEffectInstanceCreate(effect.get(), unwrappedParameters, stage,
57 effectOnFullRegion, resource.get());
58 } else {
59 PyOpOperand *opOperand = nullptr;
60 PyValue *value = nullptr;
61 PyAttribute *attribute = nullptr;
62 if (nb::try_cast<PyOpOperand *>(target, opOperand) && opOperand) {
64 effect.get(), *opOperand, unwrappedParameters, stage,
65 effectOnFullRegion, resource.get());
66 } else if (nb::try_cast<PyValue *>(target, value) && value) {
67 MlirValue mlirValue = value->get();
68 if (mlirValueIsAOpResult(mlirValue)) {
70 effect.get(), mlirValue, unwrappedParameters, stage,
71 effectOnFullRegion, resource.get());
72 } else if (mlirValueIsABlockArgument(mlirValue)) {
74 effect.get(), mlirValue, unwrappedParameters, stage,
75 effectOnFullRegion, resource.get());
76 } else {
77 throw nb::type_error(
78 "target Value must be an OpResult or BlockArgument");
79 }
80 } else if (nb::try_cast<PyAttribute *>(target, attribute) && attribute) {
81 MlirAttribute symbol = attribute->get();
82 if (!mlirAttributeIsASymbolRef(symbol))
83 throw nb::type_error("target Attribute must be a SymbolRefAttr");
85 effect.get(), symbol, unwrappedParameters, stage, effectOnFullRegion,
86 resource.get());
87 } else {
88 throw nb::type_error(
89 "target must be an OpOperand, OpResult, BlockArgument, "
90 "SymbolRefAttr, or None");
91 }
92 }
93 return rawInstance;
94}
95
96/// Takes in an optional ist of operands and converts them into a std::vector
97/// of MlirVlaues. Returns an empty std::vector if the list is empty.
98std::vector<MlirValue> wrapOperands(std::optional<nb::sequence> operandList) {
99 std::vector<MlirValue> mlirOperands;
100
101 if (!operandList || nb::len(*operandList) == 0) {
102 return mlirOperands;
103 }
104
105 // Note: as the list may contain other lists this may not be final size.
106 mlirOperands.reserve(nb::len(*operandList));
107 for (size_t i = 0, e = nb::len(*operandList); i < e; ++i) {
108 nb::handle operand = (*operandList)[i];
109 intptr_t index = static_cast<intptr_t>(i);
110 if (operand.is_none())
111 continue;
112
113 PyValue *val;
114 try {
115 val = nb::cast<PyValue *>(operand);
116 if (!val)
117 throw nb::cast_error();
118 mlirOperands.push_back(val->get());
119 continue;
120 } catch (nb::cast_error &err) {
121 // Intentionally unhandled to try sequence below first.
122 (void)err;
123 }
124
125 try {
126 auto vals = nb::cast<nb::sequence>(operand);
127 for (nb::handle v : vals) {
128 try {
129 val = nb::cast<PyValue *>(v);
130 if (!val)
131 throw nb::cast_error();
132 mlirOperands.push_back(val->get());
133 } catch (nb::cast_error &err) {
134 throw nb::value_error(
135 nanobind::detail::join("Operand ", index,
136 " must be a Value or Sequence of Values (",
137 err.what(), ")")
138 .c_str());
139 }
140 }
141 continue;
142 } catch (nb::cast_error &err) {
143 throw nb::value_error(
144 nanobind::detail::join("Operand ", index,
145 " must be a Value or Sequence of Values (",
146 err.what(), ")")
147 .c_str());
148 }
149
150 throw nb::cast_error();
151 }
152
153 return mlirOperands;
154}
155
156/// Takes in an optional vector of PyRegions and returns a std::vector of
157/// MlirRegion. Returns an empty std::vector if the list is empty.
158std::vector<MlirRegion>
159wrapRegions(std::optional<std::vector<PyRegion>> regions) {
160 std::vector<MlirRegion> mlirRegions;
161
162 if (regions) {
163 mlirRegions.reserve(regions->size());
164 for (PyRegion &region : *regions) {
165 mlirRegions.push_back(region);
166 }
167 }
168
169 return mlirRegions;
170}
171
172} // namespace
173
175 const PyMemoryEffect &effect, const nb::object &target,
176 const nb::object &parameters, int stage, bool effectOnFullRegion,
177 const PySideEffectResource &resource)
178 : PyMemoryEffectInstance(createMemoryEffectInstance(
179 effect, target, parameters, stage, effectOnFullRegion, resource)) {}
180
184
188
192
196
198 MlirAttribute parameters = mlirMemoryEffectInstanceGetParameters(instance);
199 if (mlirAttributeIsNull(parameters))
200 return nb::none();
201 PyMlirContextRef context =
203 return PyAttribute(context, parameters).maybeDownCast();
204}
205
207 MlirValue value = mlirMemoryEffectInstanceGetValue(instance);
208 if (mlirValueIsNull(value))
209 return nb::none();
210 MlirOperation owner =
212 ? mlirOpResultGetOwner(value)
214 PyMlirContextRef context =
216 return PyValue(PyOperation::forOperation(context, owner), value)
217 .maybeDownCast();
218}
219
221 MlirAttribute symbol = mlirMemoryEffectInstanceGetSymbolRef(instance);
222 if (mlirAttributeIsNull(symbol))
223 return nb::none();
224 PyMlirContextRef context =
226 return PyAttribute(context, symbol).maybeDownCast();
227}
228
229/// Python wrapper for InferTypeOpInterface. This interface has only static
230/// methods.
232 : public PyConcreteOpInterface<PyInferTypeOpInterface> {
233public:
235
236 constexpr static const char *pyClassName = "InferTypeOpInterface";
239
240 /// C-style user-data structure for type appending callback.
245
246 /// Appends the types provided as the two first arguments to the user-data
247 /// structure (expects AppendResultsCallbackData).
248 static void appendResultsCallback(intptr_t nTypes, MlirType *types,
249 void *userData) {
250 auto *data = static_cast<AppendResultsCallbackData *>(userData);
251 data->inferredTypes.reserve(data->inferredTypes.size() + nTypes);
252 for (intptr_t i = 0; i < nTypes; ++i) {
253 data->inferredTypes.emplace_back(data->pyMlirContext.getRef(), types[i]);
254 }
255 }
256
257 /// Given the arguments required to build an operation, attempts to infer its
258 /// return types. Throws value_error on failure.
259 std::vector<PyType>
260 inferReturnTypes(std::optional<nb::sequence> operandList,
261 std::optional<PyAttribute> attributes, void *properties,
262 std::optional<std::vector<PyRegion>> regions,
264 DefaultingPyLocation location) {
265 std::vector<MlirValue> mlirOperands = wrapOperands(std::move(operandList));
266 std::vector<MlirRegion> mlirRegions = wrapRegions(std::move(regions));
267
268 std::vector<PyType> inferredTypes;
269 PyMlirContext &pyContext = context.resolve();
270 AppendResultsCallbackData data{inferredTypes, pyContext};
271 MlirStringRef opNameRef =
272 mlirStringRefCreate(getOpName().data(), getOpName().length());
273 MlirAttribute attributeDict =
274 attributes ? attributes->get() : mlirAttributeGetNull();
275
277 opNameRef, pyContext.get(), location.resolve(), mlirOperands.size(),
278 mlirOperands.data(), attributeDict, properties, mlirRegions.size(),
279 mlirRegions.data(), &appendResultsCallback, &data);
280
282 throw nb::value_error("Failed to infer result types");
283 }
284
285 return inferredTypes;
286 }
287
288 static void bindDerived(ClassTy &cls) {
289 cls.def("inferReturnTypes", &PyInferTypeOpInterface::inferReturnTypes,
290 nb::arg("operands") = nb::none(),
291 nb::arg("attributes") = nb::none(),
292 nb::arg("properties") = nb::none(), nb::arg("regions") = nb::none(),
293 nb::arg("context") = nb::none(), nb::arg("loc") = nb::none(),
295 }
296};
297
298/// Wrapper around an shaped type components.
300public:
301 PyShapedTypeComponents(MlirType elementType) : elementType(elementType) {}
302 PyShapedTypeComponents(nb::list shape, MlirType elementType)
303 : shape(std::move(shape)), elementType(elementType), ranked(true) {}
304 PyShapedTypeComponents(nb::list shape, MlirType elementType,
305 MlirAttribute attribute)
306 : shape(std::move(shape)), elementType(elementType), attribute(attribute),
307 ranked(true) {}
310 : shape(other.shape), elementType(other.elementType),
311 attribute(other.attribute), ranked(other.ranked) {}
312
313 static void bind(nb::module_ &m) {
314 nb::class_<PyShapedTypeComponents>(m, "ShapedTypeComponents")
315 .def_prop_ro(
316 "element_type",
317 [](PyShapedTypeComponents &self) { return self.elementType; },
318 nb::sig("def element_type(self) -> Type"),
319 "Returns the element type of the shaped type components.")
320 .def_static(
321 "get",
322 [](PyType &elementType) {
323 return PyShapedTypeComponents(elementType);
324 },
325 nb::arg("element_type"),
326 "Create an shaped type components object with only the element "
327 "type.")
328 .def_static(
329 "get",
330 [](nb::typed<nb::list, nb::int_> shape, PyType &elementType) {
331 return PyShapedTypeComponents(std::move(shape), elementType);
332 },
333 nb::arg("shape"), nb::arg("element_type"),
334 "Create a ranked shaped type components object.")
335 .def_static(
336 "get",
337 [](nb::typed<nb::list, nb::int_> shape, PyType &elementType,
338 PyAttribute &attribute) {
339 return PyShapedTypeComponents(std::move(shape), elementType,
340 attribute);
341 },
342 nb::arg("shape"), nb::arg("element_type"), nb::arg("attribute"),
343 "Create a ranked shaped type components object with attribute.")
344 .def_prop_ro(
345 "has_rank",
346 [](PyShapedTypeComponents &self) -> bool { return self.ranked; },
347 "Returns whether the given shaped type component is ranked.")
348 .def_prop_ro(
349 "rank",
350 [](PyShapedTypeComponents &self) -> std::optional<nb::int_> {
351 if (!self.ranked)
352 return {};
353 return nb::int_(self.shape.size());
354 },
355 "Returns the rank of the given ranked shaped type components. If "
356 "the shaped type components does not have a rank, None is "
357 "returned.")
358 .def_prop_ro(
359 "shape",
360 [](PyShapedTypeComponents &self) -> std::optional<nb::list> {
361 if (!self.ranked)
362 return {};
363 return nb::list(self.shape);
364 },
365 "Returns the shape of the ranked shaped type components as a list "
366 "of integers. Returns none if the shaped type component does not "
367 "have a rank.");
368 }
369
370 nb::object getCapsule();
371 static PyShapedTypeComponents createFromCapsule(nb::object capsule);
372
373private:
374 nb::list shape;
375 MlirType elementType;
376 MlirAttribute attribute;
377 bool ranked{false};
378};
379
380/// Python wrapper for InferShapedTypeOpInterface. This interface has only
381/// static methods.
383 : public PyConcreteOpInterface<PyInferShapedTypeOpInterface> {
384public:
387
388 constexpr static const char *pyClassName = "InferShapedTypeOpInterface";
391
392 /// C-style user-data structure for type appending callback.
394 std::vector<PyShapedTypeComponents> &inferredShapedTypeComponents;
395 };
396
397 /// Appends the shaped type components provided as unpacked shape, element
398 /// type, attribute to the user-data.
399 static void appendResultsCallback(bool hasRank, intptr_t rank,
400 const int64_t *shape, MlirType elementType,
401 MlirAttribute attribute, void *userData) {
402 auto *data = static_cast<AppendResultsCallbackData *>(userData);
403 if (!hasRank) {
404 data->inferredShapedTypeComponents.emplace_back(elementType);
405 } else {
406 nb::list shapeList;
407 for (intptr_t i = 0; i < rank; ++i) {
408 shapeList.append(shape[i]);
409 }
410 data->inferredShapedTypeComponents.emplace_back(shapeList, elementType,
411 attribute);
412 }
413 }
414
415 /// Given the arguments required to build an operation, attempts to infer the
416 /// shaped type components. Throws value_error on failure.
417 std::vector<PyShapedTypeComponents> inferReturnTypeComponents(
418 std::optional<nb::sequence> operandList,
419 std::optional<PyAttribute> attributes, void *properties,
420 std::optional<std::vector<PyRegion>> regions,
422 std::vector<MlirValue> mlirOperands = wrapOperands(std::move(operandList));
423 std::vector<MlirRegion> mlirRegions = wrapRegions(std::move(regions));
424
425 std::vector<PyShapedTypeComponents> inferredShapedTypeComponents;
426 PyMlirContext &pyContext = context.resolve();
427 AppendResultsCallbackData data{inferredShapedTypeComponents};
428 MlirStringRef opNameRef =
429 mlirStringRefCreate(getOpName().data(), getOpName().length());
430 MlirAttribute attributeDict =
431 attributes ? attributes->get() : mlirAttributeGetNull();
432
434 opNameRef, pyContext.get(), location.resolve(), mlirOperands.size(),
435 mlirOperands.data(), attributeDict, properties, mlirRegions.size(),
436 mlirRegions.data(), &appendResultsCallback, &data);
437
439 throw nb::value_error("Failed to infer result shape type components");
440 }
441
442 return inferredShapedTypeComponents;
443 }
444
445 static void bindDerived(ClassTy &cls) {
446 cls.def("inferReturnTypeComponents",
448 nb::arg("operands") = nb::none(),
449 nb::arg("attributes") = nb::none(), nb::arg("regions") = nb::none(),
450 nb::arg("properties") = nb::none(), nb::arg("context") = nb::none(),
451 nb::arg("loc") = nb::none(), inferReturnTypeComponentsDoc);
452 }
453};
454
455/// Wrapper around the ConditionallySpeculatable interface.
457 : public PyConcreteOpInterface<PyConditionallySpeculatableOpInterface> {
458public:
461
462 constexpr static const char *pyClassName = "ConditionallySpeculatable";
465
466 /// Attach a new ConditionallySpeculatable FallbackModel to the named
467 /// operation. The FallbackModel acts as a trampoline for callbacks on the
468 /// Python class.
469 static void attach(nb::object &target, const std::string &opName,
472 callbacks.userData = target.ptr();
473 nb::handle(static_cast<PyObject *>(callbacks.userData)).inc_ref();
474 callbacks.construct = nullptr;
475 callbacks.destruct = [](void *userData) {
476 nb::handle(static_cast<PyObject *>(userData)).dec_ref();
477 };
478 callbacks.getSpeculatability = [](MlirOperation op, void *userData) {
479 nb::handle pyClass(static_cast<PyObject *>(userData));
480
481 auto pyGetSpeculatability =
482 nb::cast<nb::callable>(nb::getattr(pyClass, "get_speculatability"));
483
484 PyMlirContextRef context =
486 auto opview = PyOperation::forOperation(context, op)->createOpView();
487
488 return nb::cast<MlirSpeculatability>(pyGetSpeculatability(opview));
489 };
490
492 ctx->get(), mlirStringRefCreate(opName.c_str(), opName.size()),
493 callbacks);
494 }
495
496 static void bindDerived(ClassTy &cls) {
497 cls.def(
498 "getSpeculatability",
500 if (self.isStatic())
501 throw nb::type_error(
502 "Cannot query speculatability on a static interface");
503 auto operation = self.getOperationObject();
504 auto *pyOperation = nb::cast<PyOperation *>(operation);
506 pyOperation->get());
507 },
508 "Returns the speculatability of the given operation.");
509 cls.attr("attach") = classmethod(
510 [](const nb::object &cls, const nb::object &opName, nb::object target,
511 DefaultingPyMlirContext context) {
512 if (target.is_none())
513 target = cls;
514 return attach(target, nb::cast<std::string>(opName), context);
515 },
516 nb::arg("cls"), nb::arg("op_name"), nb::kw_only(),
517 nb::arg("target").none() = nb::none(),
518 nb::arg("context").none() = nb::none(),
519 "Attach the interface subclass to the given operation name.");
520 }
521};
522
523/// Wrapper around the MemoryEffectsOpInterface.
525 : public PyConcreteOpInterface<PyMemoryEffectsOpInterface> {
526public:
529
530 constexpr static const char *pyClassName = "MemoryEffectsOpInterface";
533
534 /// Attach a new MemoryEffectsOpInterface FallbackModel to the named
535 /// operation. The FallbackModel acts as a trampoline for callbacks on the
536 /// Python class.
537 static void attach(nb::object &target, const std::string &opName,
540 callbacks.userData = target.ptr();
541 nb::handle(static_cast<PyObject *>(callbacks.userData)).inc_ref();
542 callbacks.construct = nullptr;
543 callbacks.destruct = [](void *userData) {
544 nb::handle(static_cast<PyObject *>(userData)).dec_ref();
545 };
546 callbacks.getEffects = [](MlirOperation op,
548 void *callbackUserData, void *userData) {
549 nb::handle pyClass(static_cast<PyObject *>(userData));
550
551 // Get the 'get_effects' method from the Python class.
552 auto pyGetEffects =
553 nb::cast<nb::callable>(nb::getattr(pyClass, "get_effects"));
554
555 PyMlirContextRef context =
557 auto opview = PyOperation::forOperation(context, op)->createOpView();
558
559 // Invoke `pyClass.get_effects(op)` and pass the resulting instances back
560 // to the C++ interface as a borrowed array.
561 nb::object result = pyGetEffects(opview);
562 nb::iterable iterable;
563 if (!nb::try_cast<nb::iterable>(result, iterable))
564 throw nb::type_error("get_effects must return an iterable");
565
566 std::vector<nb::object> effectObjects;
567 std::vector<MlirMemoryEffectInstance> effects;
568 for (nb::handle object : iterable) {
569 PyMemoryEffectInstance *effect = nullptr;
570 if (!nb::try_cast<PyMemoryEffectInstance *>(object, effect) ||
571 !effect) {
572 throw nb::type_error(
573 "get_effects must return MemoryEffectInstance objects");
574 }
575 effectObjects.push_back(nb::borrow<nb::object>(object));
576 effects.push_back(effect->get());
577 }
578 callback(effects.size(), effects.data(), callbackUserData);
579 };
580
582 ctx->get(), mlirStringRefCreate(opName.c_str(), opName.size()),
583 callbacks);
584 }
585
586 std::vector<PyMemoryEffectInstance> getEffects() {
587 if (isStatic())
588 throw nb::type_error("Cannot query effects on a static interface");
589
590 auto operationObject = getOperationObject();
591 auto *operation = nb::cast<PyOperation *>(operationObject);
592 std::vector<PyMemoryEffectInstance> effects;
593
595 operation->get(),
596 [](intptr_t numEffects, MlirMemoryEffectInstance *effects,
597 void *userData) {
598 auto *result =
599 static_cast<std::vector<PyMemoryEffectInstance> *>(userData);
600 result->reserve(result->size() + numEffects);
601 for (intptr_t i = 0; i < numEffects; ++i) {
602 result->emplace_back(mlirMemoryEffectInstanceClone(effects[i]));
603 }
604 },
605 &effects);
606 return effects;
607 }
608
609 static void bindDerived(ClassTy &cls) {
610 cls.def("get_effects", &PyMemoryEffectsOpInterface::getEffects,
611 nb::sig("def get_effects(self) -> list[MemoryEffectInstance]"),
612 "Returns the memory effects of the operation.");
613 cls.attr("attach") = classmethod(
614 [](const nb::object &cls, const nb::object &opName, nb::object target,
615 DefaultingPyMlirContext context) {
616 if (target.is_none())
617 target = cls;
618 return attach(target, nb::cast<std::string>(opName), context);
619 },
620 nb::arg("cls"), nb::arg("op_name"), nb::kw_only(),
621 nb::arg("target").none() = nb::none(),
622 nb::arg("context").none() = nb::none(),
623 "Attach the interface subclass to the given operation name.");
624 }
625};
626
627void populateIRInterfaces(nb::module_ &m) {
628 nb::enum_<MlirSpeculatability>(m, "Speculatability")
629 .value("NotSpeculatable", MlirSpeculatabilityNotSpeculatable)
630 .value("Speculatable", MlirSpeculatabilitySpeculatable)
631 .value("RecursivelySpeculatable",
633 nb::class_<PyMemoryEffect>(m, "MemoryEffect", "A memory effect.")
634 .def(
635 "__eq__",
636 [](const PyMemoryEffect &self, const PyMemoryEffect &other) {
639 },
640 nb::is_operator(), "Compares two memory effects for equality.")
641 .def_prop_ro_static("Allocate",
642 [](nb::object & /*class*/) {
643 return PyMemoryEffect(
645 })
646 .def_prop_ro_static("Free",
647 [](nb::object & /*class*/) {
649 })
650 .def_prop_ro_static("Read",
651 [](nb::object & /*class*/) {
653 })
654 .def_prop_ro_static("Write", [](nb::object & /*class*/) {
656 });
657
658 nb::class_<PySideEffectResource>(m, "SideEffectResource",
659 "A side effect resource.")
660 .def_prop_ro_static("Default", [](nb::object & /*class*/) {
662 });
663
664 nb::class_<PyMemoryEffectInstance>(m, "MemoryEffectInstance",
665 "A concrete instance of a memory effect.")
666 .def(nb::init<const PyMemoryEffect &, const nb::object &,
667 const nb::object &, int, bool,
668 const PySideEffectResource &>(),
669 nb::arg("effect"), nb::arg("target").none() = nb::none(),
670 nb::kw_only(), nb::arg("parameters").none() = nb::none(),
671 nb::arg("stage") = 0, nb::arg("effect_on_full_region") = false,
672 nb::arg("resource") =
674 nb::sig("def __init__(self, effect: MemoryEffect, target: "
675 "OpOperand | OpResult | BlockArgument | SymbolRefAttr | "
676 "FlatSymbolRefAttr | None = None, *, parameters: Attribute "
677 "| None = None, stage: int = 0, "
678 "effect_on_full_region: bool = False, resource: "
679 "SideEffectResource = ...) -> None"),
680 "Creates a memory effect instance. The target may be an OpOperand, "
681 "OpResult, BlockArgument, SymbolRefAttr, or None.")
682 .def_prop_ro("effect", &PyMemoryEffectInstance::getEffect,
683 "Returns the kind of memory effect.")
684 .def_prop_ro("resource", &PyMemoryEffectInstance::getResource,
685 "Returns the affected side effect resource.")
686 .def_prop_ro("stage", &PyMemoryEffectInstance::getStage,
687 "Returns the stage at which the effect occurs.")
688 .def_prop_ro("effect_on_full_region",
690 "Returns whether the effect applies to the full resource.")
691 .def_prop_ro("parameters", &PyMemoryEffectInstance::getParameters,
692 nb::sig("def parameters(self) -> Attribute | None"),
693 "Returns the effect parameters, if any.")
694 .def_prop_ro(
696 nb::sig("def value(self) -> OpResult | BlockArgument | None"),
697 "Returns the affected value, if any.")
698 .def_prop_ro("symbol_ref", &PyMemoryEffectInstance::getSymbolRef,
699 nb::sig("def symbol_ref(self) -> SymbolRefAttr | "
700 "FlatSymbolRefAttr | None"),
701 "Returns the affected symbol reference, if any.");
702
708}
709} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
710} // namespace python
711} // namespace mlir
true
Given two iterators into the same block, return "true" if a is before `b.
bool mlirValueIsABlockArgument(MlirValue value)
Definition IR.cpp:1170
MlirContext mlirAttributeGetContext(MlirAttribute attribute)
Definition IR.cpp:1345
MlirOperation mlirOpResultGetOwner(MlirValue value)
Definition IR.cpp:1197
MlirBlock mlirBlockArgumentGetOwner(MlirValue value)
Definition IR.cpp:1178
bool mlirValueIsAOpResult(MlirValue value)
Definition IR.cpp:1174
MlirContext mlirOperationGetContext(MlirOperation op)
Definition IR.cpp:695
ReferrentTy * get() const
Used in function arguments when None should resolve to the current context manager set instance.
Definition IRCore.h:551
Used in function arguments when None should resolve to the current context manager set instance.
Definition IRCore.h:291
Wrapper around the generic MlirAttribute.
Definition IRCore.h:1028
nanobind::typed< nanobind::object, PyAttribute > maybeDownCast()
Definition IRCore.cpp:1872
PyConcreteOpInterface(nanobind::object object, DefaultingPyMlirContext context)
nanobind::typed< nanobind::object, PyOperation > getOperationObject()
Returns the operation instance from which this object was constructed.
bool isStatic()
Returns true if this object was constructed from a subclass of OpView rather than from an operation i...
static void attach(nb::object &target, const std::string &opName, DefaultingPyMlirContext ctx)
Attach a new ConditionallySpeculatable FallbackModel to the named operation.
static void appendResultsCallback(bool hasRank, intptr_t rank, const int64_t *shape, MlirType elementType, MlirAttribute attribute, void *userData)
Appends the shaped type components provided as unpacked shape, element type, attribute to the user-da...
std::vector< PyShapedTypeComponents > inferReturnTypeComponents(std::optional< nb::sequence > operandList, std::optional< PyAttribute > attributes, void *properties, std::optional< std::vector< PyRegion > > regions, DefaultingPyMlirContext context, DefaultingPyLocation location)
Given the arguments required to build an operation, attempts to infer the shaped type components.
std::vector< PyType > inferReturnTypes(std::optional< nb::sequence > operandList, std::optional< PyAttribute > attributes, void *properties, std::optional< std::vector< PyRegion > > regions, DefaultingPyMlirContext context, DefaultingPyLocation location)
Given the arguments required to build an operation, attempts to infer its return types.
static void appendResultsCallback(intptr_t nTypes, MlirType *types, void *userData)
Appends the types provided as the two first arguments to the user-data structure (expects AppendResul...
static void attach(nb::object &target, const std::string &opName, DefaultingPyMlirContext ctx)
Attach a new MemoryEffectsOpInterface FallbackModel to the named operation.
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
Definition IRCore.cpp:461
MlirContext get()
Accesses the underlying MlirContext.
Definition IRCore.h:224
nanobind::object createOpView()
Creates an OpView suitable for this operation.
Definition IRCore.cpp:1352
static PyOperationRef forOperation(PyMlirContextRef contextRef, MlirOperation operation, nanobind::object parentKeepAlive=nanobind::object())
Returns a PyOperation for the given MlirOperation, optionally associating it with a parentKeepAlive.
Definition IRCore.cpp:958
PyShapedTypeComponents(nb::list shape, MlirType elementType, MlirAttribute attribute)
static PyShapedTypeComponents createFromCapsule(nb::object capsule)
PyShapedTypeComponents(PyShapedTypeComponents &&other) noexcept
Wrapper around the generic MlirType.
Definition IRCore.h:901
nanobind::typed< nanobind::object, std::variant< PyBlockArgument, PyOpResult, PyValue > > maybeDownCast()
Definition IRCore.cpp:1990
MLIR_CAPI_EXPORTED MlirAttribute mlirAttributeGetNull(void)
Returns an empty attribute.
MLIR_CAPI_EXPORTED bool mlirAttributeIsASymbolRef(MlirAttribute attr)
Checks whether the given attribute is a symbol reference attribute.
MLIR_CAPI_EXPORTED MlirOperation mlirBlockGetParentOperation(MlirBlock)
Returns the closest surrounding operation that contains this block.
Definition IR.cpp:1041
MLIR_CAPI_EXPORTED MlirLogicalResult mlirInferShapedTypeOpInterfaceInferReturnTypes(MlirStringRef opName, MlirContext context, MlirLocation location, intptr_t nOperands, MlirValue *operands, MlirAttribute attributes, void *properties, intptr_t nRegions, MlirRegion *regions, MlirShapedTypeComponentsCallback callback, void *userData)
Infers the return shaped type components of the operation.
MLIR_CAPI_EXPORTED MlirSpeculatability mlirConditionallySpeculatableOpInterfaceGetSpeculatability(MlirOperation operation)
Returns the speculatability of the given operation.
MLIR_CAPI_EXPORTED MlirTypeID mlirMemoryEffectGetEffectID(MlirMemoryEffect effect)
Returns the TypeID identifying the concrete type of the given memory effect.
MLIR_CAPI_EXPORTED MlirTypeID mlirInferTypeOpInterfaceTypeID(void)
Returns the interface TypeID of the InferTypeOpInterface.
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForOpOperand(MlirMemoryEffect effect, MlirOpOperand opOperand, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with an operation operand.
MLIR_CAPI_EXPORTED MlirAttribute mlirMemoryEffectInstanceGetSymbolRef(MlirMemoryEffectInstance instance)
Returns the symbol reference of the given instance, or a null attribute if there is no associated sym...
MLIR_CAPI_EXPORTED MlirTypeID mlirConditionallySpeculatableOpInterfaceTypeID(void)
Returns the interface TypeID of the ConditionallySpeculatable interface.
MLIR_CAPI_EXPORTED void mlirConditionallySpeculatableOpInterfaceAttachFallbackModel(MlirContext ctx, MlirStringRef opName, MlirConditionallySpeculatableOpInterfaceCallbacks callbacks)
Attach a new FallbackModel for the ConditionallySpeculatable interface to the named operation.
@ MlirSpeculatabilityRecursivelySpeculatable
The operation is speculatable if all nested operations are speculatable.
Definition Interfaces.h:113
@ MlirSpeculatabilitySpeculatable
The operation is speculatable.
Definition Interfaces.h:111
@ MlirSpeculatabilityNotSpeculatable
The operation is not speculatable.
Definition Interfaces.h:109
MLIR_CAPI_EXPORTED MlirSideEffectResource mlirMemoryEffectInstanceGetResource(MlirMemoryEffectInstance instance)
Returns the side effect resource of the given instance.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsReadGet(void)
Returns the singleton instance of the read memory effect.
MLIR_CAPI_EXPORTED MlirSideEffectResource mlirSideEffectsDefaultResourceGet(void)
Returns the singleton instance of the default side effect resource.
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreate(MlirMemoryEffect effect, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance without an associated IR entity.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectInstanceGetEffect(MlirMemoryEffectInstance instance)
Returns the memory effect of the given instance.
MLIR_CAPI_EXPORTED MlirLogicalResult mlirInferTypeOpInterfaceInferReturnTypes(MlirStringRef opName, MlirContext context, MlirLocation location, intptr_t nOperands, MlirValue *operands, MlirAttribute attributes, void *properties, intptr_t nRegions, MlirRegion *regions, MlirTypesCallback callback, void *userData)
Infers the return types of the operation identified by its canonical given the arguments that will be...
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForOpResult(MlirMemoryEffect effect, MlirValue result, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with an operation result.
MLIR_CAPI_EXPORTED MlirAttribute mlirMemoryEffectInstanceGetParameters(MlirMemoryEffectInstance instance)
Returns the parameters of the given instance, or a null attribute if there are no parameters.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsFreeGet(void)
Returns the singleton instance of the free memory effect.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsWriteGet(void)
Returns the singleton instance of the write memory effect.
MLIR_CAPI_EXPORTED void mlirMemoryEffectsOpInterfaceGetEffects(MlirOperation operation, MlirMemoryEffectInstancesCallback callback, void *userData)
Gets the memory effects of the given operation.
MLIR_CAPI_EXPORTED MlirTypeID mlirMemoryEffectsOpInterfaceTypeID(void)
Returns the interface TypeID of the MemoryEffectsOpInterface.
void(* MlirMemoryEffectInstancesCallback)(intptr_t numEffects, MlirMemoryEffectInstance *effects, void *userData)
Callback for receiving a batch of memory effect instances.
Definition Interfaces.h:262
MLIR_CAPI_EXPORTED MlirTypeID mlirInferShapedTypeOpInterfaceTypeID(void)
Returns the interface TypeID of the InferShapedTypeOpInterface.
MLIR_CAPI_EXPORTED void mlirMemoryEffectsOpInterfaceAttachFallbackModel(MlirContext ctx, MlirStringRef opName, MlirMemoryEffectsOpInterfaceCallbacks callbacks)
Attach a new FallbackModel for the MemoryEffectsOpInterface to the named operation.
MLIR_CAPI_EXPORTED bool mlirMemoryEffectInstanceGetEffectOnFullRegion(MlirMemoryEffectInstance instance)
Returns true if the given instance has effect on every single value of the resource.
MLIR_CAPI_EXPORTED int mlirMemoryEffectInstanceGetStage(MlirMemoryEffectInstance instance)
Returns the stage of the given instance.
MLIR_CAPI_EXPORTED MlirMemoryEffect mlirMemoryEffectsAllocateGet(void)
Returns the singleton instance of the allocate memory effect.
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForSymbol(MlirMemoryEffect effect, MlirAttribute symbol, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with a symbol.
MLIR_CAPI_EXPORTED MlirValue mlirMemoryEffectInstanceGetValue(MlirMemoryEffectInstance instance)
Returns the value (OpOperand, OpResult, or BlockArgument) of the given instance, or a null value if t...
MLIR_CAPI_EXPORTED MlirMemoryEffectInstance mlirMemoryEffectInstanceCreateForBlockArgument(MlirMemoryEffect effect, MlirValue blockArgument, MlirAttribute parameters, int stage, bool effectOnFullRegion, MlirSideEffectResource resource)
Creates a memory effect instance associated with a block argument.
static MlirStringRef mlirStringRefCreate(const char *str, size_t length)
Constructs a string reference from the pointer and length.
Definition Support.h:87
static bool mlirLogicalResultIsFailure(MlirLogicalResult res)
Checks if the given logical result represents a failure.
Definition Support.h:132
MLIR_CAPI_EXPORTED bool mlirTypeIDEqual(MlirTypeID typeID1, MlirTypeID typeID2)
Checks if two type ids are equal.
Definition Support.cpp:89
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
Definition IRCore.h:210
static constexpr const char * inferReturnTypesDoc
static constexpr const char * inferReturnTypeComponentsDoc
nanobind::object classmethod(Func f, Args... args)
Helper for creating an @classmethod.
Definition IRCore.h:2025
Include the generated interface declarations.
std::string join(const Ts &...args)
Helper function to concatenate arguments into a std::string.
Callbacks for implementing ConditionallySpeculatable from external code.
Definition Interfaces.h:121
void(* destruct)(void *userData)
Optional destructor for user data. Set to nullptr to disable it.
Definition Interfaces.h:125
void(* construct)(void *userData)
Optional constructor for user data. Set to nullptr to disable it.
Definition Interfaces.h:123
MlirSpeculatability(* getSpeculatability)(MlirOperation op, void *userData)
Returns the speculatability of the given operation.
Definition Interfaces.h:127
A logical result value, essentially a boolean with named states.
Definition Support.h:121
Callbacks for implementing MemoryEffectsOpInterface from external code.
Definition Interfaces.h:269
void(* construct)(void *userData)
Optional constructor for user data. Set to nullptr to disable it.
Definition Interfaces.h:271
void(* destruct)(void *userData)
Optional destructor for user data. Set to nullptr to disable it.
Definition Interfaces.h:273
void(* getEffects)(MlirOperation op, MlirMemoryEffectInstancesCallback callback, void *callbackUserData, void *userData)
Get memory effects callback.
Definition Interfaces.h:278
A pointer to a sized fragment of a string, not necessarily null-terminated.
Definition Support.h:78