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