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 (std::exception &err) {
47 if (item.is_none()) {
48 std::string msg = nanobind::detail::join(
49 "Invalid expression (None?) when ", action, " (", err.what(), ")");
50 throw std::runtime_error(msg.c_str());
51 }
52 std::string msg = nanobind::detail::join("Invalid expression when ",
53 action, " (", err.what(), ")");
54 throw std::runtime_error(msg.c_str());
55 }
56 }
57}
58
59template <typename PermutationTy>
60static bool isPermutation(const std::vector<PermutationTy> &permutation) {
61 std::vector<bool> seen(permutation.size(), false);
62 for (auto val : permutation) {
63 if (val < permutation.size()) {
64 if (seen[val])
65 return false;
66 seen[val] = true;
67 continue;
68 }
69 return false;
70 }
71 return true;
72}
73
74namespace mlir {
75namespace python {
77
78/// CRTP base class for Python MLIR affine expressions that subclass AffineExpr
79/// and should be castable from it. Intermediate hierarchy classes can be
80/// modeled by specifying BaseTy.
81template <typename DerivedTy, typename BaseTy = PyAffineExpr>
82class PyConcreteAffineExpr : public BaseTy {
83public:
84 // Derived classes must define statics for:
85 // IsAFunctionTy isaFunction
86 // const char *pyClassName
87 // and redefine bindDerived.
88 using ClassTy = nb::class_<DerivedTy, BaseTy>;
89 using IsAFunctionTy = bool (*)(MlirAffineExpr);
90
92 PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
93 : BaseTy(std::move(contextRef), affineExpr) {}
96
97 static MlirAffineExpr castFrom(PyAffineExpr &orig) {
98 if (!DerivedTy::isaFunction(orig)) {
99 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(orig)));
100 throw nb::value_error(
101 nanobind::detail::join("Cannot cast affine expression to ",
102 DerivedTy::pyClassName, " (from ", origRepr,
103 ")")
104 .c_str());
105 }
106 return orig;
107 }
108
109 static void bind(nb::module_ &m) {
110 auto cls = ClassTy(m, DerivedTy::pyClassName);
111 cls.def(nb::init<PyAffineExpr &>(), nb::arg("expr"));
112 DerivedTy::bindDerived(cls);
113 }
114
115 /// Implemented by derived classes to add methods to the Python subclass.
116 static void bindDerived(ClassTy &m) {}
117};
118
119class PyAffineConstantExpr : public PyConcreteAffineExpr<PyAffineConstantExpr> {
120public:
122 static constexpr const char *pyClassName = "AffineConstantExpr";
124
126 DefaultingPyMlirContext context) {
127 MlirAffineExpr affineExpr =
128 mlirAffineConstantExprGet(context->get(), static_cast<int64_t>(value));
129 return PyAffineConstantExpr(context->getRef(), affineExpr);
130 }
131
132 static void bindDerived(ClassTy &c) {
133 c.def_static("get", &PyAffineConstantExpr::get, nb::arg("value"),
134 nb::arg("context") = nb::none());
135 c.def_prop_ro("value", [](PyAffineConstantExpr &self) {
137 });
138 }
139};
140
141class PyAffineDimExpr : public PyConcreteAffineExpr<PyAffineDimExpr> {
142public:
144 static constexpr const char *pyClassName = "AffineDimExpr";
146
148 MlirAffineExpr affineExpr = mlirAffineDimExprGet(context->get(), pos);
149 return PyAffineDimExpr(context->getRef(), affineExpr);
150 }
151
152 static void bindDerived(ClassTy &c) {
153 c.def_static("get", &PyAffineDimExpr::get, nb::arg("position"),
154 nb::arg("context") = nb::none());
155 c.def_prop_ro("position", [](PyAffineDimExpr &self) {
156 return mlirAffineDimExprGetPosition(self);
157 });
158 }
159};
160
161class PyAffineSymbolExpr : public PyConcreteAffineExpr<PyAffineSymbolExpr> {
162public:
164 static constexpr const char *pyClassName = "AffineSymbolExpr";
166
168 MlirAffineExpr affineExpr = mlirAffineSymbolExprGet(context->get(), pos);
169 return PyAffineSymbolExpr(context->getRef(), affineExpr);
170 }
171
172 static void bindDerived(ClassTy &c) {
173 c.def_static("get", &PyAffineSymbolExpr::get, nb::arg("position"),
174 nb::arg("context") = nb::none());
175 c.def_prop_ro("position", [](PyAffineSymbolExpr &self) {
177 });
178 }
179};
180
181class PyAffineBinaryExpr : public PyConcreteAffineExpr<PyAffineBinaryExpr> {
182public:
184 static constexpr const char *pyClassName = "AffineBinaryExpr";
186
187 nb::typed<nb::object, PyAffineExpr> lhs() {
188 MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get());
189 return PyAffineExpr(getContext(), lhsExpr).maybeDownCast();
190 }
191
192 nb::typed<nb::object, PyAffineExpr> rhs() {
193 MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get());
194 return PyAffineExpr(getContext(), rhsExpr).maybeDownCast();
195 }
196
197 static void bindDerived(ClassTy &c) {
198 c.def_prop_ro("lhs", &PyAffineBinaryExpr::lhs);
199 c.def_prop_ro("rhs", &PyAffineBinaryExpr::rhs);
200 }
201};
202
204 : public PyConcreteAffineExpr<PyAffineAddExpr, PyAffineBinaryExpr> {
205public:
207 static constexpr const char *pyClassName = "AffineAddExpr";
209
211 MlirAffineExpr expr = mlirAffineAddExprGet(lhs, rhs);
212 return PyAffineAddExpr(lhs.getContext(), expr);
213 }
214
220
226
227 static void bindDerived(ClassTy &c) {
228 c.def_static("get", &PyAffineAddExpr::get);
229 }
230};
231
233 : public PyConcreteAffineExpr<PyAffineMulExpr, PyAffineBinaryExpr> {
234public:
236 static constexpr const char *pyClassName = "AffineMulExpr";
238
240 MlirAffineExpr expr = mlirAffineMulExprGet(lhs, rhs);
241 return PyAffineMulExpr(lhs.getContext(), expr);
242 }
243
249
255
256 static void bindDerived(ClassTy &c) {
257 c.def_static("get", &PyAffineMulExpr::get);
258 }
259};
260
262 : public PyConcreteAffineExpr<PyAffineModExpr, PyAffineBinaryExpr> {
263public:
265 static constexpr const char *pyClassName = "AffineModExpr";
267
269 MlirAffineExpr expr = mlirAffineModExprGet(lhs, rhs);
270 return PyAffineModExpr(lhs.getContext(), expr);
271 }
272
278
284
285 static void bindDerived(ClassTy &c) {
286 c.def_static("get", &PyAffineModExpr::get);
287 }
288};
289
291 : public PyConcreteAffineExpr<PyAffineFloorDivExpr, PyAffineBinaryExpr> {
292public:
294 static constexpr const char *pyClassName = "AffineFloorDivExpr";
296
298 MlirAffineExpr expr = mlirAffineFloorDivExprGet(lhs, rhs);
299 return PyAffineFloorDivExpr(lhs.getContext(), expr);
300 }
301
307
313
314 static void bindDerived(ClassTy &c) {
315 c.def_static("get", &PyAffineFloorDivExpr::get);
316 }
317};
318
320 : public PyConcreteAffineExpr<PyAffineCeilDivExpr, PyAffineBinaryExpr> {
321public:
323 static constexpr const char *pyClassName = "AffineCeilDivExpr";
325
327 MlirAffineExpr expr = mlirAffineCeilDivExprGet(lhs, rhs);
328 return PyAffineCeilDivExpr(lhs.getContext(), expr);
329 }
330
336
342
343 static void bindDerived(ClassTy &c) {
344 c.def_static("get", &PyAffineCeilDivExpr::get);
345 }
346};
347
348} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
349} // namespace python
350} // namespace mlir
351
352bool PyAffineExpr::operator==(const PyAffineExpr &other) const {
353 return mlirAffineExprEqual(affineExpr, other.affineExpr);
354}
355
357 return nb::steal<nb::object>(mlirPythonAffineExprToCapsule(*this));
358}
359
361 MlirAffineExpr rawAffineExpr = mlirPythonCapsuleToAffineExpr(capsule.ptr());
362 if (mlirAffineExprIsNull(rawAffineExpr))
363 throw nb::python_error();
364 return PyAffineExpr(
366 rawAffineExpr);
367}
368
369nb::typed<nb::object, PyAffineExpr> PyAffineExpr::maybeDownCast() {
370 MlirAffineExpr expr = get();
372 return nb::cast(PyAffineConstantExpr(getContext(), expr));
373 if (mlirAffineExprIsADim(expr))
374 return nb::cast(PyAffineDimExpr(getContext(), expr));
375 if (mlirAffineExprIsASymbol(expr))
376 return nb::cast(PyAffineSymbolExpr(getContext(), expr));
377 if (mlirAffineExprIsAAdd(expr))
378 return nb::cast(PyAffineAddExpr(getContext(), expr));
379 if (mlirAffineExprIsAMul(expr))
380 return nb::cast(PyAffineMulExpr(getContext(), expr));
381 if (mlirAffineExprIsAMod(expr))
382 return nb::cast(PyAffineModExpr(getContext(), expr));
384 return nb::cast(PyAffineFloorDivExpr(getContext(), expr));
385 if (mlirAffineExprIsACeilDiv(expr))
386 return nb::cast(PyAffineCeilDivExpr(getContext(), expr));
387 return nb::cast(*this);
388}
389
390//------------------------------------------------------------------------------
391// PyAffineMap and utilities.
392//------------------------------------------------------------------------------
393namespace mlir {
394namespace python {
396
397/// A list of expressions contained in an affine map. Internally these are
398/// stored as a consecutive array leading to inexpensive random access. Both
399/// the map and the expression are owned by the context so we need not bother
400/// with lifetime extension.
402 : public Sliceable<PyAffineMapExprList, PyAffineExpr> {
403public:
404 static constexpr const char *pyClassName = "AffineExprList";
405
407 intptr_t length = -1, intptr_t step = 1)
410 step),
411 affineMap(map) {}
412
413private:
414 /// Give the parent CRTP class access to hook implementations below.
416
417 intptr_t getRawNumElements() { return mlirAffineMapGetNumResults(affineMap); }
418
419 PyAffineExpr getRawElement(intptr_t pos) {
420 return PyAffineExpr(affineMap.getContext(),
421 mlirAffineMapGetResult(affineMap, pos));
422 }
423
425 intptr_t step) {
426 return PyAffineMapExprList(affineMap, startIndex, length, step);
427 }
428
429 PyAffineMap affineMap;
430};
431} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
432} // namespace python
433} // namespace mlir
434
435bool PyAffineMap::operator==(const PyAffineMap &other) const {
436 return mlirAffineMapEqual(affineMap, other.affineMap);
437}
438
440 return nb::steal<nb::object>(mlirPythonAffineMapToCapsule(*this));
441}
442
443PyAffineMap PyAffineMap::createFromCapsule(const nb::object &capsule) {
444 MlirAffineMap rawAffineMap = mlirPythonCapsuleToAffineMap(capsule.ptr());
445 if (mlirAffineMapIsNull(rawAffineMap))
446 throw nb::python_error();
447 return PyAffineMap(
449 rawAffineMap);
450}
451
452//------------------------------------------------------------------------------
453// PyIntegerSet and utilities.
454//------------------------------------------------------------------------------
455namespace mlir {
456namespace python {
458
460public:
462 : set(std::move(set)), pos(pos) {}
463
465 return PyAffineExpr(set.getContext(),
467 }
468
469 bool isEq() { return mlirIntegerSetIsConstraintEq(set, pos); }
470
471 static void bind(nb::module_ &m) {
472 nb::class_<PyIntegerSetConstraint>(m, "IntegerSetConstraint")
473 .def_prop_ro("expr", &PyIntegerSetConstraint::getExpr)
474 .def_prop_ro("is_eq", &PyIntegerSetConstraint::isEq);
475 }
476
477private:
478 PyIntegerSet set;
479 intptr_t pos;
480};
481
483 : public Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint> {
484public:
485 static constexpr const char *pyClassName = "IntegerSetConstraintList";
486
493
494private:
495 /// Give the parent CRTP class access to hook implementations below.
497
498 intptr_t getRawNumElements() { return mlirIntegerSetGetNumConstraints(set); }
499
500 PyIntegerSetConstraint getRawElement(intptr_t pos) {
501 return PyIntegerSetConstraint(set, pos);
502 }
503
504 PyIntegerSetConstraintList slice(intptr_t startIndex, intptr_t length,
505 intptr_t step) {
506 return PyIntegerSetConstraintList(set, startIndex, length, step);
507 }
508
509 PyIntegerSet set;
510};
511} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
512} // namespace python
513} // namespace mlir
514
515bool PyIntegerSet::operator==(const PyIntegerSet &other) const {
516 return mlirIntegerSetEqual(integerSet, other.integerSet);
517}
518
520 return nb::steal<nb::object>(mlirPythonIntegerSetToCapsule(*this));
521}
522
524 MlirIntegerSet rawIntegerSet = mlirPythonCapsuleToIntegerSet(capsule.ptr());
525 if (mlirIntegerSetIsNull(rawIntegerSet))
526 throw nb::python_error();
527 return PyIntegerSet(
529 rawIntegerSet);
530}
531
532namespace mlir {
533namespace python {
535void populateIRAffine(nb::module_ &m) {
536 //----------------------------------------------------------------------------
537 // Mapping of PyAffineExpr and derived classes.
538 //----------------------------------------------------------------------------
539 nb::class_<PyAffineExpr>(m, "AffineExpr")
542 .def("__add__", &PyAffineAddExpr::get)
543 .def("__add__", &PyAffineAddExpr::getRHSConstant)
544 .def("__radd__", &PyAffineAddExpr::getRHSConstant)
545 .def("__mul__", &PyAffineMulExpr::get)
546 .def("__mul__", &PyAffineMulExpr::getRHSConstant)
547 .def("__rmul__", &PyAffineMulExpr::getRHSConstant)
548 .def("__mod__", &PyAffineModExpr::get)
549 .def("__mod__", &PyAffineModExpr::getRHSConstant)
550 .def("__rmod__",
551 [](PyAffineExpr &self, intptr_t other) {
553 PyAffineConstantExpr::get(other, *self.getContext().get()),
554 self);
555 })
556 .def("__sub__",
557 [](PyAffineExpr &self, PyAffineExpr &other) {
558 auto negOne =
560 return PyAffineAddExpr::get(self,
561 PyAffineMulExpr::get(negOne, other));
562 })
563 .def("__sub__",
564 [](PyAffineExpr &self, intptr_t other) {
566 self,
567 PyAffineConstantExpr::get(-other, *self.getContext().get()));
568 })
569 .def("__rsub__",
570 [](PyAffineExpr &self, intptr_t other) {
572 other, PyAffineMulExpr::getLHSConstant(-1, self));
573 })
574 .def("__eq__", [](PyAffineExpr &self,
575 PyAffineExpr &other) { return self == other; })
576 .def("__eq__",
577 [](PyAffineExpr &self, nb::object &other) { return false; })
578 .def("__str__",
579 [](PyAffineExpr &self) {
580 PyPrintAccumulator printAccum;
581 mlirAffineExprPrint(self, printAccum.getCallback(),
582 printAccum.getUserData());
583 return printAccum.join();
584 })
585 .def("__repr__",
586 [](PyAffineExpr &self) {
587 PyPrintAccumulator printAccum;
588 printAccum.parts.append("AffineExpr(");
589 mlirAffineExprPrint(self, printAccum.getCallback(),
590 printAccum.getUserData());
591 printAccum.parts.append(")");
592 return printAccum.join();
593 })
594 .def("__hash__",
595 [](PyAffineExpr &self) {
596 return std::hash<const void *>{}(self.get().ptr);
597 })
598 .def_prop_ro(
599 "context",
600 [](PyAffineExpr &self) -> nb::typed<nb::object, PyMlirContext> {
601 return self.getContext().getObject();
602 })
603 .def("compose",
604 [](PyAffineExpr &self, PyAffineMap &other) {
605 return PyAffineExpr(self.getContext(),
606 mlirAffineExprCompose(self, other));
607 })
609 .def(
610 "shift_dims",
611 [](PyAffineExpr &self, uint32_t numDims, uint32_t shift,
612 uint32_t offset) {
613 return PyAffineExpr(
614 self.getContext(),
615 mlirAffineExprShiftDims(self, numDims, shift, offset));
616 },
617 nb::arg("num_dims"), nb::arg("shift"), nb::arg("offset") = 0)
618 .def(
619 "shift_symbols",
620 [](PyAffineExpr &self, uint32_t numSymbols, uint32_t shift,
621 uint32_t offset) {
622 return PyAffineExpr(
623 self.getContext(),
624 mlirAffineExprShiftSymbols(self, numSymbols, shift, offset));
625 },
626 nb::arg("num_symbols"), nb::arg("shift"), nb::arg("offset") = 0)
627 .def_static(
628 "simplify_affine_expr",
629 [](PyAffineExpr &self, uint32_t numDims, uint32_t numSymbols) {
630 return PyAffineExpr(
631 self.getContext(),
632 mlirSimplifyAffineExpr(self, numDims, numSymbols));
633 },
634 nb::arg("expr"), nb::arg("num_dims"), nb::arg("num_symbols"),
635 "Simplify an affine expression by flattening and some amount of "
636 "simple analysis.")
637 .def_static(
638 "get_add", &PyAffineAddExpr::get,
639 "Gets an affine expression containing a sum of two expressions.")
640 .def_static("get_add", &PyAffineAddExpr::getLHSConstant,
641 "Gets an affine expression containing a sum of a constant "
642 "and another expression.")
643 .def_static("get_add", &PyAffineAddExpr::getRHSConstant,
644 "Gets an affine expression containing a sum of an expression "
645 "and a constant.")
646 .def_static(
647 "get_mul", &PyAffineMulExpr::get,
648 "Gets an affine expression containing a product of two expressions.")
649 .def_static("get_mul", &PyAffineMulExpr::getLHSConstant,
650 "Gets an affine expression containing a product of a "
651 "constant and another expression.")
652 .def_static("get_mul", &PyAffineMulExpr::getRHSConstant,
653 "Gets an affine expression containing a product of an "
654 "expression and a constant.")
655 .def_static("get_mod", &PyAffineModExpr::get,
656 "Gets an affine expression containing the modulo of dividing "
657 "one expression by another.")
658 .def_static("get_mod", &PyAffineModExpr::getLHSConstant,
659 "Gets a semi-affine expression containing the modulo of "
660 "dividing a constant by an expression.")
661 .def_static("get_mod", &PyAffineModExpr::getRHSConstant,
662 "Gets an affine expression containing the module of dividing"
663 "an expression by a constant.")
664 .def_static("get_floor_div", &PyAffineFloorDivExpr::get,
665 "Gets an affine expression containing the rounded-down "
666 "result of dividing one expression by another.")
667 .def_static("get_floor_div", &PyAffineFloorDivExpr::getLHSConstant,
668 "Gets a semi-affine expression containing the rounded-down "
669 "result of dividing a constant by an expression.")
670 .def_static("get_floor_div", &PyAffineFloorDivExpr::getRHSConstant,
671 "Gets an affine expression containing the rounded-down "
672 "result of dividing an expression by a constant.")
673 .def_static("get_ceil_div", &PyAffineCeilDivExpr::get,
674 "Gets an affine expression containing the rounded-up result "
675 "of dividing one expression by another.")
676 .def_static("get_ceil_div", &PyAffineCeilDivExpr::getLHSConstant,
677 "Gets a semi-affine expression containing the rounded-up "
678 "result of dividing a constant by an expression.")
679 .def_static("get_ceil_div", &PyAffineCeilDivExpr::getRHSConstant,
680 "Gets an affine expression containing the rounded-up result "
681 "of dividing an expression by a constant.")
682 .def_static("get_constant", &PyAffineConstantExpr::get, nb::arg("value"),
683 nb::arg("context") = nb::none(),
684 "Gets a constant affine expression with the given value.")
685 .def_static(
686 "get_dim", &PyAffineDimExpr::get, nb::arg("position"),
687 nb::arg("context") = nb::none(),
688 "Gets an affine expression of a dimension at the given position.")
689 .def_static(
690 "get_symbol", &PyAffineSymbolExpr::get, nb::arg("position"),
691 nb::arg("context") = nb::none(),
692 "Gets an affine expression of a symbol at the given position.")
693 .def(
694 "dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); },
705
706 //----------------------------------------------------------------------------
707 // Mapping of PyAffineMap.
708 //----------------------------------------------------------------------------
709 nb::class_<PyAffineMap>(m, "AffineMap")
712 .def("__eq__",
713 [](PyAffineMap &self, PyAffineMap &other) { return self == other; })
714 .def("__eq__", [](PyAffineMap &self, nb::object &other) { return false; })
715 .def("__str__",
716 [](PyAffineMap &self) {
717 PyPrintAccumulator printAccum;
718 mlirAffineMapPrint(self, printAccum.getCallback(),
719 printAccum.getUserData());
720 return printAccum.join();
721 })
722 .def("__repr__",
723 [](PyAffineMap &self) {
724 PyPrintAccumulator printAccum;
725 printAccum.parts.append("AffineMap(");
726 mlirAffineMapPrint(self, printAccum.getCallback(),
727 printAccum.getUserData());
728 printAccum.parts.append(")");
729 return printAccum.join();
730 })
731 .def("__hash__",
732 [](PyAffineMap &self) {
733 return std::hash<const void *>{}(self.get().ptr);
734 })
735 .def_static(
736 "compress_unused_symbols",
737 [](nb::typed<nb::sequence, PyAffineMap> affineMaps,
738 DefaultingPyMlirContext context) {
739 std::vector<MlirAffineMap> maps;
741 affineMaps, maps, "attempting to create an AffineMap");
742 std::vector<MlirAffineMap> compressed(nb::len(affineMaps));
743 auto populate = [](void *result, intptr_t idx, MlirAffineMap m) {
744 static_cast<MlirAffineMap *>(result)[idx] = (m);
745 };
746 mlirAffineMapCompressUnusedSymbols(maps.data(), maps.size(),
747 compressed.data(), populate);
748 std::vector<PyAffineMap> res;
749 res.reserve(compressed.size());
750 for (auto m : compressed)
751 res.emplace_back(context->getRef(), m);
752 return res;
753 })
754 .def_prop_ro(
755 "context",
756 [](PyAffineMap &self) -> nb::typed<nb::object, PyMlirContext> {
757 return self.getContext().getObject();
758 },
759 "Context that owns the Affine Map")
760 .def(
761 "dump", [](PyAffineMap &self) { mlirAffineMapDump(self); },
763 .def_static(
764 "get",
765 [](intptr_t dimCount, intptr_t symbolCount,
766 nb::typed<nb::sequence, PyAffineExpr> exprs,
767 DefaultingPyMlirContext context) {
768 std::vector<MlirAffineExpr> affineExprs;
770 exprs, affineExprs, "attempting to create an AffineMap");
771 MlirAffineMap map =
772 mlirAffineMapGet(context->get(), dimCount, symbolCount,
773 affineExprs.size(), affineExprs.data());
774 return PyAffineMap(context->getRef(), map);
775 },
776 nb::arg("dim_count"), nb::arg("symbol_count"), nb::arg("exprs"),
777 nb::arg("context") = nb::none(),
778 "Gets a map with the given expressions as results.")
779 .def_static(
780 "get_constant",
781 [](intptr_t value, DefaultingPyMlirContext context) {
782 MlirAffineMap affineMap =
783 mlirAffineMapConstantGet(context->get(), value);
784 return PyAffineMap(context->getRef(), affineMap);
785 },
786 nb::arg("value"), nb::arg("context") = nb::none(),
787 "Gets an affine map with a single constant result")
788 .def_static(
789 "get_empty",
790 [](DefaultingPyMlirContext context) {
791 MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get());
792 return PyAffineMap(context->getRef(), affineMap);
793 },
794 nb::arg("context") = nb::none(), "Gets an empty affine map.")
795 .def_static(
796 "get_identity",
797 [](intptr_t nDims, DefaultingPyMlirContext context) {
798 MlirAffineMap affineMap =
799 mlirAffineMapMultiDimIdentityGet(context->get(), nDims);
800 return PyAffineMap(context->getRef(), affineMap);
801 },
802 nb::arg("n_dims"), nb::arg("context") = nb::none(),
803 "Gets an identity map with the given number of dimensions.")
804 .def_static(
805 "get_minor_identity",
806 [](intptr_t nDims, intptr_t nResults,
807 DefaultingPyMlirContext context) {
808 MlirAffineMap affineMap =
809 mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults);
810 return PyAffineMap(context->getRef(), affineMap);
811 },
812 nb::arg("n_dims"), nb::arg("n_results"),
813 nb::arg("context") = nb::none(),
814 "Gets a minor identity map with the given number of dimensions and "
815 "results.")
816 .def_static(
817 "get_permutation",
818 [](std::vector<unsigned> permutation,
819 DefaultingPyMlirContext context) {
820 if (!isPermutation(permutation))
821 throw std::runtime_error("Invalid permutation when attempting to "
822 "create an AffineMap");
823 MlirAffineMap affineMap = mlirAffineMapPermutationGet(
824 context->get(), permutation.size(), permutation.data());
825 return PyAffineMap(context->getRef(), affineMap);
826 },
827 nb::arg("permutation"), nb::arg("context") = nb::none(),
828 "Gets an affine map that permutes its inputs.")
829 .def(
830 "get_submap",
831 [](PyAffineMap &self, std::vector<intptr_t> &resultPos) {
832 intptr_t numResults = mlirAffineMapGetNumResults(self);
833 for (intptr_t pos : resultPos) {
834 if (pos < 0 || pos >= numResults)
835 throw nb::value_error("result position out of bounds");
836 }
837 MlirAffineMap affineMap = mlirAffineMapGetSubMap(
838 self, resultPos.size(), resultPos.data());
839 return PyAffineMap(self.getContext(), affineMap);
840 },
841 nb::arg("result_positions"))
842 .def(
843 "get_major_submap",
844 [](PyAffineMap &self, intptr_t nResults) {
845 if (nResults >= mlirAffineMapGetNumResults(self))
846 throw nb::value_error("number of results out of bounds");
847 MlirAffineMap affineMap =
848 mlirAffineMapGetMajorSubMap(self, nResults);
849 return PyAffineMap(self.getContext(), affineMap);
850 },
851 nb::arg("n_results"))
852 .def(
853 "get_minor_submap",
854 [](PyAffineMap &self, intptr_t nResults) {
855 if (nResults >= mlirAffineMapGetNumResults(self))
856 throw nb::value_error("number of results out of bounds");
857 MlirAffineMap affineMap =
858 mlirAffineMapGetMinorSubMap(self, nResults);
859 return PyAffineMap(self.getContext(), affineMap);
860 },
861 nb::arg("n_results"))
862 .def(
863 "replace",
864 [](PyAffineMap &self, PyAffineExpr &expression,
865 PyAffineExpr &replacement, intptr_t numResultDims,
866 intptr_t numResultSyms) {
867 MlirAffineMap affineMap = mlirAffineMapReplace(
868 self, expression, replacement, numResultDims, numResultSyms);
869 return PyAffineMap(self.getContext(), affineMap);
870 },
871 nb::arg("expr"), nb::arg("replacement"), nb::arg("n_result_dims"),
872 nb::arg("n_result_syms"))
873 .def_prop_ro(
874 "is_permutation",
875 [](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); })
876 .def_prop_ro("is_projected_permutation",
877 [](PyAffineMap &self) {
879 })
880 .def_prop_ro(
881 "n_dims",
882 [](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); })
883 .def_prop_ro(
884 "n_inputs",
885 [](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); })
886 .def_prop_ro(
887 "n_symbols",
888 [](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); })
889 .def_prop_ro("results",
890 [](PyAffineMap &self) { return PyAffineMapExprList(self); });
892
893 //----------------------------------------------------------------------------
894 // Mapping of PyIntegerSet.
895 //----------------------------------------------------------------------------
896 nb::class_<PyIntegerSet>(m, "IntegerSet")
899 .def("__eq__", [](PyIntegerSet &self,
900 PyIntegerSet &other) { return self == other; })
901 .def("__eq__",
902 [](PyIntegerSet &self, const nb::object &other) { return false; })
903 .def("__str__",
904 [](PyIntegerSet &self) {
905 PyPrintAccumulator printAccum;
906 mlirIntegerSetPrint(self, printAccum.getCallback(),
907 printAccum.getUserData());
908 return printAccum.join();
909 })
910 .def("__repr__",
911 [](PyIntegerSet &self) {
912 PyPrintAccumulator printAccum;
913 printAccum.parts.append("IntegerSet(");
914 mlirIntegerSetPrint(self, printAccum.getCallback(),
915 printAccum.getUserData());
916 printAccum.parts.append(")");
917 return printAccum.join();
918 })
919 .def("__hash__",
920 [](PyIntegerSet &self) {
921 return std::hash<const void *>{}(self.get().ptr);
922 })
923 .def_prop_ro(
924 "context",
925 [](PyIntegerSet &self) -> nb::typed<nb::object, PyMlirContext> {
926 return self.getContext().getObject();
927 })
928 .def(
929 "dump", [](PyIntegerSet &self) { mlirIntegerSetDump(self); },
931 .def_static(
932 "get",
933 [](intptr_t numDims, intptr_t numSymbols,
934 nb::typed<nb::sequence, PyAffineExpr> exprs,
935 std::vector<bool> eqFlags, DefaultingPyMlirContext context) {
936 if (nb::len(exprs) != eqFlags.size())
937 throw nb::value_error(
938 "Expected the number of constraints to match "
939 "that of equality flags");
940 if (nb::len(exprs) == 0)
941 throw nb::value_error("Expected non-empty list of constraints");
942
943 // std::vector<bool> does not expose a bool* data pointer.
944 std::vector<char> flags(eqFlags.begin(), eqFlags.end());
945 std::vector<MlirAffineExpr> affineExprs;
946 pyListToVector<PyAffineExpr>(exprs, affineExprs,
947 "attempting to create an IntegerSet");
948 MlirIntegerSet set = mlirIntegerSetGet(
949 context->get(), numDims, numSymbols, nb::len(exprs),
950 affineExprs.data(), reinterpret_cast<bool *>(flags.data()));
951 return PyIntegerSet(context->getRef(), set);
952 },
953 nb::arg("num_dims"), nb::arg("num_symbols"), nb::arg("exprs"),
954 nb::arg("eq_flags"), nb::arg("context") = nb::none())
955 .def_static(
956 "get_empty",
957 [](intptr_t numDims, intptr_t numSymbols,
958 DefaultingPyMlirContext context) {
959 MlirIntegerSet set =
960 mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols);
961 return PyIntegerSet(context->getRef(), set);
962 },
963 nb::arg("num_dims"), nb::arg("num_symbols"),
964 nb::arg("context") = nb::none())
965 .def(
966 "get_replaced",
967 [](PyIntegerSet &self, nb::typed<nb::sequence, PyAffineExpr> dimExprs,
968 nb::typed<nb::sequence, PyAffineExpr> symbolExprs,
969 intptr_t numResultDims, intptr_t numResultSymbols) {
970 if (static_cast<intptr_t>(nb::len(dimExprs)) !=
972 throw nb::value_error(
973 "Expected the number of dimension replacement expressions "
974 "to match that of dimensions");
975 if (static_cast<intptr_t>(nb::len(symbolExprs)) !=
977 throw nb::value_error(
978 "Expected the number of symbol replacement expressions "
979 "to match that of symbols");
980
981 std::vector<MlirAffineExpr> dimAffineExprs;
982 std::vector<MlirAffineExpr> symbolAffineExprs;
984 dimExprs, dimAffineExprs,
985 "attempting to create an IntegerSet by replacing dimensions");
987 symbolExprs, symbolAffineExprs,
988 "attempting to create an IntegerSet by replacing symbols");
989 MlirIntegerSet set = mlirIntegerSetReplaceGet(
990 self, dimAffineExprs.data(), symbolAffineExprs.data(),
991 numResultDims, numResultSymbols);
992 return PyIntegerSet(self.getContext(), set);
993 },
994 nb::arg("dim_exprs"), nb::arg("symbol_exprs"),
995 nb::arg("num_result_dims"), nb::arg("num_result_symbols"))
996 .def_prop_ro("is_canonical_empty",
997 [](PyIntegerSet &self) {
999 })
1000 .def_prop_ro(
1001 "n_dims",
1002 [](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); })
1003 .def_prop_ro(
1004 "n_symbols",
1005 [](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); })
1006 .def_prop_ro(
1007 "n_inputs",
1008 [](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); })
1009 .def_prop_ro("n_equalities",
1010 [](PyIntegerSet &self) {
1011 return mlirIntegerSetGetNumEqualities(self);
1012 })
1013 .def_prop_ro("n_inequalities",
1014 [](PyIntegerSet &self) {
1016 })
1017 .def_prop_ro("constraints", [](PyIntegerSet &self) {
1018 return PyIntegerSetConstraintList(self);
1019 });
1022}
1023} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
1024} // namespace python
1025} // 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:60
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:221
static PyAffineAddExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:215
static PyAffineAddExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:210
static PyAffineCeilDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:326
static PyAffineCeilDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:331
static PyAffineCeilDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:337
static PyAffineConstantExpr get(intptr_t value, DefaultingPyMlirContext context)
Definition IRAffine.cpp:125
static PyAffineDimExpr get(intptr_t pos, DefaultingPyMlirContext context)
Definition IRAffine.cpp:147
Wrapper around MlirAffineExpr. Affine expressions are owned by the context.
Definition IRCore.h:1336
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineExpr.
Definition IRAffine.cpp:356
static PyAffineExpr createFromCapsule(const nanobind::object &capsule)
Creates a PyAffineExpr from the MlirAffineExpr wrapped by a capsule.
Definition IRAffine.cpp:360
PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition IRCore.h:1338
bool operator==(const PyAffineExpr &other) const
Definition IRAffine.cpp:352
nanobind::typed< nanobind::object, PyAffineExpr > maybeDownCast()
Definition IRAffine.cpp:369
static PyAffineFloorDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:302
static PyAffineFloorDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:297
static PyAffineFloorDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:308
A list of expressions contained in an affine map.
Definition IRAffine.cpp:402
PyAffineMapExprList(const PyAffineMap &map, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Definition IRAffine.cpp:406
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
Definition IRCore.h:1367
bool operator==(const PyAffineMap &other) const
Definition IRAffine.cpp:435
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineMap.
Definition IRAffine.cpp:439
static PyAffineMap createFromCapsule(const nanobind::object &capsule)
Creates a PyAffineMap from the MlirAffineMap wrapped by a capsule.
Definition IRAffine.cpp:443
static PyAffineModExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:279
static PyAffineModExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:273
static PyAffineModExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:268
static PyAffineMulExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:244
static PyAffineMulExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:239
static PyAffineMulExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:250
static PyAffineSymbolExpr get(intptr_t pos, DefaultingPyMlirContext context)
Definition IRAffine.cpp:167
PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition IRAffine.cpp:92
static void bindDerived(ClassTy &m)
Implemented by derived classes to add methods to the Python subclass.
Definition IRAffine.cpp:116
static MlirAffineExpr castFrom(PyAffineExpr &orig)
Definition IRAffine.cpp:97
PyIntegerSetConstraintList(const PyIntegerSet &set, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Definition IRAffine.cpp:487
PyIntegerSet(PyMlirContextRef contextRef, MlirIntegerSet integerSet)
Definition IRCore.h:1388
static PyIntegerSet createFromCapsule(const nanobind::object &capsule)
Creates a PyIntegerSet from the MlirAffineMap wrapped by a capsule.
Definition IRAffine.cpp:523
bool operator==(const PyIntegerSet &other) const
Definition IRAffine.cpp:515
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirIntegerSet.
Definition IRAffine.cpp:519
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
Definition IRCore.cpp:461
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()