MLIR 23.0.0git
IRAffine.cpp
Go to the documentation of this file.
1//===- IRAffine.cpp - Exports 'ir' module affine related bindings ---------===//
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 <cstddef>
10#include <cstdint>
11#include <memory>
12#include <stdexcept>
13#include <string>
14#include <string_view>
15#include <utility>
16#include <vector>
17
18#include "mlir-c/AffineExpr.h"
19#include "mlir-c/AffineMap.h"
21// clang-format off
23#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind.
24// clang-format on
25#include "mlir-c/IntegerSet.h"
27
28namespace nb = nanobind;
29using namespace mlir;
31
32static const char kDumpDocstring[] =
33 R"(Dumps a debug representation of the object to stderr.)";
34
35/// Attempts to populate `result` with the content of `list` casted to the
36/// appropriate type (Python and C types are provided as template arguments).
37/// Throws errors in case of failure, using "action" to describe what the caller
38/// was attempting to do.
39template <typename PyType, typename CType>
40static void pyListToVector(const nb::sequence &list, std::vector<CType> &result,
41 std::string_view action) {
42 result.reserve(nb::len(list));
43 for (nb::handle item : list) {
44 try {
45 result.push_back(nb::cast<PyType>(item));
46 } catch (nb::cast_error &err) {
47 std::string msg = nanobind::detail::join("Invalid expression when ",
48 action, " (", err.what(), ")");
49 throw std::runtime_error(msg.c_str());
50 } catch (std::runtime_error &err) {
51 std::string msg = nanobind::detail::join(
52 "Invalid expression (None?) when ", action, " (", err.what(), ")");
53 throw std::runtime_error(msg.c_str());
54 }
55 }
56}
57
58template <typename PermutationTy>
59static bool isPermutation(const std::vector<PermutationTy> &permutation) {
60 std::vector<bool> seen(permutation.size(), false);
61 for (auto val : permutation) {
62 if (val < permutation.size()) {
63 if (seen[val])
64 return false;
65 seen[val] = true;
66 continue;
67 }
68 return false;
69 }
70 return true;
71}
72
73namespace mlir {
74namespace python {
76
77/// CRTP base class for Python MLIR affine expressions that subclass AffineExpr
78/// and should be castable from it. Intermediate hierarchy classes can be
79/// modeled by specifying BaseTy.
80template <typename DerivedTy, typename BaseTy = PyAffineExpr>
81class PyConcreteAffineExpr : public BaseTy {
82public:
83 // Derived classes must define statics for:
84 // IsAFunctionTy isaFunction
85 // const char *pyClassName
86 // and redefine bindDerived.
87 using ClassTy = nb::class_<DerivedTy, BaseTy>;
88 using IsAFunctionTy = bool (*)(MlirAffineExpr);
89
91 PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
92 : BaseTy(std::move(contextRef), affineExpr) {}
95
96 static MlirAffineExpr castFrom(PyAffineExpr &orig) {
97 if (!DerivedTy::isaFunction(orig)) {
98 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(orig)));
99 throw nb::value_error(
100 nanobind::detail::join("Cannot cast affine expression to ",
101 DerivedTy::pyClassName, " (from ", origRepr,
102 ")")
103 .c_str());
104 }
105 return orig;
106 }
107
108 static void bind(nb::module_ &m) {
109 auto cls = ClassTy(m, DerivedTy::pyClassName);
110 cls.def(nb::init<PyAffineExpr &>(), nb::arg("expr"));
111 DerivedTy::bindDerived(cls);
112 }
113
114 /// Implemented by derived classes to add methods to the Python subclass.
115 static void bindDerived(ClassTy &m) {}
116};
117
118class PyAffineConstantExpr : public PyConcreteAffineExpr<PyAffineConstantExpr> {
119public:
121 static constexpr const char *pyClassName = "AffineConstantExpr";
123
125 DefaultingPyMlirContext context) {
126 MlirAffineExpr affineExpr =
127 mlirAffineConstantExprGet(context->get(), static_cast<int64_t>(value));
128 return PyAffineConstantExpr(context->getRef(), affineExpr);
129 }
130
131 static void bindDerived(ClassTy &c) {
132 c.def_static("get", &PyAffineConstantExpr::get, nb::arg("value"),
133 nb::arg("context") = nb::none());
134 c.def_prop_ro("value", [](PyAffineConstantExpr &self) {
136 });
137 }
138};
139
140class PyAffineDimExpr : public PyConcreteAffineExpr<PyAffineDimExpr> {
141public:
143 static constexpr const char *pyClassName = "AffineDimExpr";
145
147 MlirAffineExpr affineExpr = mlirAffineDimExprGet(context->get(), pos);
148 return PyAffineDimExpr(context->getRef(), affineExpr);
149 }
150
151 static void bindDerived(ClassTy &c) {
152 c.def_static("get", &PyAffineDimExpr::get, nb::arg("position"),
153 nb::arg("context") = nb::none());
154 c.def_prop_ro("position", [](PyAffineDimExpr &self) {
155 return mlirAffineDimExprGetPosition(self);
156 });
157 }
158};
159
160class PyAffineSymbolExpr : public PyConcreteAffineExpr<PyAffineSymbolExpr> {
161public:
163 static constexpr const char *pyClassName = "AffineSymbolExpr";
165
167 MlirAffineExpr affineExpr = mlirAffineSymbolExprGet(context->get(), pos);
168 return PyAffineSymbolExpr(context->getRef(), affineExpr);
169 }
170
171 static void bindDerived(ClassTy &c) {
172 c.def_static("get", &PyAffineSymbolExpr::get, nb::arg("position"),
173 nb::arg("context") = nb::none());
174 c.def_prop_ro("position", [](PyAffineSymbolExpr &self) {
176 });
177 }
178};
179
180class PyAffineBinaryExpr : public PyConcreteAffineExpr<PyAffineBinaryExpr> {
181public:
183 static constexpr const char *pyClassName = "AffineBinaryExpr";
185
186 nb::typed<nb::object, PyAffineExpr> lhs() {
187 MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get());
188 return PyAffineExpr(getContext(), lhsExpr).maybeDownCast();
189 }
190
191 nb::typed<nb::object, PyAffineExpr> rhs() {
192 MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get());
193 return PyAffineExpr(getContext(), rhsExpr).maybeDownCast();
194 }
195
196 static void bindDerived(ClassTy &c) {
197 c.def_prop_ro("lhs", &PyAffineBinaryExpr::lhs);
198 c.def_prop_ro("rhs", &PyAffineBinaryExpr::rhs);
199 }
200};
201
203 : public PyConcreteAffineExpr<PyAffineAddExpr, PyAffineBinaryExpr> {
204public:
206 static constexpr const char *pyClassName = "AffineAddExpr";
208
210 MlirAffineExpr expr = mlirAffineAddExprGet(lhs, rhs);
211 return PyAffineAddExpr(lhs.getContext(), expr);
212 }
213
219
225
226 static void bindDerived(ClassTy &c) {
227 c.def_static("get", &PyAffineAddExpr::get);
228 }
229};
230
232 : public PyConcreteAffineExpr<PyAffineMulExpr, PyAffineBinaryExpr> {
233public:
235 static constexpr const char *pyClassName = "AffineMulExpr";
237
239 MlirAffineExpr expr = mlirAffineMulExprGet(lhs, rhs);
240 return PyAffineMulExpr(lhs.getContext(), expr);
241 }
242
248
254
255 static void bindDerived(ClassTy &c) {
256 c.def_static("get", &PyAffineMulExpr::get);
257 }
258};
259
261 : public PyConcreteAffineExpr<PyAffineModExpr, PyAffineBinaryExpr> {
262public:
264 static constexpr const char *pyClassName = "AffineModExpr";
266
268 MlirAffineExpr expr = mlirAffineModExprGet(lhs, rhs);
269 return PyAffineModExpr(lhs.getContext(), expr);
270 }
271
277
283
284 static void bindDerived(ClassTy &c) {
285 c.def_static("get", &PyAffineModExpr::get);
286 }
287};
288
290 : public PyConcreteAffineExpr<PyAffineFloorDivExpr, PyAffineBinaryExpr> {
291public:
293 static constexpr const char *pyClassName = "AffineFloorDivExpr";
295
297 MlirAffineExpr expr = mlirAffineFloorDivExprGet(lhs, rhs);
298 return PyAffineFloorDivExpr(lhs.getContext(), expr);
299 }
300
306
312
313 static void bindDerived(ClassTy &c) {
314 c.def_static("get", &PyAffineFloorDivExpr::get);
315 }
316};
317
319 : public PyConcreteAffineExpr<PyAffineCeilDivExpr, PyAffineBinaryExpr> {
320public:
322 static constexpr const char *pyClassName = "AffineCeilDivExpr";
324
326 MlirAffineExpr expr = mlirAffineCeilDivExprGet(lhs, rhs);
327 return PyAffineCeilDivExpr(lhs.getContext(), expr);
328 }
329
335
341
342 static void bindDerived(ClassTy &c) {
343 c.def_static("get", &PyAffineCeilDivExpr::get);
344 }
345};
346
347} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
348} // namespace python
349} // namespace mlir
350
351bool PyAffineExpr::operator==(const PyAffineExpr &other) const {
352 return mlirAffineExprEqual(affineExpr, other.affineExpr);
353}
354
356 return nb::steal<nb::object>(mlirPythonAffineExprToCapsule(*this));
357}
358
360 MlirAffineExpr rawAffineExpr = mlirPythonCapsuleToAffineExpr(capsule.ptr());
361 if (mlirAffineExprIsNull(rawAffineExpr))
362 throw nb::python_error();
363 return PyAffineExpr(
365 rawAffineExpr);
366}
367
368nb::typed<nb::object, PyAffineExpr> PyAffineExpr::maybeDownCast() {
369 MlirAffineExpr expr = get();
371 return nb::cast(PyAffineConstantExpr(getContext(), expr));
372 if (mlirAffineExprIsADim(expr))
373 return nb::cast(PyAffineDimExpr(getContext(), expr));
374 if (mlirAffineExprIsASymbol(expr))
375 return nb::cast(PyAffineSymbolExpr(getContext(), expr));
376 if (mlirAffineExprIsAAdd(expr))
377 return nb::cast(PyAffineAddExpr(getContext(), expr));
378 if (mlirAffineExprIsAMul(expr))
379 return nb::cast(PyAffineMulExpr(getContext(), expr));
380 if (mlirAffineExprIsAMod(expr))
381 return nb::cast(PyAffineModExpr(getContext(), expr));
383 return nb::cast(PyAffineFloorDivExpr(getContext(), expr));
384 if (mlirAffineExprIsACeilDiv(expr))
385 return nb::cast(PyAffineCeilDivExpr(getContext(), expr));
386 return nb::cast(*this);
387}
388
389//------------------------------------------------------------------------------
390// PyAffineMap and utilities.
391//------------------------------------------------------------------------------
392namespace mlir {
393namespace python {
395
396/// A list of expressions contained in an affine map. Internally these are
397/// stored as a consecutive array leading to inexpensive random access. Both
398/// the map and the expression are owned by the context so we need not bother
399/// with lifetime extension.
401 : public Sliceable<PyAffineMapExprList, PyAffineExpr> {
402public:
403 static constexpr const char *pyClassName = "AffineExprList";
404
406 intptr_t length = -1, intptr_t step = 1)
409 step),
410 affineMap(map) {}
411
412private:
413 /// Give the parent CRTP class access to hook implementations below.
415
416 intptr_t getRawNumElements() { return mlirAffineMapGetNumResults(affineMap); }
417
418 PyAffineExpr getRawElement(intptr_t pos) {
419 return PyAffineExpr(affineMap.getContext(),
420 mlirAffineMapGetResult(affineMap, pos));
421 }
422
424 intptr_t step) {
425 return PyAffineMapExprList(affineMap, startIndex, length, step);
426 }
427
428 PyAffineMap affineMap;
429};
430} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
431} // namespace python
432} // namespace mlir
433
434bool PyAffineMap::operator==(const PyAffineMap &other) const {
435 return mlirAffineMapEqual(affineMap, other.affineMap);
436}
437
439 return nb::steal<nb::object>(mlirPythonAffineMapToCapsule(*this));
440}
441
442PyAffineMap PyAffineMap::createFromCapsule(const nb::object &capsule) {
443 MlirAffineMap rawAffineMap = mlirPythonCapsuleToAffineMap(capsule.ptr());
444 if (mlirAffineMapIsNull(rawAffineMap))
445 throw nb::python_error();
446 return PyAffineMap(
448 rawAffineMap);
449}
450
451//------------------------------------------------------------------------------
452// PyIntegerSet and utilities.
453//------------------------------------------------------------------------------
454namespace mlir {
455namespace python {
457
459public:
461 : set(std::move(set)), pos(pos) {}
462
464 return PyAffineExpr(set.getContext(),
466 }
467
468 bool isEq() { return mlirIntegerSetIsConstraintEq(set, pos); }
469
470 static void bind(nb::module_ &m) {
471 nb::class_<PyIntegerSetConstraint>(m, "IntegerSetConstraint")
472 .def_prop_ro("expr", &PyIntegerSetConstraint::getExpr)
473 .def_prop_ro("is_eq", &PyIntegerSetConstraint::isEq);
474 }
475
476private:
477 PyIntegerSet set;
478 intptr_t pos;
479};
480
482 : public Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint> {
483public:
484 static constexpr const char *pyClassName = "IntegerSetConstraintList";
485
492
493private:
494 /// Give the parent CRTP class access to hook implementations below.
496
497 intptr_t getRawNumElements() { return mlirIntegerSetGetNumConstraints(set); }
498
499 PyIntegerSetConstraint getRawElement(intptr_t pos) {
500 return PyIntegerSetConstraint(set, pos);
501 }
502
503 PyIntegerSetConstraintList slice(intptr_t startIndex, intptr_t length,
504 intptr_t step) {
505 return PyIntegerSetConstraintList(set, startIndex, length, step);
506 }
507
508 PyIntegerSet set;
509};
510} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
511} // namespace python
512} // namespace mlir
513
514bool PyIntegerSet::operator==(const PyIntegerSet &other) const {
515 return mlirIntegerSetEqual(integerSet, other.integerSet);
516}
517
519 return nb::steal<nb::object>(mlirPythonIntegerSetToCapsule(*this));
520}
521
523 MlirIntegerSet rawIntegerSet = mlirPythonCapsuleToIntegerSet(capsule.ptr());
524 if (mlirIntegerSetIsNull(rawIntegerSet))
525 throw nb::python_error();
526 return PyIntegerSet(
528 rawIntegerSet);
529}
530
531namespace mlir {
532namespace python {
534void populateIRAffine(nb::module_ &m) {
535 //----------------------------------------------------------------------------
536 // Mapping of PyAffineExpr and derived classes.
537 //----------------------------------------------------------------------------
538 nb::class_<PyAffineExpr>(m, "AffineExpr")
541 .def("__add__", &PyAffineAddExpr::get)
542 .def("__add__", &PyAffineAddExpr::getRHSConstant)
543 .def("__radd__", &PyAffineAddExpr::getRHSConstant)
544 .def("__mul__", &PyAffineMulExpr::get)
545 .def("__mul__", &PyAffineMulExpr::getRHSConstant)
546 .def("__rmul__", &PyAffineMulExpr::getRHSConstant)
547 .def("__mod__", &PyAffineModExpr::get)
548 .def("__mod__", &PyAffineModExpr::getRHSConstant)
549 .def("__rmod__",
550 [](PyAffineExpr &self, intptr_t other) {
552 PyAffineConstantExpr::get(other, *self.getContext().get()),
553 self);
554 })
555 .def("__sub__",
556 [](PyAffineExpr &self, PyAffineExpr &other) {
557 auto negOne =
559 return PyAffineAddExpr::get(self,
560 PyAffineMulExpr::get(negOne, other));
561 })
562 .def("__sub__",
563 [](PyAffineExpr &self, intptr_t other) {
565 self,
566 PyAffineConstantExpr::get(-other, *self.getContext().get()));
567 })
568 .def("__rsub__",
569 [](PyAffineExpr &self, intptr_t other) {
571 other, PyAffineMulExpr::getLHSConstant(-1, self));
572 })
573 .def("__eq__", [](PyAffineExpr &self,
574 PyAffineExpr &other) { return self == other; })
575 .def("__eq__",
576 [](PyAffineExpr &self, nb::object &other) { return false; })
577 .def("__str__",
578 [](PyAffineExpr &self) {
579 PyPrintAccumulator printAccum;
580 mlirAffineExprPrint(self, printAccum.getCallback(),
581 printAccum.getUserData());
582 return printAccum.join();
583 })
584 .def("__repr__",
585 [](PyAffineExpr &self) {
586 PyPrintAccumulator printAccum;
587 printAccum.parts.append("AffineExpr(");
588 mlirAffineExprPrint(self, printAccum.getCallback(),
589 printAccum.getUserData());
590 printAccum.parts.append(")");
591 return printAccum.join();
592 })
593 .def("__hash__",
594 [](PyAffineExpr &self) {
595 return std::hash<const void *>{}(self.get().ptr);
596 })
597 .def_prop_ro(
598 "context",
599 [](PyAffineExpr &self) -> nb::typed<nb::object, PyMlirContext> {
600 return self.getContext().getObject();
601 })
602 .def("compose",
603 [](PyAffineExpr &self, PyAffineMap &other) {
604 return PyAffineExpr(self.getContext(),
605 mlirAffineExprCompose(self, other));
606 })
608 .def(
609 "shift_dims",
610 [](PyAffineExpr &self, uint32_t numDims, uint32_t shift,
611 uint32_t offset) {
612 return PyAffineExpr(
613 self.getContext(),
614 mlirAffineExprShiftDims(self, numDims, shift, offset));
615 },
616 nb::arg("num_dims"), nb::arg("shift"), nb::arg("offset") = 0)
617 .def(
618 "shift_symbols",
619 [](PyAffineExpr &self, uint32_t numSymbols, uint32_t shift,
620 uint32_t offset) {
621 return PyAffineExpr(
622 self.getContext(),
623 mlirAffineExprShiftSymbols(self, numSymbols, shift, offset));
624 },
625 nb::arg("num_symbols"), nb::arg("shift"), nb::arg("offset") = 0)
626 .def_static(
627 "simplify_affine_expr",
628 [](PyAffineExpr &self, uint32_t numDims, uint32_t numSymbols) {
629 return PyAffineExpr(
630 self.getContext(),
631 mlirSimplifyAffineExpr(self, numDims, numSymbols));
632 },
633 nb::arg("expr"), nb::arg("num_dims"), nb::arg("num_symbols"),
634 "Simplify an affine expression by flattening and some amount of "
635 "simple analysis.")
636 .def_static(
637 "get_add", &PyAffineAddExpr::get,
638 "Gets an affine expression containing a sum of two expressions.")
639 .def_static("get_add", &PyAffineAddExpr::getLHSConstant,
640 "Gets an affine expression containing a sum of a constant "
641 "and another expression.")
642 .def_static("get_add", &PyAffineAddExpr::getRHSConstant,
643 "Gets an affine expression containing a sum of an expression "
644 "and a constant.")
645 .def_static(
646 "get_mul", &PyAffineMulExpr::get,
647 "Gets an affine expression containing a product of two expressions.")
648 .def_static("get_mul", &PyAffineMulExpr::getLHSConstant,
649 "Gets an affine expression containing a product of a "
650 "constant and another expression.")
651 .def_static("get_mul", &PyAffineMulExpr::getRHSConstant,
652 "Gets an affine expression containing a product of an "
653 "expression and a constant.")
654 .def_static("get_mod", &PyAffineModExpr::get,
655 "Gets an affine expression containing the modulo of dividing "
656 "one expression by another.")
657 .def_static("get_mod", &PyAffineModExpr::getLHSConstant,
658 "Gets a semi-affine expression containing the modulo of "
659 "dividing a constant by an expression.")
660 .def_static("get_mod", &PyAffineModExpr::getRHSConstant,
661 "Gets an affine expression containing the module of dividing"
662 "an expression by a constant.")
663 .def_static("get_floor_div", &PyAffineFloorDivExpr::get,
664 "Gets an affine expression containing the rounded-down "
665 "result of dividing one expression by another.")
666 .def_static("get_floor_div", &PyAffineFloorDivExpr::getLHSConstant,
667 "Gets a semi-affine expression containing the rounded-down "
668 "result of dividing a constant by an expression.")
669 .def_static("get_floor_div", &PyAffineFloorDivExpr::getRHSConstant,
670 "Gets an affine expression containing the rounded-down "
671 "result of dividing an expression by a constant.")
672 .def_static("get_ceil_div", &PyAffineCeilDivExpr::get,
673 "Gets an affine expression containing the rounded-up result "
674 "of dividing one expression by another.")
675 .def_static("get_ceil_div", &PyAffineCeilDivExpr::getLHSConstant,
676 "Gets a semi-affine expression containing the rounded-up "
677 "result of dividing a constant by an expression.")
678 .def_static("get_ceil_div", &PyAffineCeilDivExpr::getRHSConstant,
679 "Gets an affine expression containing the rounded-up result "
680 "of dividing an expression by a constant.")
681 .def_static("get_constant", &PyAffineConstantExpr::get, nb::arg("value"),
682 nb::arg("context") = nb::none(),
683 "Gets a constant affine expression with the given value.")
684 .def_static(
685 "get_dim", &PyAffineDimExpr::get, nb::arg("position"),
686 nb::arg("context") = nb::none(),
687 "Gets an affine expression of a dimension at the given position.")
688 .def_static(
689 "get_symbol", &PyAffineSymbolExpr::get, nb::arg("position"),
690 nb::arg("context") = nb::none(),
691 "Gets an affine expression of a symbol at the given position.")
692 .def(
693 "dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); },
704
705 //----------------------------------------------------------------------------
706 // Mapping of PyAffineMap.
707 //----------------------------------------------------------------------------
708 nb::class_<PyAffineMap>(m, "AffineMap")
711 .def("__eq__",
712 [](PyAffineMap &self, PyAffineMap &other) { return self == other; })
713 .def("__eq__", [](PyAffineMap &self, nb::object &other) { return false; })
714 .def("__str__",
715 [](PyAffineMap &self) {
716 PyPrintAccumulator printAccum;
717 mlirAffineMapPrint(self, printAccum.getCallback(),
718 printAccum.getUserData());
719 return printAccum.join();
720 })
721 .def("__repr__",
722 [](PyAffineMap &self) {
723 PyPrintAccumulator printAccum;
724 printAccum.parts.append("AffineMap(");
725 mlirAffineMapPrint(self, printAccum.getCallback(),
726 printAccum.getUserData());
727 printAccum.parts.append(")");
728 return printAccum.join();
729 })
730 .def("__hash__",
731 [](PyAffineMap &self) {
732 return std::hash<const void *>{}(self.get().ptr);
733 })
734 .def_static(
735 "compress_unused_symbols",
736 [](nb::typed<nb::sequence, PyAffineMap> affineMaps,
737 DefaultingPyMlirContext context) {
738 std::vector<MlirAffineMap> maps;
740 affineMaps, maps, "attempting to create an AffineMap");
741 std::vector<MlirAffineMap> compressed(nb::len(affineMaps));
742 auto populate = [](void *result, intptr_t idx, MlirAffineMap m) {
743 static_cast<MlirAffineMap *>(result)[idx] = (m);
744 };
745 mlirAffineMapCompressUnusedSymbols(maps.data(), maps.size(),
746 compressed.data(), populate);
747 std::vector<PyAffineMap> res;
748 res.reserve(compressed.size());
749 for (auto m : compressed)
750 res.emplace_back(context->getRef(), m);
751 return res;
752 })
753 .def_prop_ro(
754 "context",
755 [](PyAffineMap &self) -> nb::typed<nb::object, PyMlirContext> {
756 return self.getContext().getObject();
757 },
758 "Context that owns the Affine Map")
759 .def(
760 "dump", [](PyAffineMap &self) { mlirAffineMapDump(self); },
762 .def_static(
763 "get",
764 [](intptr_t dimCount, intptr_t symbolCount,
765 nb::typed<nb::sequence, PyAffineExpr> exprs,
766 DefaultingPyMlirContext context) {
767 std::vector<MlirAffineExpr> affineExprs;
769 exprs, affineExprs, "attempting to create an AffineMap");
770 MlirAffineMap map =
771 mlirAffineMapGet(context->get(), dimCount, symbolCount,
772 affineExprs.size(), affineExprs.data());
773 return PyAffineMap(context->getRef(), map);
774 },
775 nb::arg("dim_count"), nb::arg("symbol_count"), nb::arg("exprs"),
776 nb::arg("context") = nb::none(),
777 "Gets a map with the given expressions as results.")
778 .def_static(
779 "get_constant",
780 [](intptr_t value, DefaultingPyMlirContext context) {
781 MlirAffineMap affineMap =
782 mlirAffineMapConstantGet(context->get(), value);
783 return PyAffineMap(context->getRef(), affineMap);
784 },
785 nb::arg("value"), nb::arg("context") = nb::none(),
786 "Gets an affine map with a single constant result")
787 .def_static(
788 "get_empty",
789 [](DefaultingPyMlirContext context) {
790 MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get());
791 return PyAffineMap(context->getRef(), affineMap);
792 },
793 nb::arg("context") = nb::none(), "Gets an empty affine map.")
794 .def_static(
795 "get_identity",
796 [](intptr_t nDims, DefaultingPyMlirContext context) {
797 MlirAffineMap affineMap =
798 mlirAffineMapMultiDimIdentityGet(context->get(), nDims);
799 return PyAffineMap(context->getRef(), affineMap);
800 },
801 nb::arg("n_dims"), nb::arg("context") = nb::none(),
802 "Gets an identity map with the given number of dimensions.")
803 .def_static(
804 "get_minor_identity",
805 [](intptr_t nDims, intptr_t nResults,
806 DefaultingPyMlirContext context) {
807 MlirAffineMap affineMap =
808 mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults);
809 return PyAffineMap(context->getRef(), affineMap);
810 },
811 nb::arg("n_dims"), nb::arg("n_results"),
812 nb::arg("context") = nb::none(),
813 "Gets a minor identity map with the given number of dimensions and "
814 "results.")
815 .def_static(
816 "get_permutation",
817 [](std::vector<unsigned> permutation,
818 DefaultingPyMlirContext context) {
819 if (!isPermutation(permutation))
820 throw std::runtime_error("Invalid permutation when attempting to "
821 "create an AffineMap");
822 MlirAffineMap affineMap = mlirAffineMapPermutationGet(
823 context->get(), permutation.size(), permutation.data());
824 return PyAffineMap(context->getRef(), affineMap);
825 },
826 nb::arg("permutation"), nb::arg("context") = nb::none(),
827 "Gets an affine map that permutes its inputs.")
828 .def(
829 "get_submap",
830 [](PyAffineMap &self, std::vector<intptr_t> &resultPos) {
831 intptr_t numResults = mlirAffineMapGetNumResults(self);
832 for (intptr_t pos : resultPos) {
833 if (pos < 0 || pos >= numResults)
834 throw nb::value_error("result position out of bounds");
835 }
836 MlirAffineMap affineMap = mlirAffineMapGetSubMap(
837 self, resultPos.size(), resultPos.data());
838 return PyAffineMap(self.getContext(), affineMap);
839 },
840 nb::arg("result_positions"))
841 .def(
842 "get_major_submap",
843 [](PyAffineMap &self, intptr_t nResults) {
844 if (nResults >= mlirAffineMapGetNumResults(self))
845 throw nb::value_error("number of results out of bounds");
846 MlirAffineMap affineMap =
847 mlirAffineMapGetMajorSubMap(self, nResults);
848 return PyAffineMap(self.getContext(), affineMap);
849 },
850 nb::arg("n_results"))
851 .def(
852 "get_minor_submap",
853 [](PyAffineMap &self, intptr_t nResults) {
854 if (nResults >= mlirAffineMapGetNumResults(self))
855 throw nb::value_error("number of results out of bounds");
856 MlirAffineMap affineMap =
857 mlirAffineMapGetMinorSubMap(self, nResults);
858 return PyAffineMap(self.getContext(), affineMap);
859 },
860 nb::arg("n_results"))
861 .def(
862 "replace",
863 [](PyAffineMap &self, PyAffineExpr &expression,
864 PyAffineExpr &replacement, intptr_t numResultDims,
865 intptr_t numResultSyms) {
866 MlirAffineMap affineMap = mlirAffineMapReplace(
867 self, expression, replacement, numResultDims, numResultSyms);
868 return PyAffineMap(self.getContext(), affineMap);
869 },
870 nb::arg("expr"), nb::arg("replacement"), nb::arg("n_result_dims"),
871 nb::arg("n_result_syms"))
872 .def_prop_ro(
873 "is_permutation",
874 [](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); })
875 .def_prop_ro("is_projected_permutation",
876 [](PyAffineMap &self) {
878 })
879 .def_prop_ro(
880 "n_dims",
881 [](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); })
882 .def_prop_ro(
883 "n_inputs",
884 [](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); })
885 .def_prop_ro(
886 "n_symbols",
887 [](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); })
888 .def_prop_ro("results",
889 [](PyAffineMap &self) { return PyAffineMapExprList(self); });
891
892 //----------------------------------------------------------------------------
893 // Mapping of PyIntegerSet.
894 //----------------------------------------------------------------------------
895 nb::class_<PyIntegerSet>(m, "IntegerSet")
898 .def("__eq__", [](PyIntegerSet &self,
899 PyIntegerSet &other) { return self == other; })
900 .def("__eq__",
901 [](PyIntegerSet &self, const nb::object &other) { return false; })
902 .def("__str__",
903 [](PyIntegerSet &self) {
904 PyPrintAccumulator printAccum;
905 mlirIntegerSetPrint(self, printAccum.getCallback(),
906 printAccum.getUserData());
907 return printAccum.join();
908 })
909 .def("__repr__",
910 [](PyIntegerSet &self) {
911 PyPrintAccumulator printAccum;
912 printAccum.parts.append("IntegerSet(");
913 mlirIntegerSetPrint(self, printAccum.getCallback(),
914 printAccum.getUserData());
915 printAccum.parts.append(")");
916 return printAccum.join();
917 })
918 .def("__hash__",
919 [](PyIntegerSet &self) {
920 return std::hash<const void *>{}(self.get().ptr);
921 })
922 .def_prop_ro(
923 "context",
924 [](PyIntegerSet &self) -> nb::typed<nb::object, PyMlirContext> {
925 return self.getContext().getObject();
926 })
927 .def(
928 "dump", [](PyIntegerSet &self) { mlirIntegerSetDump(self); },
930 .def_static(
931 "get",
932 [](intptr_t numDims, intptr_t numSymbols,
933 nb::typed<nb::sequence, PyAffineExpr> exprs,
934 std::vector<bool> eqFlags, DefaultingPyMlirContext context) {
935 if (nb::len(exprs) != eqFlags.size())
936 throw nb::value_error(
937 "Expected the number of constraints to match "
938 "that of equality flags");
939 if (nb::len(exprs) == 0)
940 throw nb::value_error("Expected non-empty list of constraints");
941
942 // std::vector<bool> does not expose a bool* data pointer.
943 std::vector<char> flags(eqFlags.begin(), eqFlags.end());
944 std::vector<MlirAffineExpr> affineExprs;
945 pyListToVector<PyAffineExpr>(exprs, affineExprs,
946 "attempting to create an IntegerSet");
947 MlirIntegerSet set = mlirIntegerSetGet(
948 context->get(), numDims, numSymbols, nb::len(exprs),
949 affineExprs.data(), reinterpret_cast<bool *>(flags.data()));
950 return PyIntegerSet(context->getRef(), set);
951 },
952 nb::arg("num_dims"), nb::arg("num_symbols"), nb::arg("exprs"),
953 nb::arg("eq_flags"), nb::arg("context") = nb::none())
954 .def_static(
955 "get_empty",
956 [](intptr_t numDims, intptr_t numSymbols,
957 DefaultingPyMlirContext context) {
958 MlirIntegerSet set =
959 mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols);
960 return PyIntegerSet(context->getRef(), set);
961 },
962 nb::arg("num_dims"), nb::arg("num_symbols"),
963 nb::arg("context") = nb::none())
964 .def(
965 "get_replaced",
966 [](PyIntegerSet &self, nb::typed<nb::sequence, PyAffineExpr> dimExprs,
967 nb::typed<nb::sequence, PyAffineExpr> symbolExprs,
968 intptr_t numResultDims, intptr_t numResultSymbols) {
969 if (static_cast<intptr_t>(nb::len(dimExprs)) !=
971 throw nb::value_error(
972 "Expected the number of dimension replacement expressions "
973 "to match that of dimensions");
974 if (static_cast<intptr_t>(nb::len(symbolExprs)) !=
976 throw nb::value_error(
977 "Expected the number of symbol replacement expressions "
978 "to match that of symbols");
979
980 std::vector<MlirAffineExpr> dimAffineExprs;
981 std::vector<MlirAffineExpr> symbolAffineExprs;
983 dimExprs, dimAffineExprs,
984 "attempting to create an IntegerSet by replacing dimensions");
986 symbolExprs, symbolAffineExprs,
987 "attempting to create an IntegerSet by replacing symbols");
988 MlirIntegerSet set = mlirIntegerSetReplaceGet(
989 self, dimAffineExprs.data(), symbolAffineExprs.data(),
990 numResultDims, numResultSymbols);
991 return PyIntegerSet(self.getContext(), set);
992 },
993 nb::arg("dim_exprs"), nb::arg("symbol_exprs"),
994 nb::arg("num_result_dims"), nb::arg("num_result_symbols"))
995 .def_prop_ro("is_canonical_empty",
996 [](PyIntegerSet &self) {
998 })
999 .def_prop_ro(
1000 "n_dims",
1001 [](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); })
1002 .def_prop_ro(
1003 "n_symbols",
1004 [](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); })
1005 .def_prop_ro(
1006 "n_inputs",
1007 [](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); })
1008 .def_prop_ro("n_equalities",
1009 [](PyIntegerSet &self) {
1010 return mlirIntegerSetGetNumEqualities(self);
1011 })
1012 .def_prop_ro("n_inequalities",
1013 [](PyIntegerSet &self) {
1015 })
1016 .def_prop_ro("constraints", [](PyIntegerSet &self) {
1017 return PyIntegerSetConstraintList(self);
1018 });
1021}
1022} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
1023} // namespace python
1024} // namespace mlir
MlirAffineExpr mlirAffineExprCompose(MlirAffineExpr affineExpr, MlirAffineMap affineMap)
void mlirAffineExprDump(MlirAffineExpr affineExpr)
MlirAffineExpr mlirAffineExprShiftDims(MlirAffineExpr affineExpr, uint32_t numDims, uint32_t shift, uint32_t offset)
void mlirAffineExprPrint(MlirAffineExpr affineExpr, MlirStringCallback callback, void *userData)
MlirAffineExpr mlirAffineExprShiftSymbols(MlirAffineExpr affineExpr, uint32_t numSymbols, uint32_t shift, uint32_t offset)
MlirAffineMap mlirAffineMapMultiDimIdentityGet(MlirContext ctx, intptr_t numDims)
Definition AffineMap.cpp:58
MlirAffineMap mlirAffineMapPermutationGet(MlirContext ctx, intptr_t size, unsigned *permutation)
Definition AffineMap.cpp:68
void mlirAffineMapDump(MlirAffineMap affineMap)
Definition AffineMap.cpp:35
bool mlirAffineMapIsProjectedPermutation(MlirAffineMap affineMap)
MlirAffineMap mlirAffineMapConstantGet(MlirContext ctx, int64_t val)
Definition AffineMap.cpp:54
MlirAffineExpr mlirAffineMapGetResult(MlirAffineMap affineMap, intptr_t pos)
intptr_t mlirAffineMapGetNumInputs(MlirAffineMap affineMap)
MlirAffineMap mlirAffineMapGet(MlirContext ctx, intptr_t dimCount, intptr_t symbolCount, intptr_t nAffineExprs, MlirAffineExpr *affineExprs)
Definition AffineMap.cpp:46
MlirAffineMap mlirAffineMapGetSubMap(MlirAffineMap affineMap, intptr_t size, intptr_t *resultPos)
void mlirAffineMapPrint(MlirAffineMap affineMap, MlirStringCallback callback, void *userData)
Definition AffineMap.cpp:29
MlirAffineMap mlirAffineMapEmptyGet(MlirContext ctx)
Definition AffineMap.cpp:37
MlirAffineMap mlirAffineMapGetMajorSubMap(MlirAffineMap affineMap, intptr_t numResults)
MlirAffineMap mlirAffineMapMinorIdentityGet(MlirContext ctx, intptr_t dims, intptr_t results)
Definition AffineMap.cpp:63
bool mlirAffineMapIsPermutation(MlirAffineMap affineMap)
MlirAffineMap mlirAffineMapGetMinorSubMap(MlirAffineMap affineMap, intptr_t numResults)
intptr_t mlirAffineMapGetNumDims(MlirAffineMap affineMap)
Definition AffineMap.cpp:94
intptr_t mlirAffineMapGetNumResults(MlirAffineMap affineMap)
MlirAffineMap mlirAffineMapReplace(MlirAffineMap affineMap, MlirAffineExpr expression, MlirAffineExpr replacement, intptr_t numResultDims, intptr_t numResultSyms)
intptr_t mlirAffineMapGetNumSymbols(MlirAffineMap affineMap)
Definition AffineMap.cpp:98
MlirIntegerSet mlirIntegerSetReplaceGet(MlirIntegerSet set, const MlirAffineExpr *dimReplacements, const MlirAffineExpr *symbolReplacements, intptr_t numResultDims, intptr_t numResultSymbols)
void mlirIntegerSetDump(MlirIntegerSet set)
intptr_t mlirIntegerSetGetNumSymbols(MlirIntegerSet set)
bool mlirIntegerSetIsCanonicalEmpty(MlirIntegerSet set)
intptr_t mlirIntegerSetGetNumEqualities(MlirIntegerSet set)
intptr_t mlirIntegerSetGetNumConstraints(MlirIntegerSet set)
intptr_t mlirIntegerSetGetNumInequalities(MlirIntegerSet set)
intptr_t mlirIntegerSetGetNumInputs(MlirIntegerSet set)
MlirIntegerSet mlirIntegerSetEmptyGet(MlirContext context, intptr_t numDims, intptr_t numSymbols)
void mlirIntegerSetPrint(MlirIntegerSet set, MlirStringCallback callback, void *userData)
MlirAffineExpr mlirIntegerSetGetConstraint(MlirIntegerSet set, intptr_t pos)
intptr_t mlirIntegerSetGetNumDims(MlirIntegerSet set)
MlirIntegerSet mlirIntegerSetGet(MlirContext context, intptr_t numDims, intptr_t numSymbols, intptr_t numConstraints, const MlirAffineExpr *constraints, const bool *eqFlags)
static void pyListToVector(const nb::sequence &list, std::vector< CType > &result, std::string_view action)
Attempts to populate result with the content of list casted to the appropriate type (Python and C typ...
Definition IRAffine.cpp:40
static bool isPermutation(const std::vector< PermutationTy > &permutation)
Definition IRAffine.cpp:59
static const char kDumpDocstring[]
Definition IRAffine.cpp:32
static MlirIntegerSet mlirPythonCapsuleToIntegerSet(PyObject *capsule)
Extracts an MlirIntegerSet from a capsule as produced from mlirPythonIntegerSetToCapsule.
Definition Interop.h:414
#define MLIR_PYTHON_MAYBE_DOWNCAST_ATTR
Attribute on MLIR Python objects that expose a function for downcasting the corresponding Python obje...
Definition Interop.h:118
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
Definition Interop.h:97
static MlirAffineMap mlirPythonCapsuleToAffineMap(PyObject *capsule)
Extracts an MlirAffineMap from a capsule as produced from mlirPythonAffineMapToCapsule.
Definition Interop.h:395
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
Definition Interop.h:110
static PyObject * mlirPythonAffineMapToCapsule(MlirAffineMap affineMap)
Creates a capsule object encapsulating the raw C-API MlirAffineMap.
Definition Interop.h:386
static PyObject * mlirPythonIntegerSetToCapsule(MlirIntegerSet integerSet)
Creates a capsule object encapsulating the raw C-API MlirIntegerSet.
Definition Interop.h:405
static MlirAffineExpr mlirPythonCapsuleToAffineExpr(PyObject *capsule)
Extracts an MlirAffineExpr from a capsule as produced from mlirPythonAffineExprToCapsule.
Definition Interop.h:170
static PyObject * mlirPythonAffineExprToCapsule(MlirAffineExpr expr)
Creates a capsule object encapsulating the raw C-API MlirAffineExpr.
Definition Interop.h:161
*if copies could not be generated due to yet unimplemented cases *copyInPlacementStart and copyOutPlacementStart in copyPlacementBlock *specify the insertion points where the incoming copies and outgoing should be the output argument nBegin is set to its * replacement(set to `begin` if no invalidation happens). Since outgoing *copies could have been inserted at `end`
A CRTP base class for pseudo-containers willing to support Python-type slicing access on top of index...
Sliceable(intptr_t startIndex, intptr_t length, intptr_t step)
ReferrentTy * get() const
PyMlirContextRef & getContext()
Accesses the context reference.
Definition IRCore.h:310
Used in function arguments when None should resolve to the current context manager set instance.
Definition IRCore.h:291
static PyAffineAddExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:220
static PyAffineAddExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:214
static PyAffineAddExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:209
static PyAffineCeilDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:325
static PyAffineCeilDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:330
static PyAffineCeilDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:336
static PyAffineConstantExpr get(intptr_t value, DefaultingPyMlirContext context)
Definition IRAffine.cpp:124
static PyAffineDimExpr get(intptr_t pos, DefaultingPyMlirContext context)
Definition IRAffine.cpp:146
Wrapper around MlirAffineExpr. Affine expressions are owned by the context.
Definition IRCore.h:1207
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineExpr.
Definition IRAffine.cpp:355
static PyAffineExpr createFromCapsule(const nanobind::object &capsule)
Creates a PyAffineExpr from the MlirAffineExpr wrapped by a capsule.
Definition IRAffine.cpp:359
PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition IRCore.h:1209
bool operator==(const PyAffineExpr &other) const
Definition IRAffine.cpp:351
nanobind::typed< nanobind::object, PyAffineExpr > maybeDownCast()
Definition IRAffine.cpp:368
static PyAffineFloorDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:301
static PyAffineFloorDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:296
static PyAffineFloorDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:307
A list of expressions contained in an affine map.
Definition IRAffine.cpp:401
PyAffineMapExprList(const PyAffineMap &map, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Definition IRAffine.cpp:405
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
Definition IRCore.h:1238
bool operator==(const PyAffineMap &other) const
Definition IRAffine.cpp:434
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineMap.
Definition IRAffine.cpp:438
static PyAffineMap createFromCapsule(const nanobind::object &capsule)
Creates a PyAffineMap from the MlirAffineMap wrapped by a capsule.
Definition IRAffine.cpp:442
static PyAffineModExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:278
static PyAffineModExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:272
static PyAffineModExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:267
static PyAffineMulExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:243
static PyAffineMulExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:238
static PyAffineMulExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:249
static PyAffineSymbolExpr get(intptr_t pos, DefaultingPyMlirContext context)
Definition IRAffine.cpp:166
PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition IRAffine.cpp:91
static void bindDerived(ClassTy &m)
Implemented by derived classes to add methods to the Python subclass.
Definition IRAffine.cpp:115
static MlirAffineExpr castFrom(PyAffineExpr &orig)
Definition IRAffine.cpp:96
PyIntegerSetConstraintList(const PyIntegerSet &set, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Definition IRAffine.cpp:486
PyIntegerSet(PyMlirContextRef contextRef, MlirIntegerSet integerSet)
Definition IRCore.h:1259
static PyIntegerSet createFromCapsule(const nanobind::object &capsule)
Creates a PyIntegerSet from the MlirAffineMap wrapped by a capsule.
Definition IRAffine.cpp:522
bool operator==(const PyIntegerSet &other) const
Definition IRAffine.cpp:514
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirIntegerSet.
Definition IRAffine.cpp:518
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
Definition IRCore.cpp:460
MLIR_CAPI_EXPORTED MlirAffineExpr mlirSimplifyAffineExpr(MlirAffineExpr expr, uint32_t numDims, uint32_t numSymbols)
Prints an affine expression by sending chunks of the string representation and forwarding userData to...
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAConstant(MlirAffineExpr affineExpr)
Checks whether the given affine expression is a constant expression.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineBinaryOpExprGetLHS(MlirAffineExpr affineExpr)
Returns the left hand side affine expression of the given affine binary operation expression.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineMulExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine mul expression with 'lhs' and 'rhs'.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx, int64_t constant)
Creates an affine constant expression with 'constant' in the context.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineBinaryOpExprGetRHS(MlirAffineExpr affineExpr)
Returns the right hand side affine expression of the given affine binary operation expression.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineAddExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine add expression with 'lhs' and 'rhs'.
MLIR_CAPI_EXPORTED intptr_t mlirAffineDimExprGetPosition(MlirAffineExpr affineExpr)
Returns the position of the given affine dimension expression.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAAdd(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an add expression.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsABinary(MlirAffineExpr affineExpr)
Checks whether the given affine expression is binary.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAMul(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an mul expression.
MLIR_CAPI_EXPORTED int64_t mlirAffineConstantExprGetValue(MlirAffineExpr affineExpr)
Returns the value of the given affine constant expression.
MLIR_CAPI_EXPORTED MlirContext mlirAffineExprGetContext(MlirAffineExpr affineExpr)
Gets the context that owns the affine expression.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsASymbol(MlirAffineExpr affineExpr)
Checks whether the given affine expression is a symbol expression.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsACeilDiv(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an ceildiv expression.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineFloorDivExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine floordiv expression with 'lhs' and 'rhs'.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAFloorDiv(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an floordiv expression.
MLIR_CAPI_EXPORTED bool mlirAffineExprEqual(MlirAffineExpr lhs, MlirAffineExpr rhs)
Returns true if the two affine expressions are equal.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx, intptr_t position)
Creates an affine dimension expression with 'position' in the context.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAMod(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an mod expression.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineModExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine mod expression with 'lhs' and 'rhs'.
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx, intptr_t position)
Creates an affine symbol expression with 'position' in the context.
static bool mlirAffineExprIsNull(MlirAffineExpr affineExpr)
Returns true if the given affine expression is a null expression.
Definition AffineExpr.h:54
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineCeilDivExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine ceildiv expression with 'lhs' and 'rhs'.
MLIR_CAPI_EXPORTED intptr_t mlirAffineSymbolExprGetPosition(MlirAffineExpr affineExpr)
Returns the position of the given affine symbol expression.
MLIR_CAPI_EXPORTED bool mlirAffineExprIsADim(MlirAffineExpr affineExpr)
Checks whether the given affine expression is a dimension expression.
MLIR_CAPI_EXPORTED bool mlirAffineMapEqual(MlirAffineMap a1, MlirAffineMap a2)
Checks if two affine maps are equal.
Definition AffineMap.cpp:25
MLIR_CAPI_EXPORTED MlirContext mlirAffineMapGetContext(MlirAffineMap affineMap)
Gets the context that the given affine map was created with.
Definition AffineMap.cpp:21
MLIR_CAPI_EXPORTED void mlirAffineMapCompressUnusedSymbols(MlirAffineMap *affineMaps, intptr_t size, void *result, void(*populateResult)(void *res, intptr_t idx, MlirAffineMap m))
Prints an affine map by sending chunks of the string representation and forwarding userData to callba...
static bool mlirAffineMapIsNull(MlirAffineMap affineMap)
Checks whether an affine map is null.
Definition AffineMap.h:47
static bool mlirIntegerSetIsNull(MlirIntegerSet set)
Checks whether an integer set is a null object.
Definition IntegerSet.h:46
MLIR_CAPI_EXPORTED MlirContext mlirIntegerSetGetContext(MlirIntegerSet set)
Gets the context in which the given integer set lives.
MLIR_CAPI_EXPORTED bool mlirIntegerSetEqual(MlirIntegerSet s1, MlirIntegerSet s2)
Checks if two integer set objects are equal.
MLIR_CAPI_EXPORTED bool mlirIntegerSetIsConstraintEq(MlirIntegerSet set, intptr_t pos)
Prints an integer set by sending chunks of the string representation and forwarding userData to callb...
PyObjectRef< PyMlirContext > PyMlirContextRef
Wrapper around MlirContext.
Definition IRCore.h:210
Include the generated interface declarations.
std::string join(const Ts &...args)
Helper function to concatenate arguments into a std::string.
Accumulates into a python string from a method that accepts an MlirStringCallback.
MlirStringCallback getCallback()