MLIR 22.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 <stdexcept>
12#include <string>
13#include <utility>
14#include <vector>
15
16#include "mlir-c/AffineExpr.h"
17#include "mlir-c/AffineMap.h"
19// clang-format off
21#include "mlir-c/Bindings/Python/Interop.h" // This is expected after nanobind.
22// clang-format on
23#include "mlir-c/IntegerSet.h"
25#include "mlir/Support/LLVM.h"
26#include "llvm/ADT/Hashing.h"
27#include "llvm/ADT/SmallVector.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/ADT/Twine.h"
30
31namespace nb = nanobind;
32using namespace mlir;
34
36using llvm::StringRef;
37using llvm::Twine;
38
39static const char kDumpDocstring[] =
40 R"(Dumps a debug representation of the object to stderr.)";
41
42/// Attempts to populate `result` with the content of `list` casted to the
43/// appropriate type (Python and C types are provided as template arguments).
44/// Throws errors in case of failure, using "action" to describe what the caller
45/// was attempting to do.
46template <typename PyType, typename CType>
47static void pyListToVector(const nb::list &list,
49 StringRef action) {
50 result.reserve(nb::len(list));
51 for (nb::handle item : list) {
52 try {
53 result.push_back(nb::cast<PyType>(item));
54 } catch (nb::cast_error &err) {
55 std::string msg = (llvm::Twine("Invalid expression when ") + action +
56 " (" + err.what() + ")")
57 .str();
58 throw std::runtime_error(msg.c_str());
59 } catch (std::runtime_error &err) {
60 std::string msg = (llvm::Twine("Invalid expression (None?) when ") +
61 action + " (" + err.what() + ")")
62 .str();
63 throw std::runtime_error(msg.c_str());
64 }
65 }
66}
67
68template <typename PermutationTy>
69static bool isPermutation(const std::vector<PermutationTy> &permutation) {
70 llvm::SmallVector<bool, 8> seen(permutation.size(), false);
71 for (auto val : permutation) {
72 if (val < permutation.size()) {
73 if (seen[val])
74 return false;
75 seen[val] = true;
76 continue;
77 }
78 return false;
79 }
80 return true;
81}
82
83namespace mlir {
84namespace python {
86
87/// CRTP base class for Python MLIR affine expressions that subclass AffineExpr
88/// and should be castable from it. Intermediate hierarchy classes can be
89/// modeled by specifying BaseTy.
90template <typename DerivedTy, typename BaseTy = PyAffineExpr>
91class PyConcreteAffineExpr : public BaseTy {
92public:
93 // Derived classes must define statics for:
94 // IsAFunctionTy isaFunction
95 // const char *pyClassName
96 // and redefine bindDerived.
97 using ClassTy = nb::class_<DerivedTy, BaseTy>;
98 using IsAFunctionTy = bool (*)(MlirAffineExpr);
99
101 PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
102 : BaseTy(std::move(contextRef), affineExpr) {}
105
106 static MlirAffineExpr castFrom(PyAffineExpr &orig) {
107 if (!DerivedTy::isaFunction(orig)) {
108 auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(orig)));
109 throw nb::value_error((Twine("Cannot cast affine expression to ") +
110 DerivedTy::pyClassName + " (from " + origRepr +
111 ")")
112 .str()
113 .c_str());
114 }
115 return orig;
116 }
117
118 static void bind(nb::module_ &m) {
119 auto cls = ClassTy(m, DerivedTy::pyClassName);
120 cls.def(nb::init<PyAffineExpr &>(), nb::arg("expr"));
121 DerivedTy::bindDerived(cls);
122 }
123
124 /// Implemented by derived classes to add methods to the Python subclass.
125 static void bindDerived(ClassTy &m) {}
126};
127
128class PyAffineConstantExpr : public PyConcreteAffineExpr<PyAffineConstantExpr> {
129public:
131 static constexpr const char *pyClassName = "AffineConstantExpr";
133
135 DefaultingPyMlirContext context) {
136 MlirAffineExpr affineExpr =
137 mlirAffineConstantExprGet(context->get(), static_cast<int64_t>(value));
138 return PyAffineConstantExpr(context->getRef(), affineExpr);
139 }
140
141 static void bindDerived(ClassTy &c) {
142 c.def_static("get", &PyAffineConstantExpr::get, nb::arg("value"),
143 nb::arg("context") = nb::none());
144 c.def_prop_ro("value", [](PyAffineConstantExpr &self) {
146 });
147 }
148};
149
150class PyAffineDimExpr : public PyConcreteAffineExpr<PyAffineDimExpr> {
151public:
153 static constexpr const char *pyClassName = "AffineDimExpr";
155
157 MlirAffineExpr affineExpr = mlirAffineDimExprGet(context->get(), pos);
158 return PyAffineDimExpr(context->getRef(), affineExpr);
159 }
160
161 static void bindDerived(ClassTy &c) {
162 c.def_static("get", &PyAffineDimExpr::get, nb::arg("position"),
163 nb::arg("context") = nb::none());
164 c.def_prop_ro("position", [](PyAffineDimExpr &self) {
165 return mlirAffineDimExprGetPosition(self);
166 });
167 }
168};
169
170class PyAffineSymbolExpr : public PyConcreteAffineExpr<PyAffineSymbolExpr> {
171public:
173 static constexpr const char *pyClassName = "AffineSymbolExpr";
175
177 MlirAffineExpr affineExpr = mlirAffineSymbolExprGet(context->get(), pos);
178 return PyAffineSymbolExpr(context->getRef(), affineExpr);
179 }
180
181 static void bindDerived(ClassTy &c) {
182 c.def_static("get", &PyAffineSymbolExpr::get, nb::arg("position"),
183 nb::arg("context") = nb::none());
184 c.def_prop_ro("position", [](PyAffineSymbolExpr &self) {
186 });
187 }
188};
189
190class PyAffineBinaryExpr : public PyConcreteAffineExpr<PyAffineBinaryExpr> {
191public:
193 static constexpr const char *pyClassName = "AffineBinaryExpr";
195
196 nb::typed<nb::object, PyAffineExpr> lhs() {
197 MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get());
198 return PyAffineExpr(getContext(), lhsExpr).maybeDownCast();
199 }
200
201 nb::typed<nb::object, PyAffineExpr> rhs() {
202 MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get());
203 return PyAffineExpr(getContext(), rhsExpr).maybeDownCast();
204 }
205
206 static void bindDerived(ClassTy &c) {
207 c.def_prop_ro("lhs", &PyAffineBinaryExpr::lhs);
208 c.def_prop_ro("rhs", &PyAffineBinaryExpr::rhs);
209 }
210};
211
213 : public PyConcreteAffineExpr<PyAffineAddExpr, PyAffineBinaryExpr> {
214public:
216 static constexpr const char *pyClassName = "AffineAddExpr";
218
220 MlirAffineExpr expr = mlirAffineAddExprGet(lhs, rhs);
221 return PyAffineAddExpr(lhs.getContext(), expr);
222 }
223
229
235
236 static void bindDerived(ClassTy &c) {
237 c.def_static("get", &PyAffineAddExpr::get);
238 }
239};
240
242 : public PyConcreteAffineExpr<PyAffineMulExpr, PyAffineBinaryExpr> {
243public:
245 static constexpr const char *pyClassName = "AffineMulExpr";
247
249 MlirAffineExpr expr = mlirAffineMulExprGet(lhs, rhs);
250 return PyAffineMulExpr(lhs.getContext(), expr);
251 }
252
258
264
265 static void bindDerived(ClassTy &c) {
266 c.def_static("get", &PyAffineMulExpr::get);
267 }
268};
269
271 : public PyConcreteAffineExpr<PyAffineModExpr, PyAffineBinaryExpr> {
272public:
274 static constexpr const char *pyClassName = "AffineModExpr";
276
278 MlirAffineExpr expr = mlirAffineModExprGet(lhs, rhs);
279 return PyAffineModExpr(lhs.getContext(), expr);
280 }
281
287
293
294 static void bindDerived(ClassTy &c) {
295 c.def_static("get", &PyAffineModExpr::get);
296 }
297};
298
300 : public PyConcreteAffineExpr<PyAffineFloorDivExpr, PyAffineBinaryExpr> {
301public:
303 static constexpr const char *pyClassName = "AffineFloorDivExpr";
305
307 MlirAffineExpr expr = mlirAffineFloorDivExprGet(lhs, rhs);
308 return PyAffineFloorDivExpr(lhs.getContext(), expr);
309 }
310
316
322
323 static void bindDerived(ClassTy &c) {
324 c.def_static("get", &PyAffineFloorDivExpr::get);
325 }
326};
327
329 : public PyConcreteAffineExpr<PyAffineCeilDivExpr, PyAffineBinaryExpr> {
330public:
332 static constexpr const char *pyClassName = "AffineCeilDivExpr";
334
336 MlirAffineExpr expr = mlirAffineCeilDivExprGet(lhs, rhs);
337 return PyAffineCeilDivExpr(lhs.getContext(), expr);
338 }
339
345
351
352 static void bindDerived(ClassTy &c) {
353 c.def_static("get", &PyAffineCeilDivExpr::get);
354 }
355};
356
357} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
358} // namespace python
359} // namespace mlir
360
361bool PyAffineExpr::operator==(const PyAffineExpr &other) const {
362 return mlirAffineExprEqual(affineExpr, other.affineExpr);
363}
364
366 return nb::steal<nb::object>(mlirPythonAffineExprToCapsule(*this));
367}
368
370 MlirAffineExpr rawAffineExpr = mlirPythonCapsuleToAffineExpr(capsule.ptr());
371 if (mlirAffineExprIsNull(rawAffineExpr))
372 throw nb::python_error();
373 return PyAffineExpr(
375 rawAffineExpr);
376}
377
378nb::typed<nb::object, PyAffineExpr> PyAffineExpr::maybeDownCast() {
379 MlirAffineExpr expr = get();
381 return nb::cast(PyAffineConstantExpr(getContext(), expr));
382 if (mlirAffineExprIsADim(expr))
383 return nb::cast(PyAffineDimExpr(getContext(), expr));
384 if (mlirAffineExprIsASymbol(expr))
385 return nb::cast(PyAffineSymbolExpr(getContext(), expr));
386 if (mlirAffineExprIsAAdd(expr))
387 return nb::cast(PyAffineAddExpr(getContext(), expr));
388 if (mlirAffineExprIsAMul(expr))
389 return nb::cast(PyAffineMulExpr(getContext(), expr));
390 if (mlirAffineExprIsAMod(expr))
391 return nb::cast(PyAffineModExpr(getContext(), expr));
393 return nb::cast(PyAffineFloorDivExpr(getContext(), expr));
394 if (mlirAffineExprIsACeilDiv(expr))
395 return nb::cast(PyAffineCeilDivExpr(getContext(), expr));
396 return nb::cast(*this);
397}
398
399//------------------------------------------------------------------------------
400// PyAffineMap and utilities.
401//------------------------------------------------------------------------------
402namespace mlir {
403namespace python {
405
406/// A list of expressions contained in an affine map. Internally these are
407/// stored as a consecutive array leading to inexpensive random access. Both
408/// the map and the expression are owned by the context so we need not bother
409/// with lifetime extension.
411 : public Sliceable<PyAffineMapExprList, PyAffineExpr> {
412public:
413 static constexpr const char *pyClassName = "AffineExprList";
414
416 intptr_t length = -1, intptr_t step = 1)
419 step),
420 affineMap(map) {}
421
422private:
423 /// Give the parent CRTP class access to hook implementations below.
425
426 intptr_t getRawNumElements() { return mlirAffineMapGetNumResults(affineMap); }
427
428 PyAffineExpr getRawElement(intptr_t pos) {
429 return PyAffineExpr(affineMap.getContext(),
430 mlirAffineMapGetResult(affineMap, pos));
431 }
432
434 intptr_t step) {
435 return PyAffineMapExprList(affineMap, startIndex, length, step);
436 }
437
438 PyAffineMap affineMap;
439};
440} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
441} // namespace python
442} // namespace mlir
443
444bool PyAffineMap::operator==(const PyAffineMap &other) const {
445 return mlirAffineMapEqual(affineMap, other.affineMap);
446}
447
449 return nb::steal<nb::object>(mlirPythonAffineMapToCapsule(*this));
450}
451
452PyAffineMap PyAffineMap::createFromCapsule(const nb::object &capsule) {
453 MlirAffineMap rawAffineMap = mlirPythonCapsuleToAffineMap(capsule.ptr());
454 if (mlirAffineMapIsNull(rawAffineMap))
455 throw nb::python_error();
456 return PyAffineMap(
458 rawAffineMap);
459}
460
461//------------------------------------------------------------------------------
462// PyIntegerSet and utilities.
463//------------------------------------------------------------------------------
464namespace mlir {
465namespace python {
467
469public:
471 : set(std::move(set)), pos(pos) {}
472
474 return PyAffineExpr(set.getContext(),
476 }
477
478 bool isEq() { return mlirIntegerSetIsConstraintEq(set, pos); }
479
480 static void bind(nb::module_ &m) {
481 nb::class_<PyIntegerSetConstraint>(m, "IntegerSetConstraint")
482 .def_prop_ro("expr", &PyIntegerSetConstraint::getExpr)
483 .def_prop_ro("is_eq", &PyIntegerSetConstraint::isEq);
484 }
485
486private:
487 PyIntegerSet set;
488 intptr_t pos;
489};
490
492 : public Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint> {
493public:
494 static constexpr const char *pyClassName = "IntegerSetConstraintList";
495
502
503private:
504 /// Give the parent CRTP class access to hook implementations below.
506
507 intptr_t getRawNumElements() { return mlirIntegerSetGetNumConstraints(set); }
508
509 PyIntegerSetConstraint getRawElement(intptr_t pos) {
510 return PyIntegerSetConstraint(set, pos);
511 }
512
513 PyIntegerSetConstraintList slice(intptr_t startIndex, intptr_t length,
514 intptr_t step) {
515 return PyIntegerSetConstraintList(set, startIndex, length, step);
516 }
517
518 PyIntegerSet set;
519};
520} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
521} // namespace python
522} // namespace mlir
523
524bool PyIntegerSet::operator==(const PyIntegerSet &other) const {
525 return mlirIntegerSetEqual(integerSet, other.integerSet);
526}
527
529 return nb::steal<nb::object>(mlirPythonIntegerSetToCapsule(*this));
530}
531
533 MlirIntegerSet rawIntegerSet = mlirPythonCapsuleToIntegerSet(capsule.ptr());
534 if (mlirIntegerSetIsNull(rawIntegerSet))
535 throw nb::python_error();
536 return PyIntegerSet(
538 rawIntegerSet);
539}
540
541namespace mlir {
542namespace python {
544void populateIRAffine(nb::module_ &m) {
545 //----------------------------------------------------------------------------
546 // Mapping of PyAffineExpr and derived classes.
547 //----------------------------------------------------------------------------
548 nb::class_<PyAffineExpr>(m, "AffineExpr")
551 .def("__add__", &PyAffineAddExpr::get)
552 .def("__add__", &PyAffineAddExpr::getRHSConstant)
553 .def("__radd__", &PyAffineAddExpr::getRHSConstant)
554 .def("__mul__", &PyAffineMulExpr::get)
555 .def("__mul__", &PyAffineMulExpr::getRHSConstant)
556 .def("__rmul__", &PyAffineMulExpr::getRHSConstant)
557 .def("__mod__", &PyAffineModExpr::get)
558 .def("__mod__", &PyAffineModExpr::getRHSConstant)
559 .def("__rmod__",
560 [](PyAffineExpr &self, intptr_t other) {
562 PyAffineConstantExpr::get(other, *self.getContext().get()),
563 self);
564 })
565 .def("__sub__",
566 [](PyAffineExpr &self, PyAffineExpr &other) {
567 auto negOne =
569 return PyAffineAddExpr::get(self,
570 PyAffineMulExpr::get(negOne, other));
571 })
572 .def("__sub__",
573 [](PyAffineExpr &self, intptr_t other) {
575 self,
576 PyAffineConstantExpr::get(-other, *self.getContext().get()));
577 })
578 .def("__rsub__",
579 [](PyAffineExpr &self, intptr_t other) {
581 other, PyAffineMulExpr::getLHSConstant(-1, self));
582 })
583 .def("__eq__", [](PyAffineExpr &self,
584 PyAffineExpr &other) { return self == other; })
585 .def("__eq__",
586 [](PyAffineExpr &self, nb::object &other) { return false; })
587 .def("__str__",
588 [](PyAffineExpr &self) {
589 PyPrintAccumulator printAccum;
590 mlirAffineExprPrint(self, printAccum.getCallback(),
591 printAccum.getUserData());
592 return printAccum.join();
593 })
594 .def("__repr__",
595 [](PyAffineExpr &self) {
596 PyPrintAccumulator printAccum;
597 printAccum.parts.append("AffineExpr(");
598 mlirAffineExprPrint(self, printAccum.getCallback(),
599 printAccum.getUserData());
600 printAccum.parts.append(")");
601 return printAccum.join();
602 })
603 .def("__hash__",
604 [](PyAffineExpr &self) {
605 return static_cast<size_t>(llvm::hash_value(self.get().ptr));
606 })
607 .def_prop_ro(
608 "context",
609 [](PyAffineExpr &self) -> nb::typed<nb::object, PyMlirContext> {
610 return self.getContext().getObject();
611 })
612 .def("compose",
613 [](PyAffineExpr &self, PyAffineMap &other) {
614 return PyAffineExpr(self.getContext(),
615 mlirAffineExprCompose(self, other));
616 })
617 .def("maybe_downcast", &PyAffineExpr::maybeDownCast)
618 .def(
619 "shift_dims",
620 [](PyAffineExpr &self, uint32_t numDims, uint32_t shift,
621 uint32_t offset) {
622 return PyAffineExpr(
623 self.getContext(),
624 mlirAffineExprShiftDims(self, numDims, shift, offset));
625 },
626 nb::arg("num_dims"), nb::arg("shift"), nb::arg("offset") = 0)
627 .def(
628 "shift_symbols",
629 [](PyAffineExpr &self, uint32_t numSymbols, uint32_t shift,
630 uint32_t offset) {
631 return PyAffineExpr(
632 self.getContext(),
633 mlirAffineExprShiftSymbols(self, numSymbols, shift, offset));
634 },
635 nb::arg("num_symbols"), nb::arg("shift"), nb::arg("offset") = 0)
636 .def_static(
637 "simplify_affine_expr",
638 [](PyAffineExpr &self, uint32_t numDims, uint32_t numSymbols) {
639 return PyAffineExpr(
640 self.getContext(),
641 mlirSimplifyAffineExpr(self, numDims, numSymbols));
642 },
643 nb::arg("expr"), nb::arg("num_dims"), nb::arg("num_symbols"),
644 "Simplify an affine expression by flattening and some amount of "
645 "simple analysis.")
646 .def_static(
647 "get_add", &PyAffineAddExpr::get,
648 "Gets an affine expression containing a sum of two expressions.")
649 .def_static("get_add", &PyAffineAddExpr::getLHSConstant,
650 "Gets an affine expression containing a sum of a constant "
651 "and another expression.")
652 .def_static("get_add", &PyAffineAddExpr::getRHSConstant,
653 "Gets an affine expression containing a sum of an expression "
654 "and a constant.")
655 .def_static(
656 "get_mul", &PyAffineMulExpr::get,
657 "Gets an affine expression containing a product of two expressions.")
658 .def_static("get_mul", &PyAffineMulExpr::getLHSConstant,
659 "Gets an affine expression containing a product of a "
660 "constant and another expression.")
661 .def_static("get_mul", &PyAffineMulExpr::getRHSConstant,
662 "Gets an affine expression containing a product of an "
663 "expression and a constant.")
664 .def_static("get_mod", &PyAffineModExpr::get,
665 "Gets an affine expression containing the modulo of dividing "
666 "one expression by another.")
667 .def_static("get_mod", &PyAffineModExpr::getLHSConstant,
668 "Gets a semi-affine expression containing the modulo of "
669 "dividing a constant by an expression.")
670 .def_static("get_mod", &PyAffineModExpr::getRHSConstant,
671 "Gets an affine expression containing the module of dividing"
672 "an expression by a constant.")
673 .def_static("get_floor_div", &PyAffineFloorDivExpr::get,
674 "Gets an affine expression containing the rounded-down "
675 "result of dividing one expression by another.")
676 .def_static("get_floor_div", &PyAffineFloorDivExpr::getLHSConstant,
677 "Gets a semi-affine expression containing the rounded-down "
678 "result of dividing a constant by an expression.")
679 .def_static("get_floor_div", &PyAffineFloorDivExpr::getRHSConstant,
680 "Gets an affine expression containing the rounded-down "
681 "result of dividing an expression by a constant.")
682 .def_static("get_ceil_div", &PyAffineCeilDivExpr::get,
683 "Gets an affine expression containing the rounded-up result "
684 "of dividing one expression by another.")
685 .def_static("get_ceil_div", &PyAffineCeilDivExpr::getLHSConstant,
686 "Gets a semi-affine expression containing the rounded-up "
687 "result of dividing a constant by an expression.")
688 .def_static("get_ceil_div", &PyAffineCeilDivExpr::getRHSConstant,
689 "Gets an affine expression containing the rounded-up result "
690 "of dividing an expression by a constant.")
691 .def_static("get_constant", &PyAffineConstantExpr::get, nb::arg("value"),
692 nb::arg("context") = nb::none(),
693 "Gets a constant affine expression with the given value.")
694 .def_static(
695 "get_dim", &PyAffineDimExpr::get, nb::arg("position"),
696 nb::arg("context") = nb::none(),
697 "Gets an affine expression of a dimension at the given position.")
698 .def_static(
699 "get_symbol", &PyAffineSymbolExpr::get, nb::arg("position"),
700 nb::arg("context") = nb::none(),
701 "Gets an affine expression of a symbol at the given position.")
702 .def(
703 "dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); },
714
715 //----------------------------------------------------------------------------
716 // Mapping of PyAffineMap.
717 //----------------------------------------------------------------------------
718 nb::class_<PyAffineMap>(m, "AffineMap")
721 .def("__eq__",
722 [](PyAffineMap &self, PyAffineMap &other) { return self == other; })
723 .def("__eq__", [](PyAffineMap &self, nb::object &other) { return false; })
724 .def("__str__",
725 [](PyAffineMap &self) {
726 PyPrintAccumulator printAccum;
727 mlirAffineMapPrint(self, printAccum.getCallback(),
728 printAccum.getUserData());
729 return printAccum.join();
730 })
731 .def("__repr__",
732 [](PyAffineMap &self) {
733 PyPrintAccumulator printAccum;
734 printAccum.parts.append("AffineMap(");
735 mlirAffineMapPrint(self, printAccum.getCallback(),
736 printAccum.getUserData());
737 printAccum.parts.append(")");
738 return printAccum.join();
739 })
740 .def("__hash__",
741 [](PyAffineMap &self) {
742 return static_cast<size_t>(llvm::hash_value(self.get().ptr));
743 })
744 .def_static(
745 "compress_unused_symbols",
746 [](const nb::list &affineMaps, DefaultingPyMlirContext context) {
749 affineMaps, maps, "attempting to create an AffineMap");
750 std::vector<MlirAffineMap> compressed(affineMaps.size());
751 auto populate = [](void *result, intptr_t idx, MlirAffineMap m) {
752 static_cast<MlirAffineMap *>(result)[idx] = (m);
753 };
754 mlirAffineMapCompressUnusedSymbols(maps.data(), maps.size(),
755 compressed.data(), populate);
756 std::vector<PyAffineMap> res;
757 res.reserve(compressed.size());
758 for (auto m : compressed)
759 res.emplace_back(context->getRef(), m);
760 return res;
761 })
762 .def_prop_ro(
763 "context",
764 [](PyAffineMap &self) -> nb::typed<nb::object, PyMlirContext> {
765 return self.getContext().getObject();
766 },
767 "Context that owns the Affine Map")
768 .def(
769 "dump", [](PyAffineMap &self) { mlirAffineMapDump(self); },
771 .def_static(
772 "get",
773 [](intptr_t dimCount, intptr_t symbolCount, const nb::list &exprs,
774 DefaultingPyMlirContext context) {
775 SmallVector<MlirAffineExpr> affineExprs;
777 exprs, affineExprs, "attempting to create an AffineMap");
778 MlirAffineMap map =
779 mlirAffineMapGet(context->get(), dimCount, symbolCount,
780 affineExprs.size(), affineExprs.data());
781 return PyAffineMap(context->getRef(), map);
782 },
783 nb::arg("dim_count"), nb::arg("symbol_count"), nb::arg("exprs"),
784 nb::arg("context") = nb::none(),
785 "Gets a map with the given expressions as results.")
786 .def_static(
787 "get_constant",
788 [](intptr_t value, DefaultingPyMlirContext context) {
789 MlirAffineMap affineMap =
790 mlirAffineMapConstantGet(context->get(), value);
791 return PyAffineMap(context->getRef(), affineMap);
792 },
793 nb::arg("value"), nb::arg("context") = nb::none(),
794 "Gets an affine map with a single constant result")
795 .def_static(
796 "get_empty",
797 [](DefaultingPyMlirContext context) {
798 MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get());
799 return PyAffineMap(context->getRef(), affineMap);
800 },
801 nb::arg("context") = nb::none(), "Gets an empty affine map.")
802 .def_static(
803 "get_identity",
804 [](intptr_t nDims, DefaultingPyMlirContext context) {
805 MlirAffineMap affineMap =
806 mlirAffineMapMultiDimIdentityGet(context->get(), nDims);
807 return PyAffineMap(context->getRef(), affineMap);
808 },
809 nb::arg("n_dims"), nb::arg("context") = nb::none(),
810 "Gets an identity map with the given number of dimensions.")
811 .def_static(
812 "get_minor_identity",
813 [](intptr_t nDims, intptr_t nResults,
814 DefaultingPyMlirContext context) {
815 MlirAffineMap affineMap =
816 mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults);
817 return PyAffineMap(context->getRef(), affineMap);
818 },
819 nb::arg("n_dims"), nb::arg("n_results"),
820 nb::arg("context") = nb::none(),
821 "Gets a minor identity map with the given number of dimensions and "
822 "results.")
823 .def_static(
824 "get_permutation",
825 [](std::vector<unsigned> permutation,
826 DefaultingPyMlirContext context) {
827 if (!isPermutation(permutation))
828 throw std::runtime_error("Invalid permutation when attempting to "
829 "create an AffineMap");
830 MlirAffineMap affineMap = mlirAffineMapPermutationGet(
831 context->get(), permutation.size(), permutation.data());
832 return PyAffineMap(context->getRef(), affineMap);
833 },
834 nb::arg("permutation"), nb::arg("context") = nb::none(),
835 "Gets an affine map that permutes its inputs.")
836 .def(
837 "get_submap",
838 [](PyAffineMap &self, std::vector<intptr_t> &resultPos) {
839 intptr_t numResults = mlirAffineMapGetNumResults(self);
840 for (intptr_t pos : resultPos) {
841 if (pos < 0 || pos >= numResults)
842 throw nb::value_error("result position out of bounds");
843 }
844 MlirAffineMap affineMap = mlirAffineMapGetSubMap(
845 self, resultPos.size(), resultPos.data());
846 return PyAffineMap(self.getContext(), affineMap);
847 },
848 nb::arg("result_positions"))
849 .def(
850 "get_major_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 mlirAffineMapGetMajorSubMap(self, nResults);
856 return PyAffineMap(self.getContext(), affineMap);
857 },
858 nb::arg("n_results"))
859 .def(
860 "get_minor_submap",
861 [](PyAffineMap &self, intptr_t nResults) {
862 if (nResults >= mlirAffineMapGetNumResults(self))
863 throw nb::value_error("number of results out of bounds");
864 MlirAffineMap affineMap =
865 mlirAffineMapGetMinorSubMap(self, nResults);
866 return PyAffineMap(self.getContext(), affineMap);
867 },
868 nb::arg("n_results"))
869 .def(
870 "replace",
871 [](PyAffineMap &self, PyAffineExpr &expression,
872 PyAffineExpr &replacement, intptr_t numResultDims,
873 intptr_t numResultSyms) {
874 MlirAffineMap affineMap = mlirAffineMapReplace(
875 self, expression, replacement, numResultDims, numResultSyms);
876 return PyAffineMap(self.getContext(), affineMap);
877 },
878 nb::arg("expr"), nb::arg("replacement"), nb::arg("n_result_dims"),
879 nb::arg("n_result_syms"))
880 .def_prop_ro(
881 "is_permutation",
882 [](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); })
883 .def_prop_ro("is_projected_permutation",
884 [](PyAffineMap &self) {
886 })
887 .def_prop_ro(
888 "n_dims",
889 [](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); })
890 .def_prop_ro(
891 "n_inputs",
892 [](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); })
893 .def_prop_ro(
894 "n_symbols",
895 [](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); })
896 .def_prop_ro("results",
897 [](PyAffineMap &self) { return PyAffineMapExprList(self); });
899
900 //----------------------------------------------------------------------------
901 // Mapping of PyIntegerSet.
902 //----------------------------------------------------------------------------
903 nb::class_<PyIntegerSet>(m, "IntegerSet")
906 .def("__eq__", [](PyIntegerSet &self,
907 PyIntegerSet &other) { return self == other; })
908 .def("__eq__",
909 [](PyIntegerSet &self, const nb::object &other) { return false; })
910 .def("__str__",
911 [](PyIntegerSet &self) {
912 PyPrintAccumulator printAccum;
913 mlirIntegerSetPrint(self, printAccum.getCallback(),
914 printAccum.getUserData());
915 return printAccum.join();
916 })
917 .def("__repr__",
918 [](PyIntegerSet &self) {
919 PyPrintAccumulator printAccum;
920 printAccum.parts.append("IntegerSet(");
921 mlirIntegerSetPrint(self, printAccum.getCallback(),
922 printAccum.getUserData());
923 printAccum.parts.append(")");
924 return printAccum.join();
925 })
926 .def("__hash__",
927 [](PyIntegerSet &self) {
928 return static_cast<size_t>(llvm::hash_value(self.get().ptr));
929 })
930 .def_prop_ro(
931 "context",
932 [](PyIntegerSet &self) -> nb::typed<nb::object, PyMlirContext> {
933 return self.getContext().getObject();
934 })
935 .def(
936 "dump", [](PyIntegerSet &self) { mlirIntegerSetDump(self); },
938 .def_static(
939 "get",
940 [](intptr_t numDims, intptr_t numSymbols, const nb::list &exprs,
941 std::vector<bool> eqFlags, DefaultingPyMlirContext context) {
942 if (exprs.size() != eqFlags.size())
943 throw nb::value_error(
944 "Expected the number of constraints to match "
945 "that of equality flags");
946 if (exprs.size() == 0)
947 throw nb::value_error("Expected non-empty list of constraints");
948
949 // Copy over to a SmallVector because std::vector has a
950 // specialization for booleans that packs data and does not
951 // expose a `bool *`.
952 SmallVector<bool, 8> flags(eqFlags.begin(), eqFlags.end());
953
954 SmallVector<MlirAffineExpr> affineExprs;
955 pyListToVector<PyAffineExpr>(exprs, affineExprs,
956 "attempting to create an IntegerSet");
957 MlirIntegerSet set = mlirIntegerSetGet(
958 context->get(), numDims, numSymbols, exprs.size(),
959 affineExprs.data(), flags.data());
960 return PyIntegerSet(context->getRef(), set);
961 },
962 nb::arg("num_dims"), nb::arg("num_symbols"), nb::arg("exprs"),
963 nb::arg("eq_flags"), nb::arg("context") = nb::none())
964 .def_static(
965 "get_empty",
966 [](intptr_t numDims, intptr_t numSymbols,
967 DefaultingPyMlirContext context) {
968 MlirIntegerSet set =
969 mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols);
970 return PyIntegerSet(context->getRef(), set);
971 },
972 nb::arg("num_dims"), nb::arg("num_symbols"),
973 nb::arg("context") = nb::none())
974 .def(
975 "get_replaced",
976 [](PyIntegerSet &self, const nb::list &dimExprs,
977 const nb::list &symbolExprs, intptr_t numResultDims,
978 intptr_t numResultSymbols) {
979 if (static_cast<intptr_t>(dimExprs.size()) !=
981 throw nb::value_error(
982 "Expected the number of dimension replacement expressions "
983 "to match that of dimensions");
984 if (static_cast<intptr_t>(symbolExprs.size()) !=
986 throw nb::value_error(
987 "Expected the number of symbol replacement expressions "
988 "to match that of symbols");
989
990 SmallVector<MlirAffineExpr> dimAffineExprs, symbolAffineExprs;
992 dimExprs, dimAffineExprs,
993 "attempting to create an IntegerSet by replacing dimensions");
995 symbolExprs, symbolAffineExprs,
996 "attempting to create an IntegerSet by replacing symbols");
997 MlirIntegerSet set = mlirIntegerSetReplaceGet(
998 self, dimAffineExprs.data(), symbolAffineExprs.data(),
999 numResultDims, numResultSymbols);
1000 return PyIntegerSet(self.getContext(), set);
1001 },
1002 nb::arg("dim_exprs"), nb::arg("symbol_exprs"),
1003 nb::arg("num_result_dims"), nb::arg("num_result_symbols"))
1004 .def_prop_ro("is_canonical_empty",
1005 [](PyIntegerSet &self) {
1006 return mlirIntegerSetIsCanonicalEmpty(self);
1007 })
1008 .def_prop_ro(
1009 "n_dims",
1010 [](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); })
1011 .def_prop_ro(
1012 "n_symbols",
1013 [](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); })
1014 .def_prop_ro(
1015 "n_inputs",
1016 [](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); })
1017 .def_prop_ro("n_equalities",
1018 [](PyIntegerSet &self) {
1019 return mlirIntegerSetGetNumEqualities(self);
1020 })
1021 .def_prop_ro("n_inequalities",
1022 [](PyIntegerSet &self) {
1024 })
1025 .def_prop_ro("constraints", [](PyIntegerSet &self) {
1026 return PyIntegerSetConstraintList(self);
1027 });
1030}
1031} // namespace MLIR_BINDINGS_PYTHON_DOMAIN
1032} // namespace python
1033} // 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:69
static void pyListToVector(const nb::list &list, llvm::SmallVectorImpl< CType > &result, StringRef action)
Attempts to populate result with the content of list casted to the appropriate type (Python and C typ...
Definition IRAffine.cpp:47
static const char kDumpDocstring[]
Definition IRAffine.cpp:39
static MlirIntegerSet mlirPythonCapsuleToIntegerSet(PyObject *capsule)
Extracts an MlirIntegerSet from a capsule as produced from mlirPythonIntegerSetToCapsule.
Definition Interop.h:414
#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:230
static PyAffineAddExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:224
static PyAffineAddExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:219
static PyAffineCeilDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:335
static PyAffineCeilDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:340
static PyAffineCeilDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:346
static PyAffineConstantExpr get(intptr_t value, DefaultingPyMlirContext context)
Definition IRAffine.cpp:134
static PyAffineDimExpr get(intptr_t pos, DefaultingPyMlirContext context)
Definition IRAffine.cpp:156
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:365
static PyAffineExpr createFromCapsule(const nanobind::object &capsule)
Creates a PyAffineExpr from the MlirAffineExpr wrapped by a capsule.
Definition IRAffine.cpp:369
PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition IRCore.h:1205
bool operator==(const PyAffineExpr &other) const
Definition IRAffine.cpp:361
nanobind::typed< nanobind::object, PyAffineExpr > maybeDownCast()
Definition IRAffine.cpp:378
static PyAffineFloorDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:311
static PyAffineFloorDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:306
static PyAffineFloorDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:317
A list of expressions contained in an affine map.
Definition IRAffine.cpp:411
PyAffineMapExprList(const PyAffineMap &map, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Definition IRAffine.cpp:415
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
Definition IRCore.h:1234
bool operator==(const PyAffineMap &other) const
Definition IRAffine.cpp:444
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineMap.
Definition IRAffine.cpp:448
static PyAffineMap createFromCapsule(const nanobind::object &capsule)
Creates a PyAffineMap from the MlirAffineMap wrapped by a capsule.
Definition IRAffine.cpp:452
static PyAffineModExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:288
static PyAffineModExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:282
static PyAffineModExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:277
static PyAffineMulExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs)
Definition IRAffine.cpp:253
static PyAffineMulExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs)
Definition IRAffine.cpp:248
static PyAffineMulExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs)
Definition IRAffine.cpp:259
static PyAffineSymbolExpr get(intptr_t pos, DefaultingPyMlirContext context)
Definition IRAffine.cpp:176
PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition IRAffine.cpp:101
static void bindDerived(ClassTy &m)
Implemented by derived classes to add methods to the Python subclass.
Definition IRAffine.cpp:125
static MlirAffineExpr castFrom(PyAffineExpr &orig)
Definition IRAffine.cpp:106
PyIntegerSetConstraintList(const PyIntegerSet &set, intptr_t startIndex=0, intptr_t length=-1, intptr_t step=1)
Definition IRAffine.cpp:496
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:532
bool operator==(const PyIntegerSet &other) const
Definition IRAffine.cpp:524
nanobind::object getCapsule()
Gets a capsule wrapping the void* within the MlirIntegerSet.
Definition IRAffine.cpp:528
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
Definition IRCore.cpp:477
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.
Accumulates into a python string from a method that accepts an MlirStringCallback.
MlirStringCallback getCallback()