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#include "mlir/Support/LLVM.h"
28
29namespace nb = nanobind;
30using namespace mlir;
32
33static const char kDumpDocstring[] =
34 R"(Dumps a debug representation of the object to stderr.)";
35
36/// Attempts to populate `result` with the content of `list` casted to the
37/// appropriate type (Python and C types are provided as template arguments).
38/// Throws errors in case of failure, using "action" to describe what the caller
39/// was attempting to do.
40template <typename PyType, typename CType>
41static void pyListToVector(const nb::list &list, std::vector<CType> &result,
42 std::string_view action) {
43 result.reserve(nb::len(list));
44 for (nb::handle item : list) {
45 try {
46 result.push_back(nb::cast<PyType>(item));
47 } catch (nb::cast_error &err) {
48 std::string msg = nanobind::detail::join("Invalid expression when ",
49 action, " (", err.what(), ")");
50 throw std::runtime_error(msg.c_str());
51 } catch (std::runtime_error &err) {
52 std::string msg = nanobind::detail::join(
53 "Invalid expression (None?) when ", 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 [](const nb::list &affineMaps, DefaultingPyMlirContext context) {
738 std::vector<MlirAffineMap> maps;
740 affineMaps, maps, "attempting to create an AffineMap");
741 std::vector<MlirAffineMap> compressed(affineMaps.size());
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, const nb::list &exprs,
765 DefaultingPyMlirContext context) {
766 std::vector<MlirAffineExpr> affineExprs;
768 exprs, affineExprs, "attempting to create an AffineMap");
769 MlirAffineMap map =
770 mlirAffineMapGet(context->get(), dimCount, symbolCount,
771 affineExprs.size(), affineExprs.data());
772 return PyAffineMap(context->getRef(), map);
773 },
774 nb::arg("dim_count"), nb::arg("symbol_count"), nb::arg("exprs"),
775 nb::arg("context") = nb::none(),
776 "Gets a map with the given expressions as results.")
777 .def_static(
778 "get_constant",
779 [](intptr_t value, DefaultingPyMlirContext context) {
780 MlirAffineMap affineMap =
781 mlirAffineMapConstantGet(context->get(), value);
782 return PyAffineMap(context->getRef(), affineMap);
783 },
784 nb::arg("value"), nb::arg("context") = nb::none(),
785 "Gets an affine map with a single constant result")
786 .def_static(
787 "get_empty",
788 [](DefaultingPyMlirContext context) {
789 MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get());
790 return PyAffineMap(context->getRef(), affineMap);
791 },
792 nb::arg("context") = nb::none(), "Gets an empty affine map.")
793 .def_static(
794 "get_identity",
795 [](intptr_t nDims, DefaultingPyMlirContext context) {
796 MlirAffineMap affineMap =
797 mlirAffineMapMultiDimIdentityGet(context->get(), nDims);
798 return PyAffineMap(context->getRef(), affineMap);
799 },
800 nb::arg("n_dims"), nb::arg("context") = nb::none(),
801 "Gets an identity map with the given number of dimensions.")
802 .def_static(
803 "get_minor_identity",
804 [](intptr_t nDims, intptr_t nResults,
805 DefaultingPyMlirContext context) {
806 MlirAffineMap affineMap =
807 mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults);
808 return PyAffineMap(context->getRef(), affineMap);
809 },
810 nb::arg("n_dims"), nb::arg("n_results"),
811 nb::arg("context") = nb::none(),
812 "Gets a minor identity map with the given number of dimensions and "
813 "results.")
814 .def_static(
815 "get_permutation",
816 [](std::vector<unsigned> permutation,
817 DefaultingPyMlirContext context) {
818 if (!isPermutation(permutation))
819 throw std::runtime_error("Invalid permutation when attempting to "
820 "create an AffineMap");
821 MlirAffineMap affineMap = mlirAffineMapPermutationGet(
822 context->get(), permutation.size(), permutation.data());
823 return PyAffineMap(context->getRef(), affineMap);
824 },
825 nb::arg("permutation"), nb::arg("context") = nb::none(),
826 "Gets an affine map that permutes its inputs.")
827 .def(
828 "get_submap",
829 [](PyAffineMap &self, std::vector<intptr_t> &resultPos) {
830 intptr_t numResults = mlirAffineMapGetNumResults(self);
831 for (intptr_t pos : resultPos) {
832 if (pos < 0 || pos >= numResults)
833 throw nb::value_error("result position out of bounds");
834 }
835 MlirAffineMap affineMap = mlirAffineMapGetSubMap(
836 self, resultPos.size(), resultPos.data());
837 return PyAffineMap(self.getContext(), affineMap);
838 },
839 nb::arg("result_positions"))
840 .def(
841 "get_major_submap",
842 [](PyAffineMap &self, intptr_t nResults) {
843 if (nResults >= mlirAffineMapGetNumResults(self))
844 throw nb::value_error("number of results out of bounds");
845 MlirAffineMap affineMap =
846 mlirAffineMapGetMajorSubMap(self, nResults);
847 return PyAffineMap(self.getContext(), affineMap);
848 },
849 nb::arg("n_results"))
850 .def(
851 "get_minor_submap",
852 [](PyAffineMap &self, intptr_t nResults) {
853 if (nResults >= mlirAffineMapGetNumResults(self))
854 throw nb::value_error("number of results out of bounds");
855 MlirAffineMap affineMap =
856 mlirAffineMapGetMinorSubMap(self, nResults);
857 return PyAffineMap(self.getContext(), affineMap);
858 },
859 nb::arg("n_results"))
860 .def(
861 "replace",
862 [](PyAffineMap &self, PyAffineExpr &expression,
863 PyAffineExpr &replacement, intptr_t numResultDims,
864 intptr_t numResultSyms) {
865 MlirAffineMap affineMap = mlirAffineMapReplace(
866 self, expression, replacement, numResultDims, numResultSyms);
867 return PyAffineMap(self.getContext(), affineMap);
868 },
869 nb::arg("expr"), nb::arg("replacement"), nb::arg("n_result_dims"),
870 nb::arg("n_result_syms"))
871 .def_prop_ro(
872 "is_permutation",
873 [](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); })
874 .def_prop_ro("is_projected_permutation",
875 [](PyAffineMap &self) {
877 })
878 .def_prop_ro(
879 "n_dims",
880 [](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); })
881 .def_prop_ro(
882 "n_inputs",
883 [](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); })
884 .def_prop_ro(
885 "n_symbols",
886 [](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); })
887 .def_prop_ro("results",
888 [](PyAffineMap &self) { return PyAffineMapExprList(self); });
890
891 //----------------------------------------------------------------------------
892 // Mapping of PyIntegerSet.
893 //----------------------------------------------------------------------------
894 nb::class_<PyIntegerSet>(m, "IntegerSet")
897 .def("__eq__", [](PyIntegerSet &self,
898 PyIntegerSet &other) { return self == other; })
899 .def("__eq__",
900 [](PyIntegerSet &self, const nb::object &other) { return false; })
901 .def("__str__",
902 [](PyIntegerSet &self) {
903 PyPrintAccumulator printAccum;
904 mlirIntegerSetPrint(self, printAccum.getCallback(),
905 printAccum.getUserData());
906 return printAccum.join();
907 })
908 .def("__repr__",
909 [](PyIntegerSet &self) {
910 PyPrintAccumulator printAccum;
911 printAccum.parts.append("IntegerSet(");
912 mlirIntegerSetPrint(self, printAccum.getCallback(),
913 printAccum.getUserData());
914 printAccum.parts.append(")");
915 return printAccum.join();
916 })
917 .def("__hash__",
918 [](PyIntegerSet &self) {
919 return std::hash<const void *>{}(self.get().ptr);
920 })
921 .def_prop_ro(
922 "context",
923 [](PyIntegerSet &self) -> nb::typed<nb::object, PyMlirContext> {
924 return self.getContext().getObject();
925 })
926 .def(
927 "dump", [](PyIntegerSet &self) { mlirIntegerSetDump(self); },
929 .def_static(
930 "get",
931 [](intptr_t numDims, intptr_t numSymbols, const nb::list &exprs,
932 std::vector<bool> eqFlags, DefaultingPyMlirContext context) {
933 if (exprs.size() != eqFlags.size())
934 throw nb::value_error(
935 "Expected the number of constraints to match "
936 "that of equality flags");
937 if (exprs.size() == 0)
938 throw nb::value_error("Expected non-empty list of constraints");
939
940 // std::vector<bool> does not expose a bool* data pointer.
941 std::vector<char> flags(eqFlags.begin(), eqFlags.end());
942 std::vector<MlirAffineExpr> affineExprs;
943 pyListToVector<PyAffineExpr>(exprs, affineExprs,
944 "attempting to create an IntegerSet");
945 MlirIntegerSet set = mlirIntegerSetGet(
946 context->get(), numDims, numSymbols, exprs.size(),
947 affineExprs.data(), reinterpret_cast<bool *>(flags.data()));
948 return PyIntegerSet(context->getRef(), set);
949 },
950 nb::arg("num_dims"), nb::arg("num_symbols"), nb::arg("exprs"),
951 nb::arg("eq_flags"), nb::arg("context") = nb::none())
952 .def_static(
953 "get_empty",
954 [](intptr_t numDims, intptr_t numSymbols,
955 DefaultingPyMlirContext context) {
956 MlirIntegerSet set =
957 mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols);
958 return PyIntegerSet(context->getRef(), set);
959 },
960 nb::arg("num_dims"), nb::arg("num_symbols"),
961 nb::arg("context") = nb::none())
962 .def(
963 "get_replaced",
964 [](PyIntegerSet &self, const nb::list &dimExprs,
965 const nb::list &symbolExprs, intptr_t numResultDims,
966 intptr_t numResultSymbols) {
967 if (static_cast<intptr_t>(dimExprs.size()) !=
969 throw nb::value_error(
970 "Expected the number of dimension replacement expressions "
971 "to match that of dimensions");
972 if (static_cast<intptr_t>(symbolExprs.size()) !=
974 throw nb::value_error(
975 "Expected the number of symbol replacement expressions "
976 "to match that of symbols");
977
978 std::vector<MlirAffineExpr> dimAffineExprs;
979 std::vector<MlirAffineExpr> symbolAffineExprs;
981 dimExprs, dimAffineExprs,
982 "attempting to create an IntegerSet by replacing dimensions");
984 symbolExprs, symbolAffineExprs,
985 "attempting to create an IntegerSet by replacing symbols");
986 MlirIntegerSet set = mlirIntegerSetReplaceGet(
987 self, dimAffineExprs.data(), symbolAffineExprs.data(),
988 numResultDims, numResultSymbols);
989 return PyIntegerSet(self.getContext(), set);
990 },
991 nb::arg("dim_exprs"), nb::arg("symbol_exprs"),
992 nb::arg("num_result_dims"), nb::arg("num_result_symbols"))
993 .def_prop_ro("is_canonical_empty",
994 [](PyIntegerSet &self) {
996 })
997 .def_prop_ro(
998 "n_dims",
999 [](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); })
1000 .def_prop_ro(
1001 "n_symbols",
1002 [](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); })
1003 .def_prop_ro(
1004 "n_inputs",
1005 [](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); })
1006 .def_prop_ro("n_equalities",
1007 [](PyIntegerSet &self) {
1008 return mlirIntegerSetGetNumEqualities(self);
1009 })
1010 .def_prop_ro("n_inequalities",
1011 [](PyIntegerSet &self) {
1013 })
1014 .def_prop_ro("constraints", [](PyIntegerSet &self) {
1015 return PyIntegerSetConstraintList(self);
1016 });
1019}
1020} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
1021} // namespace python
1022} // 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 bool isPermutation(const std::vector< PermutationTy > &permutation)
Definition IRAffine.cpp:60
static const char kDumpDocstring[]
Definition IRAffine.cpp:33
static void pyListToVector(const nb::list &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:41
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:299
Used in function arguments when None should resolve to the current context manager set instance.
Definition IRCore.h:280
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:1204
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:1206
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:1235
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:1256
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:486
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:199
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()