1436c6c9cSStella Laurenzo //===- IRAffine.cpp - Exports 'ir' module affine related bindings ---------===//
2436c6c9cSStella Laurenzo //
3436c6c9cSStella Laurenzo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4436c6c9cSStella Laurenzo // See https://llvm.org/LICENSE.txt for license information.
5436c6c9cSStella Laurenzo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6436c6c9cSStella Laurenzo //
7436c6c9cSStella Laurenzo //===----------------------------------------------------------------------===//
8436c6c9cSStella Laurenzo
91fc096afSMehdi Amini #include <utility>
101fc096afSMehdi Amini
11436c6c9cSStella Laurenzo #include "IRModule.h"
12436c6c9cSStella Laurenzo
13436c6c9cSStella Laurenzo #include "PybindUtils.h"
14436c6c9cSStella Laurenzo
15436c6c9cSStella Laurenzo #include "mlir-c/AffineMap.h"
16436c6c9cSStella Laurenzo #include "mlir-c/Bindings/Python/Interop.h"
17436c6c9cSStella Laurenzo #include "mlir-c/IntegerSet.h"
18436c6c9cSStella Laurenzo
19436c6c9cSStella Laurenzo namespace py = pybind11;
20436c6c9cSStella Laurenzo using namespace mlir;
21436c6c9cSStella Laurenzo using namespace mlir::python;
22436c6c9cSStella Laurenzo
23436c6c9cSStella Laurenzo using llvm::SmallVector;
24436c6c9cSStella Laurenzo using llvm::StringRef;
25436c6c9cSStella Laurenzo using llvm::Twine;
26436c6c9cSStella Laurenzo
27436c6c9cSStella Laurenzo static const char kDumpDocstring[] =
28436c6c9cSStella Laurenzo R"(Dumps a debug representation of the object to stderr.)";
29436c6c9cSStella Laurenzo
30436c6c9cSStella Laurenzo /// Attempts to populate `result` with the content of `list` casted to the
31436c6c9cSStella Laurenzo /// appropriate type (Python and C types are provided as template arguments).
32436c6c9cSStella Laurenzo /// Throws errors in case of failure, using "action" to describe what the caller
33436c6c9cSStella Laurenzo /// was attempting to do.
34436c6c9cSStella Laurenzo template <typename PyType, typename CType>
pyListToVector(const py::list & list,llvm::SmallVectorImpl<CType> & result,StringRef action)351fc096afSMehdi Amini static void pyListToVector(const py::list &list,
361fc096afSMehdi Amini llvm::SmallVectorImpl<CType> &result,
37436c6c9cSStella Laurenzo StringRef action) {
38436c6c9cSStella Laurenzo result.reserve(py::len(list));
39436c6c9cSStella Laurenzo for (py::handle item : list) {
40436c6c9cSStella Laurenzo try {
41436c6c9cSStella Laurenzo result.push_back(item.cast<PyType>());
42436c6c9cSStella Laurenzo } catch (py::cast_error &err) {
43436c6c9cSStella Laurenzo std::string msg = (llvm::Twine("Invalid expression when ") + action +
44436c6c9cSStella Laurenzo " (" + err.what() + ")")
45436c6c9cSStella Laurenzo .str();
46436c6c9cSStella Laurenzo throw py::cast_error(msg);
47436c6c9cSStella Laurenzo } catch (py::reference_cast_error &err) {
48436c6c9cSStella Laurenzo std::string msg = (llvm::Twine("Invalid expression (None?) when ") +
49436c6c9cSStella Laurenzo action + " (" + err.what() + ")")
50436c6c9cSStella Laurenzo .str();
51436c6c9cSStella Laurenzo throw py::cast_error(msg);
52436c6c9cSStella Laurenzo }
53436c6c9cSStella Laurenzo }
54436c6c9cSStella Laurenzo }
55436c6c9cSStella Laurenzo
56436c6c9cSStella Laurenzo template <typename PermutationTy>
isPermutation(std::vector<PermutationTy> permutation)57436c6c9cSStella Laurenzo static bool isPermutation(std::vector<PermutationTy> permutation) {
58436c6c9cSStella Laurenzo llvm::SmallVector<bool, 8> seen(permutation.size(), false);
59436c6c9cSStella Laurenzo for (auto val : permutation) {
60436c6c9cSStella Laurenzo if (val < permutation.size()) {
61436c6c9cSStella Laurenzo if (seen[val])
62436c6c9cSStella Laurenzo return false;
63436c6c9cSStella Laurenzo seen[val] = true;
64436c6c9cSStella Laurenzo continue;
65436c6c9cSStella Laurenzo }
66436c6c9cSStella Laurenzo return false;
67436c6c9cSStella Laurenzo }
68436c6c9cSStella Laurenzo return true;
69436c6c9cSStella Laurenzo }
70436c6c9cSStella Laurenzo
71436c6c9cSStella Laurenzo namespace {
72436c6c9cSStella Laurenzo
73436c6c9cSStella Laurenzo /// CRTP base class for Python MLIR affine expressions that subclass AffineExpr
74436c6c9cSStella Laurenzo /// and should be castable from it. Intermediate hierarchy classes can be
75436c6c9cSStella Laurenzo /// modeled by specifying BaseTy.
76436c6c9cSStella Laurenzo template <typename DerivedTy, typename BaseTy = PyAffineExpr>
77436c6c9cSStella Laurenzo class PyConcreteAffineExpr : public BaseTy {
78436c6c9cSStella Laurenzo public:
79436c6c9cSStella Laurenzo // Derived classes must define statics for:
80436c6c9cSStella Laurenzo // IsAFunctionTy isaFunction
81436c6c9cSStella Laurenzo // const char *pyClassName
82436c6c9cSStella Laurenzo // and redefine bindDerived.
83436c6c9cSStella Laurenzo using ClassTy = py::class_<DerivedTy, BaseTy>;
84436c6c9cSStella Laurenzo using IsAFunctionTy = bool (*)(MlirAffineExpr);
85436c6c9cSStella Laurenzo
86436c6c9cSStella Laurenzo PyConcreteAffineExpr() = default;
PyConcreteAffineExpr(PyMlirContextRef contextRef,MlirAffineExpr affineExpr)87436c6c9cSStella Laurenzo PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
88436c6c9cSStella Laurenzo : BaseTy(std::move(contextRef), affineExpr) {}
PyConcreteAffineExpr(PyAffineExpr & orig)89436c6c9cSStella Laurenzo PyConcreteAffineExpr(PyAffineExpr &orig)
90436c6c9cSStella Laurenzo : PyConcreteAffineExpr(orig.getContext(), castFrom(orig)) {}
91436c6c9cSStella Laurenzo
castFrom(PyAffineExpr & orig)92436c6c9cSStella Laurenzo static MlirAffineExpr castFrom(PyAffineExpr &orig) {
93436c6c9cSStella Laurenzo if (!DerivedTy::isaFunction(orig)) {
94436c6c9cSStella Laurenzo auto origRepr = py::repr(py::cast(orig)).cast<std::string>();
95436c6c9cSStella Laurenzo throw SetPyError(PyExc_ValueError,
96436c6c9cSStella Laurenzo Twine("Cannot cast affine expression to ") +
97436c6c9cSStella Laurenzo DerivedTy::pyClassName + " (from " + origRepr + ")");
98436c6c9cSStella Laurenzo }
99436c6c9cSStella Laurenzo return orig;
100436c6c9cSStella Laurenzo }
101436c6c9cSStella Laurenzo
bind(py::module & m)102436c6c9cSStella Laurenzo static void bind(py::module &m) {
103f05ff4f7SStella Laurenzo auto cls = ClassTy(m, DerivedTy::pyClassName, py::module_local());
104a6e7d024SStella Laurenzo cls.def(py::init<PyAffineExpr &>(), py::arg("expr"));
105a6e7d024SStella Laurenzo cls.def_static(
106a6e7d024SStella Laurenzo "isinstance",
107a6e7d024SStella Laurenzo [](PyAffineExpr &otherAffineExpr) -> bool {
10878f2dae0SAlex Zinenko return DerivedTy::isaFunction(otherAffineExpr);
109a6e7d024SStella Laurenzo },
110a6e7d024SStella Laurenzo py::arg("other"));
111436c6c9cSStella Laurenzo DerivedTy::bindDerived(cls);
112436c6c9cSStella Laurenzo }
113436c6c9cSStella Laurenzo
114436c6c9cSStella Laurenzo /// Implemented by derived classes to add methods to the Python subclass.
bindDerived(ClassTy & m)115436c6c9cSStella Laurenzo static void bindDerived(ClassTy &m) {}
116436c6c9cSStella Laurenzo };
117436c6c9cSStella Laurenzo
118436c6c9cSStella Laurenzo class PyAffineConstantExpr : public PyConcreteAffineExpr<PyAffineConstantExpr> {
119436c6c9cSStella Laurenzo public:
120436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAConstant;
121436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineConstantExpr";
122436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
123436c6c9cSStella Laurenzo
get(intptr_t value,DefaultingPyMlirContext context)124436c6c9cSStella Laurenzo static PyAffineConstantExpr get(intptr_t value,
125436c6c9cSStella Laurenzo DefaultingPyMlirContext context) {
126436c6c9cSStella Laurenzo MlirAffineExpr affineExpr =
127436c6c9cSStella Laurenzo mlirAffineConstantExprGet(context->get(), static_cast<int64_t>(value));
128436c6c9cSStella Laurenzo return PyAffineConstantExpr(context->getRef(), affineExpr);
129436c6c9cSStella Laurenzo }
130436c6c9cSStella Laurenzo
bindDerived(ClassTy & c)131436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
132436c6c9cSStella Laurenzo c.def_static("get", &PyAffineConstantExpr::get, py::arg("value"),
133436c6c9cSStella Laurenzo py::arg("context") = py::none());
134436c6c9cSStella Laurenzo c.def_property_readonly("value", [](PyAffineConstantExpr &self) {
135436c6c9cSStella Laurenzo return mlirAffineConstantExprGetValue(self);
136436c6c9cSStella Laurenzo });
137436c6c9cSStella Laurenzo }
138436c6c9cSStella Laurenzo };
139436c6c9cSStella Laurenzo
140436c6c9cSStella Laurenzo class PyAffineDimExpr : public PyConcreteAffineExpr<PyAffineDimExpr> {
141436c6c9cSStella Laurenzo public:
142436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsADim;
143436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineDimExpr";
144436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
145436c6c9cSStella Laurenzo
get(intptr_t pos,DefaultingPyMlirContext context)146436c6c9cSStella Laurenzo static PyAffineDimExpr get(intptr_t pos, DefaultingPyMlirContext context) {
147436c6c9cSStella Laurenzo MlirAffineExpr affineExpr = mlirAffineDimExprGet(context->get(), pos);
148436c6c9cSStella Laurenzo return PyAffineDimExpr(context->getRef(), affineExpr);
149436c6c9cSStella Laurenzo }
150436c6c9cSStella Laurenzo
bindDerived(ClassTy & c)151436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
152436c6c9cSStella Laurenzo c.def_static("get", &PyAffineDimExpr::get, py::arg("position"),
153436c6c9cSStella Laurenzo py::arg("context") = py::none());
154436c6c9cSStella Laurenzo c.def_property_readonly("position", [](PyAffineDimExpr &self) {
155436c6c9cSStella Laurenzo return mlirAffineDimExprGetPosition(self);
156436c6c9cSStella Laurenzo });
157436c6c9cSStella Laurenzo }
158436c6c9cSStella Laurenzo };
159436c6c9cSStella Laurenzo
160436c6c9cSStella Laurenzo class PyAffineSymbolExpr : public PyConcreteAffineExpr<PyAffineSymbolExpr> {
161436c6c9cSStella Laurenzo public:
162436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsASymbol;
163436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineSymbolExpr";
164436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
165436c6c9cSStella Laurenzo
get(intptr_t pos,DefaultingPyMlirContext context)166436c6c9cSStella Laurenzo static PyAffineSymbolExpr get(intptr_t pos, DefaultingPyMlirContext context) {
167436c6c9cSStella Laurenzo MlirAffineExpr affineExpr = mlirAffineSymbolExprGet(context->get(), pos);
168436c6c9cSStella Laurenzo return PyAffineSymbolExpr(context->getRef(), affineExpr);
169436c6c9cSStella Laurenzo }
170436c6c9cSStella Laurenzo
bindDerived(ClassTy & c)171436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
172436c6c9cSStella Laurenzo c.def_static("get", &PyAffineSymbolExpr::get, py::arg("position"),
173436c6c9cSStella Laurenzo py::arg("context") = py::none());
174436c6c9cSStella Laurenzo c.def_property_readonly("position", [](PyAffineSymbolExpr &self) {
175436c6c9cSStella Laurenzo return mlirAffineSymbolExprGetPosition(self);
176436c6c9cSStella Laurenzo });
177436c6c9cSStella Laurenzo }
178436c6c9cSStella Laurenzo };
179436c6c9cSStella Laurenzo
180436c6c9cSStella Laurenzo class PyAffineBinaryExpr : public PyConcreteAffineExpr<PyAffineBinaryExpr> {
181436c6c9cSStella Laurenzo public:
182436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsABinary;
183436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineBinaryExpr";
184436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
185436c6c9cSStella Laurenzo
lhs()186436c6c9cSStella Laurenzo PyAffineExpr lhs() {
187436c6c9cSStella Laurenzo MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get());
188436c6c9cSStella Laurenzo return PyAffineExpr(getContext(), lhsExpr);
189436c6c9cSStella Laurenzo }
190436c6c9cSStella Laurenzo
rhs()191436c6c9cSStella Laurenzo PyAffineExpr rhs() {
192436c6c9cSStella Laurenzo MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get());
193436c6c9cSStella Laurenzo return PyAffineExpr(getContext(), rhsExpr);
194436c6c9cSStella Laurenzo }
195436c6c9cSStella Laurenzo
bindDerived(ClassTy & c)196436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
197436c6c9cSStella Laurenzo c.def_property_readonly("lhs", &PyAffineBinaryExpr::lhs);
198436c6c9cSStella Laurenzo c.def_property_readonly("rhs", &PyAffineBinaryExpr::rhs);
199436c6c9cSStella Laurenzo }
200436c6c9cSStella Laurenzo };
201436c6c9cSStella Laurenzo
202436c6c9cSStella Laurenzo class PyAffineAddExpr
203436c6c9cSStella Laurenzo : public PyConcreteAffineExpr<PyAffineAddExpr, PyAffineBinaryExpr> {
204436c6c9cSStella Laurenzo public:
205436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAAdd;
206436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineAddExpr";
207436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
208436c6c9cSStella Laurenzo
get(PyAffineExpr lhs,const PyAffineExpr & rhs)2091fc096afSMehdi Amini static PyAffineAddExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
210436c6c9cSStella Laurenzo MlirAffineExpr expr = mlirAffineAddExprGet(lhs, rhs);
211436c6c9cSStella Laurenzo return PyAffineAddExpr(lhs.getContext(), expr);
212436c6c9cSStella Laurenzo }
213436c6c9cSStella Laurenzo
getRHSConstant(PyAffineExpr lhs,intptr_t rhs)214fc7594ccSAlex Zinenko static PyAffineAddExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
215fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineAddExprGet(
216fc7594ccSAlex Zinenko lhs, mlirAffineConstantExprGet(mlirAffineExprGetContext(lhs), rhs));
217fc7594ccSAlex Zinenko return PyAffineAddExpr(lhs.getContext(), expr);
218fc7594ccSAlex Zinenko }
219fc7594ccSAlex Zinenko
getLHSConstant(intptr_t lhs,PyAffineExpr rhs)220fc7594ccSAlex Zinenko static PyAffineAddExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
221fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineAddExprGet(
222fc7594ccSAlex Zinenko mlirAffineConstantExprGet(mlirAffineExprGetContext(rhs), lhs), rhs);
223fc7594ccSAlex Zinenko return PyAffineAddExpr(rhs.getContext(), expr);
224fc7594ccSAlex Zinenko }
225fc7594ccSAlex Zinenko
bindDerived(ClassTy & c)226436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
227436c6c9cSStella Laurenzo c.def_static("get", &PyAffineAddExpr::get);
228436c6c9cSStella Laurenzo }
229436c6c9cSStella Laurenzo };
230436c6c9cSStella Laurenzo
231436c6c9cSStella Laurenzo class PyAffineMulExpr
232436c6c9cSStella Laurenzo : public PyConcreteAffineExpr<PyAffineMulExpr, PyAffineBinaryExpr> {
233436c6c9cSStella Laurenzo public:
234436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAMul;
235436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineMulExpr";
236436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
237436c6c9cSStella Laurenzo
get(PyAffineExpr lhs,const PyAffineExpr & rhs)2381fc096afSMehdi Amini static PyAffineMulExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
239436c6c9cSStella Laurenzo MlirAffineExpr expr = mlirAffineMulExprGet(lhs, rhs);
240436c6c9cSStella Laurenzo return PyAffineMulExpr(lhs.getContext(), expr);
241436c6c9cSStella Laurenzo }
242436c6c9cSStella Laurenzo
getRHSConstant(PyAffineExpr lhs,intptr_t rhs)243fc7594ccSAlex Zinenko static PyAffineMulExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
244fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineMulExprGet(
245fc7594ccSAlex Zinenko lhs, mlirAffineConstantExprGet(mlirAffineExprGetContext(lhs), rhs));
246fc7594ccSAlex Zinenko return PyAffineMulExpr(lhs.getContext(), expr);
247fc7594ccSAlex Zinenko }
248fc7594ccSAlex Zinenko
getLHSConstant(intptr_t lhs,PyAffineExpr rhs)249fc7594ccSAlex Zinenko static PyAffineMulExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
250fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineMulExprGet(
251fc7594ccSAlex Zinenko mlirAffineConstantExprGet(mlirAffineExprGetContext(rhs), lhs), rhs);
252fc7594ccSAlex Zinenko return PyAffineMulExpr(rhs.getContext(), expr);
253fc7594ccSAlex Zinenko }
254fc7594ccSAlex Zinenko
bindDerived(ClassTy & c)255436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
256436c6c9cSStella Laurenzo c.def_static("get", &PyAffineMulExpr::get);
257436c6c9cSStella Laurenzo }
258436c6c9cSStella Laurenzo };
259436c6c9cSStella Laurenzo
260436c6c9cSStella Laurenzo class PyAffineModExpr
261436c6c9cSStella Laurenzo : public PyConcreteAffineExpr<PyAffineModExpr, PyAffineBinaryExpr> {
262436c6c9cSStella Laurenzo public:
263436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAMod;
264436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineModExpr";
265436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
266436c6c9cSStella Laurenzo
get(PyAffineExpr lhs,const PyAffineExpr & rhs)2671fc096afSMehdi Amini static PyAffineModExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
268436c6c9cSStella Laurenzo MlirAffineExpr expr = mlirAffineModExprGet(lhs, rhs);
269436c6c9cSStella Laurenzo return PyAffineModExpr(lhs.getContext(), expr);
270436c6c9cSStella Laurenzo }
271436c6c9cSStella Laurenzo
getRHSConstant(PyAffineExpr lhs,intptr_t rhs)272fc7594ccSAlex Zinenko static PyAffineModExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
273fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineModExprGet(
274fc7594ccSAlex Zinenko lhs, mlirAffineConstantExprGet(mlirAffineExprGetContext(lhs), rhs));
275fc7594ccSAlex Zinenko return PyAffineModExpr(lhs.getContext(), expr);
276fc7594ccSAlex Zinenko }
277fc7594ccSAlex Zinenko
getLHSConstant(intptr_t lhs,PyAffineExpr rhs)278fc7594ccSAlex Zinenko static PyAffineModExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
279fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineModExprGet(
280fc7594ccSAlex Zinenko mlirAffineConstantExprGet(mlirAffineExprGetContext(rhs), lhs), rhs);
281fc7594ccSAlex Zinenko return PyAffineModExpr(rhs.getContext(), expr);
282fc7594ccSAlex Zinenko }
283fc7594ccSAlex Zinenko
bindDerived(ClassTy & c)284436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
285436c6c9cSStella Laurenzo c.def_static("get", &PyAffineModExpr::get);
286436c6c9cSStella Laurenzo }
287436c6c9cSStella Laurenzo };
288436c6c9cSStella Laurenzo
289436c6c9cSStella Laurenzo class PyAffineFloorDivExpr
290436c6c9cSStella Laurenzo : public PyConcreteAffineExpr<PyAffineFloorDivExpr, PyAffineBinaryExpr> {
291436c6c9cSStella Laurenzo public:
292436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAFloorDiv;
293436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineFloorDivExpr";
294436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
295436c6c9cSStella Laurenzo
get(PyAffineExpr lhs,const PyAffineExpr & rhs)2961fc096afSMehdi Amini static PyAffineFloorDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
297436c6c9cSStella Laurenzo MlirAffineExpr expr = mlirAffineFloorDivExprGet(lhs, rhs);
298436c6c9cSStella Laurenzo return PyAffineFloorDivExpr(lhs.getContext(), expr);
299436c6c9cSStella Laurenzo }
300436c6c9cSStella Laurenzo
getRHSConstant(PyAffineExpr lhs,intptr_t rhs)301fc7594ccSAlex Zinenko static PyAffineFloorDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
302fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineFloorDivExprGet(
303fc7594ccSAlex Zinenko lhs, mlirAffineConstantExprGet(mlirAffineExprGetContext(lhs), rhs));
304fc7594ccSAlex Zinenko return PyAffineFloorDivExpr(lhs.getContext(), expr);
305fc7594ccSAlex Zinenko }
306fc7594ccSAlex Zinenko
getLHSConstant(intptr_t lhs,PyAffineExpr rhs)307fc7594ccSAlex Zinenko static PyAffineFloorDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
308fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineFloorDivExprGet(
309fc7594ccSAlex Zinenko mlirAffineConstantExprGet(mlirAffineExprGetContext(rhs), lhs), rhs);
310fc7594ccSAlex Zinenko return PyAffineFloorDivExpr(rhs.getContext(), expr);
311fc7594ccSAlex Zinenko }
312fc7594ccSAlex Zinenko
bindDerived(ClassTy & c)313436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
314436c6c9cSStella Laurenzo c.def_static("get", &PyAffineFloorDivExpr::get);
315436c6c9cSStella Laurenzo }
316436c6c9cSStella Laurenzo };
317436c6c9cSStella Laurenzo
318436c6c9cSStella Laurenzo class PyAffineCeilDivExpr
319436c6c9cSStella Laurenzo : public PyConcreteAffineExpr<PyAffineCeilDivExpr, PyAffineBinaryExpr> {
320436c6c9cSStella Laurenzo public:
321436c6c9cSStella Laurenzo static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsACeilDiv;
322436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineCeilDivExpr";
323436c6c9cSStella Laurenzo using PyConcreteAffineExpr::PyConcreteAffineExpr;
324436c6c9cSStella Laurenzo
get(PyAffineExpr lhs,const PyAffineExpr & rhs)3251fc096afSMehdi Amini static PyAffineCeilDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
326436c6c9cSStella Laurenzo MlirAffineExpr expr = mlirAffineCeilDivExprGet(lhs, rhs);
327436c6c9cSStella Laurenzo return PyAffineCeilDivExpr(lhs.getContext(), expr);
328436c6c9cSStella Laurenzo }
329436c6c9cSStella Laurenzo
getRHSConstant(PyAffineExpr lhs,intptr_t rhs)330fc7594ccSAlex Zinenko static PyAffineCeilDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
331fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineCeilDivExprGet(
332fc7594ccSAlex Zinenko lhs, mlirAffineConstantExprGet(mlirAffineExprGetContext(lhs), rhs));
333fc7594ccSAlex Zinenko return PyAffineCeilDivExpr(lhs.getContext(), expr);
334fc7594ccSAlex Zinenko }
335fc7594ccSAlex Zinenko
getLHSConstant(intptr_t lhs,PyAffineExpr rhs)336fc7594ccSAlex Zinenko static PyAffineCeilDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
337fc7594ccSAlex Zinenko MlirAffineExpr expr = mlirAffineCeilDivExprGet(
338fc7594ccSAlex Zinenko mlirAffineConstantExprGet(mlirAffineExprGetContext(rhs), lhs), rhs);
339fc7594ccSAlex Zinenko return PyAffineCeilDivExpr(rhs.getContext(), expr);
340fc7594ccSAlex Zinenko }
341fc7594ccSAlex Zinenko
bindDerived(ClassTy & c)342436c6c9cSStella Laurenzo static void bindDerived(ClassTy &c) {
343436c6c9cSStella Laurenzo c.def_static("get", &PyAffineCeilDivExpr::get);
344436c6c9cSStella Laurenzo }
345436c6c9cSStella Laurenzo };
346436c6c9cSStella Laurenzo
347436c6c9cSStella Laurenzo } // namespace
348436c6c9cSStella Laurenzo
operator ==(const PyAffineExpr & other)349436c6c9cSStella Laurenzo bool PyAffineExpr::operator==(const PyAffineExpr &other) {
350436c6c9cSStella Laurenzo return mlirAffineExprEqual(affineExpr, other.affineExpr);
351436c6c9cSStella Laurenzo }
352436c6c9cSStella Laurenzo
getCapsule()353436c6c9cSStella Laurenzo py::object PyAffineExpr::getCapsule() {
354436c6c9cSStella Laurenzo return py::reinterpret_steal<py::object>(
355436c6c9cSStella Laurenzo mlirPythonAffineExprToCapsule(*this));
356436c6c9cSStella Laurenzo }
357436c6c9cSStella Laurenzo
createFromCapsule(py::object capsule)358436c6c9cSStella Laurenzo PyAffineExpr PyAffineExpr::createFromCapsule(py::object capsule) {
359436c6c9cSStella Laurenzo MlirAffineExpr rawAffineExpr = mlirPythonCapsuleToAffineExpr(capsule.ptr());
360436c6c9cSStella Laurenzo if (mlirAffineExprIsNull(rawAffineExpr))
361436c6c9cSStella Laurenzo throw py::error_already_set();
362436c6c9cSStella Laurenzo return PyAffineExpr(
363436c6c9cSStella Laurenzo PyMlirContext::forContext(mlirAffineExprGetContext(rawAffineExpr)),
364436c6c9cSStella Laurenzo rawAffineExpr);
365436c6c9cSStella Laurenzo }
366436c6c9cSStella Laurenzo
367436c6c9cSStella Laurenzo //------------------------------------------------------------------------------
368436c6c9cSStella Laurenzo // PyAffineMap and utilities.
369436c6c9cSStella Laurenzo //------------------------------------------------------------------------------
370436c6c9cSStella Laurenzo namespace {
371436c6c9cSStella Laurenzo
372436c6c9cSStella Laurenzo /// A list of expressions contained in an affine map. Internally these are
373436c6c9cSStella Laurenzo /// stored as a consecutive array leading to inexpensive random access. Both
374436c6c9cSStella Laurenzo /// the map and the expression are owned by the context so we need not bother
375436c6c9cSStella Laurenzo /// with lifetime extension.
376436c6c9cSStella Laurenzo class PyAffineMapExprList
377436c6c9cSStella Laurenzo : public Sliceable<PyAffineMapExprList, PyAffineExpr> {
378436c6c9cSStella Laurenzo public:
379436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "AffineExprList";
380436c6c9cSStella Laurenzo
PyAffineMapExprList(const PyAffineMap & map,intptr_t startIndex=0,intptr_t length=-1,intptr_t step=1)3811fc096afSMehdi Amini PyAffineMapExprList(const PyAffineMap &map, intptr_t startIndex = 0,
382436c6c9cSStella Laurenzo intptr_t length = -1, intptr_t step = 1)
383436c6c9cSStella Laurenzo : Sliceable(startIndex,
384436c6c9cSStella Laurenzo length == -1 ? mlirAffineMapGetNumResults(map) : length,
385436c6c9cSStella Laurenzo step),
386436c6c9cSStella Laurenzo affineMap(map) {}
387436c6c9cSStella Laurenzo
388*ee168fb9SAlex Zinenko private:
389*ee168fb9SAlex Zinenko /// Give the parent CRTP class access to hook implementations below.
390*ee168fb9SAlex Zinenko friend class Sliceable<PyAffineMapExprList, PyAffineExpr>;
391436c6c9cSStella Laurenzo
getRawNumElements()392*ee168fb9SAlex Zinenko intptr_t getRawNumElements() { return mlirAffineMapGetNumResults(affineMap); }
393*ee168fb9SAlex Zinenko
getRawElement(intptr_t pos)394*ee168fb9SAlex Zinenko PyAffineExpr getRawElement(intptr_t pos) {
395436c6c9cSStella Laurenzo return PyAffineExpr(affineMap.getContext(),
396436c6c9cSStella Laurenzo mlirAffineMapGetResult(affineMap, pos));
397436c6c9cSStella Laurenzo }
398436c6c9cSStella Laurenzo
slice(intptr_t startIndex,intptr_t length,intptr_t step)399436c6c9cSStella Laurenzo PyAffineMapExprList slice(intptr_t startIndex, intptr_t length,
400436c6c9cSStella Laurenzo intptr_t step) {
401436c6c9cSStella Laurenzo return PyAffineMapExprList(affineMap, startIndex, length, step);
402436c6c9cSStella Laurenzo }
403436c6c9cSStella Laurenzo
404436c6c9cSStella Laurenzo PyAffineMap affineMap;
405436c6c9cSStella Laurenzo };
406be0a7e9fSMehdi Amini } // namespace
407436c6c9cSStella Laurenzo
operator ==(const PyAffineMap & other)408436c6c9cSStella Laurenzo bool PyAffineMap::operator==(const PyAffineMap &other) {
409436c6c9cSStella Laurenzo return mlirAffineMapEqual(affineMap, other.affineMap);
410436c6c9cSStella Laurenzo }
411436c6c9cSStella Laurenzo
getCapsule()412436c6c9cSStella Laurenzo py::object PyAffineMap::getCapsule() {
413436c6c9cSStella Laurenzo return py::reinterpret_steal<py::object>(mlirPythonAffineMapToCapsule(*this));
414436c6c9cSStella Laurenzo }
415436c6c9cSStella Laurenzo
createFromCapsule(py::object capsule)416436c6c9cSStella Laurenzo PyAffineMap PyAffineMap::createFromCapsule(py::object capsule) {
417436c6c9cSStella Laurenzo MlirAffineMap rawAffineMap = mlirPythonCapsuleToAffineMap(capsule.ptr());
418436c6c9cSStella Laurenzo if (mlirAffineMapIsNull(rawAffineMap))
419436c6c9cSStella Laurenzo throw py::error_already_set();
420436c6c9cSStella Laurenzo return PyAffineMap(
421436c6c9cSStella Laurenzo PyMlirContext::forContext(mlirAffineMapGetContext(rawAffineMap)),
422436c6c9cSStella Laurenzo rawAffineMap);
423436c6c9cSStella Laurenzo }
424436c6c9cSStella Laurenzo
425436c6c9cSStella Laurenzo //------------------------------------------------------------------------------
426436c6c9cSStella Laurenzo // PyIntegerSet and utilities.
427436c6c9cSStella Laurenzo //------------------------------------------------------------------------------
428436c6c9cSStella Laurenzo namespace {
429436c6c9cSStella Laurenzo
430436c6c9cSStella Laurenzo class PyIntegerSetConstraint {
431436c6c9cSStella Laurenzo public:
PyIntegerSetConstraint(PyIntegerSet set,intptr_t pos)4321fc096afSMehdi Amini PyIntegerSetConstraint(PyIntegerSet set, intptr_t pos)
4331fc096afSMehdi Amini : set(std::move(set)), pos(pos) {}
434436c6c9cSStella Laurenzo
getExpr()435436c6c9cSStella Laurenzo PyAffineExpr getExpr() {
436436c6c9cSStella Laurenzo return PyAffineExpr(set.getContext(),
437436c6c9cSStella Laurenzo mlirIntegerSetGetConstraint(set, pos));
438436c6c9cSStella Laurenzo }
439436c6c9cSStella Laurenzo
isEq()440436c6c9cSStella Laurenzo bool isEq() { return mlirIntegerSetIsConstraintEq(set, pos); }
441436c6c9cSStella Laurenzo
bind(py::module & m)442436c6c9cSStella Laurenzo static void bind(py::module &m) {
443f05ff4f7SStella Laurenzo py::class_<PyIntegerSetConstraint>(m, "IntegerSetConstraint",
444f05ff4f7SStella Laurenzo py::module_local())
445436c6c9cSStella Laurenzo .def_property_readonly("expr", &PyIntegerSetConstraint::getExpr)
446436c6c9cSStella Laurenzo .def_property_readonly("is_eq", &PyIntegerSetConstraint::isEq);
447436c6c9cSStella Laurenzo }
448436c6c9cSStella Laurenzo
449436c6c9cSStella Laurenzo private:
450436c6c9cSStella Laurenzo PyIntegerSet set;
451436c6c9cSStella Laurenzo intptr_t pos;
452436c6c9cSStella Laurenzo };
453436c6c9cSStella Laurenzo
454436c6c9cSStella Laurenzo class PyIntegerSetConstraintList
455436c6c9cSStella Laurenzo : public Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint> {
456436c6c9cSStella Laurenzo public:
457436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "IntegerSetConstraintList";
458436c6c9cSStella Laurenzo
PyIntegerSetConstraintList(const PyIntegerSet & set,intptr_t startIndex=0,intptr_t length=-1,intptr_t step=1)4591fc096afSMehdi Amini PyIntegerSetConstraintList(const PyIntegerSet &set, intptr_t startIndex = 0,
460436c6c9cSStella Laurenzo intptr_t length = -1, intptr_t step = 1)
461436c6c9cSStella Laurenzo : Sliceable(startIndex,
462436c6c9cSStella Laurenzo length == -1 ? mlirIntegerSetGetNumConstraints(set) : length,
463436c6c9cSStella Laurenzo step),
464436c6c9cSStella Laurenzo set(set) {}
465436c6c9cSStella Laurenzo
466*ee168fb9SAlex Zinenko private:
467*ee168fb9SAlex Zinenko /// Give the parent CRTP class access to hook implementations below.
468*ee168fb9SAlex Zinenko friend class Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint>;
469436c6c9cSStella Laurenzo
getRawNumElements()470*ee168fb9SAlex Zinenko intptr_t getRawNumElements() { return mlirIntegerSetGetNumConstraints(set); }
471*ee168fb9SAlex Zinenko
getRawElement(intptr_t pos)472*ee168fb9SAlex Zinenko PyIntegerSetConstraint getRawElement(intptr_t pos) {
473436c6c9cSStella Laurenzo return PyIntegerSetConstraint(set, pos);
474436c6c9cSStella Laurenzo }
475436c6c9cSStella Laurenzo
slice(intptr_t startIndex,intptr_t length,intptr_t step)476436c6c9cSStella Laurenzo PyIntegerSetConstraintList slice(intptr_t startIndex, intptr_t length,
477436c6c9cSStella Laurenzo intptr_t step) {
478436c6c9cSStella Laurenzo return PyIntegerSetConstraintList(set, startIndex, length, step);
479436c6c9cSStella Laurenzo }
480436c6c9cSStella Laurenzo
481436c6c9cSStella Laurenzo PyIntegerSet set;
482436c6c9cSStella Laurenzo };
483436c6c9cSStella Laurenzo } // namespace
484436c6c9cSStella Laurenzo
operator ==(const PyIntegerSet & other)485436c6c9cSStella Laurenzo bool PyIntegerSet::operator==(const PyIntegerSet &other) {
486436c6c9cSStella Laurenzo return mlirIntegerSetEqual(integerSet, other.integerSet);
487436c6c9cSStella Laurenzo }
488436c6c9cSStella Laurenzo
getCapsule()489436c6c9cSStella Laurenzo py::object PyIntegerSet::getCapsule() {
490436c6c9cSStella Laurenzo return py::reinterpret_steal<py::object>(
491436c6c9cSStella Laurenzo mlirPythonIntegerSetToCapsule(*this));
492436c6c9cSStella Laurenzo }
493436c6c9cSStella Laurenzo
createFromCapsule(py::object capsule)494436c6c9cSStella Laurenzo PyIntegerSet PyIntegerSet::createFromCapsule(py::object capsule) {
495436c6c9cSStella Laurenzo MlirIntegerSet rawIntegerSet = mlirPythonCapsuleToIntegerSet(capsule.ptr());
496436c6c9cSStella Laurenzo if (mlirIntegerSetIsNull(rawIntegerSet))
497436c6c9cSStella Laurenzo throw py::error_already_set();
498436c6c9cSStella Laurenzo return PyIntegerSet(
499436c6c9cSStella Laurenzo PyMlirContext::forContext(mlirIntegerSetGetContext(rawIntegerSet)),
500436c6c9cSStella Laurenzo rawIntegerSet);
501436c6c9cSStella Laurenzo }
502436c6c9cSStella Laurenzo
populateIRAffine(py::module & m)503436c6c9cSStella Laurenzo void mlir::python::populateIRAffine(py::module &m) {
504436c6c9cSStella Laurenzo //----------------------------------------------------------------------------
505436c6c9cSStella Laurenzo // Mapping of PyAffineExpr and derived classes.
506436c6c9cSStella Laurenzo //----------------------------------------------------------------------------
507f05ff4f7SStella Laurenzo py::class_<PyAffineExpr>(m, "AffineExpr", py::module_local())
508436c6c9cSStella Laurenzo .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
509436c6c9cSStella Laurenzo &PyAffineExpr::getCapsule)
510436c6c9cSStella Laurenzo .def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAffineExpr::createFromCapsule)
511fc7594ccSAlex Zinenko .def("__add__", &PyAffineAddExpr::get)
512fc7594ccSAlex Zinenko .def("__add__", &PyAffineAddExpr::getRHSConstant)
513fc7594ccSAlex Zinenko .def("__radd__", &PyAffineAddExpr::getRHSConstant)
514fc7594ccSAlex Zinenko .def("__mul__", &PyAffineMulExpr::get)
515fc7594ccSAlex Zinenko .def("__mul__", &PyAffineMulExpr::getRHSConstant)
516fc7594ccSAlex Zinenko .def("__rmul__", &PyAffineMulExpr::getRHSConstant)
517fc7594ccSAlex Zinenko .def("__mod__", &PyAffineModExpr::get)
518fc7594ccSAlex Zinenko .def("__mod__", &PyAffineModExpr::getRHSConstant)
519fc7594ccSAlex Zinenko .def("__rmod__",
520fc7594ccSAlex Zinenko [](PyAffineExpr &self, intptr_t other) {
521fc7594ccSAlex Zinenko return PyAffineModExpr::get(
522fc7594ccSAlex Zinenko PyAffineConstantExpr::get(other, *self.getContext().get()),
523fc7594ccSAlex Zinenko self);
524436c6c9cSStella Laurenzo })
525436c6c9cSStella Laurenzo .def("__sub__",
526436c6c9cSStella Laurenzo [](PyAffineExpr &self, PyAffineExpr &other) {
527436c6c9cSStella Laurenzo auto negOne =
528436c6c9cSStella Laurenzo PyAffineConstantExpr::get(-1, *self.getContext().get());
529436c6c9cSStella Laurenzo return PyAffineAddExpr::get(self,
530436c6c9cSStella Laurenzo PyAffineMulExpr::get(negOne, other));
531436c6c9cSStella Laurenzo })
532fc7594ccSAlex Zinenko .def("__sub__",
533fc7594ccSAlex Zinenko [](PyAffineExpr &self, intptr_t other) {
534fc7594ccSAlex Zinenko return PyAffineAddExpr::get(
535fc7594ccSAlex Zinenko self,
536fc7594ccSAlex Zinenko PyAffineConstantExpr::get(-other, *self.getContext().get()));
537fc7594ccSAlex Zinenko })
538fc7594ccSAlex Zinenko .def("__rsub__",
539fc7594ccSAlex Zinenko [](PyAffineExpr &self, intptr_t other) {
540fc7594ccSAlex Zinenko return PyAffineAddExpr::getLHSConstant(
541fc7594ccSAlex Zinenko other, PyAffineMulExpr::getLHSConstant(-1, self));
542fc7594ccSAlex Zinenko })
543436c6c9cSStella Laurenzo .def("__eq__", [](PyAffineExpr &self,
544436c6c9cSStella Laurenzo PyAffineExpr &other) { return self == other; })
545436c6c9cSStella Laurenzo .def("__eq__",
546436c6c9cSStella Laurenzo [](PyAffineExpr &self, py::object &other) { return false; })
547436c6c9cSStella Laurenzo .def("__str__",
548436c6c9cSStella Laurenzo [](PyAffineExpr &self) {
549436c6c9cSStella Laurenzo PyPrintAccumulator printAccum;
550436c6c9cSStella Laurenzo mlirAffineExprPrint(self, printAccum.getCallback(),
551436c6c9cSStella Laurenzo printAccum.getUserData());
552436c6c9cSStella Laurenzo return printAccum.join();
553436c6c9cSStella Laurenzo })
554436c6c9cSStella Laurenzo .def("__repr__",
555436c6c9cSStella Laurenzo [](PyAffineExpr &self) {
556436c6c9cSStella Laurenzo PyPrintAccumulator printAccum;
557436c6c9cSStella Laurenzo printAccum.parts.append("AffineExpr(");
558436c6c9cSStella Laurenzo mlirAffineExprPrint(self, printAccum.getCallback(),
559436c6c9cSStella Laurenzo printAccum.getUserData());
560436c6c9cSStella Laurenzo printAccum.parts.append(")");
561436c6c9cSStella Laurenzo return printAccum.join();
562436c6c9cSStella Laurenzo })
563fc7594ccSAlex Zinenko .def("__hash__",
564fc7594ccSAlex Zinenko [](PyAffineExpr &self) {
565fc7594ccSAlex Zinenko return static_cast<size_t>(llvm::hash_value(self.get().ptr));
566fc7594ccSAlex Zinenko })
567436c6c9cSStella Laurenzo .def_property_readonly(
568436c6c9cSStella Laurenzo "context",
569436c6c9cSStella Laurenzo [](PyAffineExpr &self) { return self.getContext().getObject(); })
570fc7594ccSAlex Zinenko .def("compose",
571fc7594ccSAlex Zinenko [](PyAffineExpr &self, PyAffineMap &other) {
572fc7594ccSAlex Zinenko return PyAffineExpr(self.getContext(),
573fc7594ccSAlex Zinenko mlirAffineExprCompose(self, other));
574fc7594ccSAlex Zinenko })
575436c6c9cSStella Laurenzo .def_static(
576436c6c9cSStella Laurenzo "get_add", &PyAffineAddExpr::get,
577436c6c9cSStella Laurenzo "Gets an affine expression containing a sum of two expressions.")
578fc7594ccSAlex Zinenko .def_static("get_add", &PyAffineAddExpr::getLHSConstant,
579fc7594ccSAlex Zinenko "Gets an affine expression containing a sum of a constant "
580fc7594ccSAlex Zinenko "and another expression.")
581fc7594ccSAlex Zinenko .def_static("get_add", &PyAffineAddExpr::getRHSConstant,
582fc7594ccSAlex Zinenko "Gets an affine expression containing a sum of an expression "
583fc7594ccSAlex Zinenko "and a constant.")
584436c6c9cSStella Laurenzo .def_static(
585436c6c9cSStella Laurenzo "get_mul", &PyAffineMulExpr::get,
586436c6c9cSStella Laurenzo "Gets an affine expression containing a product of two expressions.")
587fc7594ccSAlex Zinenko .def_static("get_mul", &PyAffineMulExpr::getLHSConstant,
588fc7594ccSAlex Zinenko "Gets an affine expression containing a product of a "
589fc7594ccSAlex Zinenko "constant and another expression.")
590fc7594ccSAlex Zinenko .def_static("get_mul", &PyAffineMulExpr::getRHSConstant,
591fc7594ccSAlex Zinenko "Gets an affine expression containing a product of an "
592fc7594ccSAlex Zinenko "expression and a constant.")
593436c6c9cSStella Laurenzo .def_static("get_mod", &PyAffineModExpr::get,
594436c6c9cSStella Laurenzo "Gets an affine expression containing the modulo of dividing "
595436c6c9cSStella Laurenzo "one expression by another.")
596fc7594ccSAlex Zinenko .def_static("get_mod", &PyAffineModExpr::getLHSConstant,
597fc7594ccSAlex Zinenko "Gets a semi-affine expression containing the modulo of "
598fc7594ccSAlex Zinenko "dividing a constant by an expression.")
599fc7594ccSAlex Zinenko .def_static("get_mod", &PyAffineModExpr::getRHSConstant,
600fc7594ccSAlex Zinenko "Gets an affine expression containing the module of dividing"
601fc7594ccSAlex Zinenko "an expression by a constant.")
602436c6c9cSStella Laurenzo .def_static("get_floor_div", &PyAffineFloorDivExpr::get,
603436c6c9cSStella Laurenzo "Gets an affine expression containing the rounded-down "
604436c6c9cSStella Laurenzo "result of dividing one expression by another.")
605fc7594ccSAlex Zinenko .def_static("get_floor_div", &PyAffineFloorDivExpr::getLHSConstant,
606fc7594ccSAlex Zinenko "Gets a semi-affine expression containing the rounded-down "
607fc7594ccSAlex Zinenko "result of dividing a constant by an expression.")
608fc7594ccSAlex Zinenko .def_static("get_floor_div", &PyAffineFloorDivExpr::getRHSConstant,
609fc7594ccSAlex Zinenko "Gets an affine expression containing the rounded-down "
610fc7594ccSAlex Zinenko "result of dividing an expression by a constant.")
611436c6c9cSStella Laurenzo .def_static("get_ceil_div", &PyAffineCeilDivExpr::get,
612436c6c9cSStella Laurenzo "Gets an affine expression containing the rounded-up result "
613436c6c9cSStella Laurenzo "of dividing one expression by another.")
614fc7594ccSAlex Zinenko .def_static("get_ceil_div", &PyAffineCeilDivExpr::getLHSConstant,
615fc7594ccSAlex Zinenko "Gets a semi-affine expression containing the rounded-up "
616fc7594ccSAlex Zinenko "result of dividing a constant by an expression.")
617fc7594ccSAlex Zinenko .def_static("get_ceil_div", &PyAffineCeilDivExpr::getRHSConstant,
618fc7594ccSAlex Zinenko "Gets an affine expression containing the rounded-up result "
619fc7594ccSAlex Zinenko "of dividing an expression by a constant.")
620436c6c9cSStella Laurenzo .def_static("get_constant", &PyAffineConstantExpr::get, py::arg("value"),
621436c6c9cSStella Laurenzo py::arg("context") = py::none(),
622436c6c9cSStella Laurenzo "Gets a constant affine expression with the given value.")
623436c6c9cSStella Laurenzo .def_static(
624436c6c9cSStella Laurenzo "get_dim", &PyAffineDimExpr::get, py::arg("position"),
625436c6c9cSStella Laurenzo py::arg("context") = py::none(),
626436c6c9cSStella Laurenzo "Gets an affine expression of a dimension at the given position.")
627436c6c9cSStella Laurenzo .def_static(
628436c6c9cSStella Laurenzo "get_symbol", &PyAffineSymbolExpr::get, py::arg("position"),
629436c6c9cSStella Laurenzo py::arg("context") = py::none(),
630436c6c9cSStella Laurenzo "Gets an affine expression of a symbol at the given position.")
631436c6c9cSStella Laurenzo .def(
632436c6c9cSStella Laurenzo "dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); },
633436c6c9cSStella Laurenzo kDumpDocstring);
634436c6c9cSStella Laurenzo PyAffineConstantExpr::bind(m);
635436c6c9cSStella Laurenzo PyAffineDimExpr::bind(m);
636436c6c9cSStella Laurenzo PyAffineSymbolExpr::bind(m);
637436c6c9cSStella Laurenzo PyAffineBinaryExpr::bind(m);
638436c6c9cSStella Laurenzo PyAffineAddExpr::bind(m);
639436c6c9cSStella Laurenzo PyAffineMulExpr::bind(m);
640436c6c9cSStella Laurenzo PyAffineModExpr::bind(m);
641436c6c9cSStella Laurenzo PyAffineFloorDivExpr::bind(m);
642436c6c9cSStella Laurenzo PyAffineCeilDivExpr::bind(m);
643436c6c9cSStella Laurenzo
644436c6c9cSStella Laurenzo //----------------------------------------------------------------------------
645436c6c9cSStella Laurenzo // Mapping of PyAffineMap.
646436c6c9cSStella Laurenzo //----------------------------------------------------------------------------
647f05ff4f7SStella Laurenzo py::class_<PyAffineMap>(m, "AffineMap", py::module_local())
648436c6c9cSStella Laurenzo .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
649436c6c9cSStella Laurenzo &PyAffineMap::getCapsule)
650436c6c9cSStella Laurenzo .def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAffineMap::createFromCapsule)
651436c6c9cSStella Laurenzo .def("__eq__",
652436c6c9cSStella Laurenzo [](PyAffineMap &self, PyAffineMap &other) { return self == other; })
653436c6c9cSStella Laurenzo .def("__eq__", [](PyAffineMap &self, py::object &other) { return false; })
654436c6c9cSStella Laurenzo .def("__str__",
655436c6c9cSStella Laurenzo [](PyAffineMap &self) {
656436c6c9cSStella Laurenzo PyPrintAccumulator printAccum;
657436c6c9cSStella Laurenzo mlirAffineMapPrint(self, printAccum.getCallback(),
658436c6c9cSStella Laurenzo printAccum.getUserData());
659436c6c9cSStella Laurenzo return printAccum.join();
660436c6c9cSStella Laurenzo })
661436c6c9cSStella Laurenzo .def("__repr__",
662436c6c9cSStella Laurenzo [](PyAffineMap &self) {
663436c6c9cSStella Laurenzo PyPrintAccumulator printAccum;
664436c6c9cSStella Laurenzo printAccum.parts.append("AffineMap(");
665436c6c9cSStella Laurenzo mlirAffineMapPrint(self, printAccum.getCallback(),
666436c6c9cSStella Laurenzo printAccum.getUserData());
667436c6c9cSStella Laurenzo printAccum.parts.append(")");
668436c6c9cSStella Laurenzo return printAccum.join();
669436c6c9cSStella Laurenzo })
670fc7594ccSAlex Zinenko .def("__hash__",
671fc7594ccSAlex Zinenko [](PyAffineMap &self) {
672fc7594ccSAlex Zinenko return static_cast<size_t>(llvm::hash_value(self.get().ptr));
673fc7594ccSAlex Zinenko })
674335d2df5SNicolas Vasilache .def_static("compress_unused_symbols",
675335d2df5SNicolas Vasilache [](py::list affineMaps, DefaultingPyMlirContext context) {
676335d2df5SNicolas Vasilache SmallVector<MlirAffineMap> maps;
677335d2df5SNicolas Vasilache pyListToVector<PyAffineMap, MlirAffineMap>(
678335d2df5SNicolas Vasilache affineMaps, maps, "attempting to create an AffineMap");
679335d2df5SNicolas Vasilache std::vector<MlirAffineMap> compressed(affineMaps.size());
680335d2df5SNicolas Vasilache auto populate = [](void *result, intptr_t idx,
681335d2df5SNicolas Vasilache MlirAffineMap m) {
682335d2df5SNicolas Vasilache static_cast<MlirAffineMap *>(result)[idx] = (m);
683335d2df5SNicolas Vasilache };
684335d2df5SNicolas Vasilache mlirAffineMapCompressUnusedSymbols(
685335d2df5SNicolas Vasilache maps.data(), maps.size(), compressed.data(), populate);
686335d2df5SNicolas Vasilache std::vector<PyAffineMap> res;
687e2f16be5SMehdi Amini res.reserve(compressed.size());
688335d2df5SNicolas Vasilache for (auto m : compressed)
689e5639b3fSMehdi Amini res.emplace_back(context->getRef(), m);
690335d2df5SNicolas Vasilache return res;
691335d2df5SNicolas Vasilache })
692436c6c9cSStella Laurenzo .def_property_readonly(
693436c6c9cSStella Laurenzo "context",
694436c6c9cSStella Laurenzo [](PyAffineMap &self) { return self.getContext().getObject(); },
695436c6c9cSStella Laurenzo "Context that owns the Affine Map")
696436c6c9cSStella Laurenzo .def(
697436c6c9cSStella Laurenzo "dump", [](PyAffineMap &self) { mlirAffineMapDump(self); },
698436c6c9cSStella Laurenzo kDumpDocstring)
699436c6c9cSStella Laurenzo .def_static(
700436c6c9cSStella Laurenzo "get",
701436c6c9cSStella Laurenzo [](intptr_t dimCount, intptr_t symbolCount, py::list exprs,
702436c6c9cSStella Laurenzo DefaultingPyMlirContext context) {
703436c6c9cSStella Laurenzo SmallVector<MlirAffineExpr> affineExprs;
704436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr, MlirAffineExpr>(
705337c937dSMehdi Amini exprs, affineExprs, "attempting to create an AffineMap");
706436c6c9cSStella Laurenzo MlirAffineMap map =
707436c6c9cSStella Laurenzo mlirAffineMapGet(context->get(), dimCount, symbolCount,
708436c6c9cSStella Laurenzo affineExprs.size(), affineExprs.data());
709436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), map);
710436c6c9cSStella Laurenzo },
711436c6c9cSStella Laurenzo py::arg("dim_count"), py::arg("symbol_count"), py::arg("exprs"),
712436c6c9cSStella Laurenzo py::arg("context") = py::none(),
713436c6c9cSStella Laurenzo "Gets a map with the given expressions as results.")
714436c6c9cSStella Laurenzo .def_static(
715436c6c9cSStella Laurenzo "get_constant",
716436c6c9cSStella Laurenzo [](intptr_t value, DefaultingPyMlirContext context) {
717436c6c9cSStella Laurenzo MlirAffineMap affineMap =
718436c6c9cSStella Laurenzo mlirAffineMapConstantGet(context->get(), value);
719436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap);
720436c6c9cSStella Laurenzo },
721436c6c9cSStella Laurenzo py::arg("value"), py::arg("context") = py::none(),
722436c6c9cSStella Laurenzo "Gets an affine map with a single constant result")
723436c6c9cSStella Laurenzo .def_static(
724436c6c9cSStella Laurenzo "get_empty",
725436c6c9cSStella Laurenzo [](DefaultingPyMlirContext context) {
726436c6c9cSStella Laurenzo MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get());
727436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap);
728436c6c9cSStella Laurenzo },
729436c6c9cSStella Laurenzo py::arg("context") = py::none(), "Gets an empty affine map.")
730436c6c9cSStella Laurenzo .def_static(
731436c6c9cSStella Laurenzo "get_identity",
732436c6c9cSStella Laurenzo [](intptr_t nDims, DefaultingPyMlirContext context) {
733436c6c9cSStella Laurenzo MlirAffineMap affineMap =
734436c6c9cSStella Laurenzo mlirAffineMapMultiDimIdentityGet(context->get(), nDims);
735436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap);
736436c6c9cSStella Laurenzo },
737436c6c9cSStella Laurenzo py::arg("n_dims"), py::arg("context") = py::none(),
738436c6c9cSStella Laurenzo "Gets an identity map with the given number of dimensions.")
739436c6c9cSStella Laurenzo .def_static(
740436c6c9cSStella Laurenzo "get_minor_identity",
741436c6c9cSStella Laurenzo [](intptr_t nDims, intptr_t nResults,
742436c6c9cSStella Laurenzo DefaultingPyMlirContext context) {
743436c6c9cSStella Laurenzo MlirAffineMap affineMap =
744436c6c9cSStella Laurenzo mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults);
745436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap);
746436c6c9cSStella Laurenzo },
747436c6c9cSStella Laurenzo py::arg("n_dims"), py::arg("n_results"),
748436c6c9cSStella Laurenzo py::arg("context") = py::none(),
749436c6c9cSStella Laurenzo "Gets a minor identity map with the given number of dimensions and "
750436c6c9cSStella Laurenzo "results.")
751436c6c9cSStella Laurenzo .def_static(
752436c6c9cSStella Laurenzo "get_permutation",
753436c6c9cSStella Laurenzo [](std::vector<unsigned> permutation,
754436c6c9cSStella Laurenzo DefaultingPyMlirContext context) {
755436c6c9cSStella Laurenzo if (!isPermutation(permutation))
756436c6c9cSStella Laurenzo throw py::cast_error("Invalid permutation when attempting to "
757436c6c9cSStella Laurenzo "create an AffineMap");
758436c6c9cSStella Laurenzo MlirAffineMap affineMap = mlirAffineMapPermutationGet(
759436c6c9cSStella Laurenzo context->get(), permutation.size(), permutation.data());
760436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap);
761436c6c9cSStella Laurenzo },
762436c6c9cSStella Laurenzo py::arg("permutation"), py::arg("context") = py::none(),
763436c6c9cSStella Laurenzo "Gets an affine map that permutes its inputs.")
764a6e7d024SStella Laurenzo .def(
765a6e7d024SStella Laurenzo "get_submap",
766436c6c9cSStella Laurenzo [](PyAffineMap &self, std::vector<intptr_t> &resultPos) {
767436c6c9cSStella Laurenzo intptr_t numResults = mlirAffineMapGetNumResults(self);
768436c6c9cSStella Laurenzo for (intptr_t pos : resultPos) {
769436c6c9cSStella Laurenzo if (pos < 0 || pos >= numResults)
770436c6c9cSStella Laurenzo throw py::value_error("result position out of bounds");
771436c6c9cSStella Laurenzo }
772436c6c9cSStella Laurenzo MlirAffineMap affineMap = mlirAffineMapGetSubMap(
773436c6c9cSStella Laurenzo self, resultPos.size(), resultPos.data());
774436c6c9cSStella Laurenzo return PyAffineMap(self.getContext(), affineMap);
775a6e7d024SStella Laurenzo },
776a6e7d024SStella Laurenzo py::arg("result_positions"))
777a6e7d024SStella Laurenzo .def(
778a6e7d024SStella Laurenzo "get_major_submap",
779436c6c9cSStella Laurenzo [](PyAffineMap &self, intptr_t nResults) {
780436c6c9cSStella Laurenzo if (nResults >= mlirAffineMapGetNumResults(self))
781436c6c9cSStella Laurenzo throw py::value_error("number of results out of bounds");
782436c6c9cSStella Laurenzo MlirAffineMap affineMap =
783436c6c9cSStella Laurenzo mlirAffineMapGetMajorSubMap(self, nResults);
784436c6c9cSStella Laurenzo return PyAffineMap(self.getContext(), affineMap);
785a6e7d024SStella Laurenzo },
786a6e7d024SStella Laurenzo py::arg("n_results"))
787a6e7d024SStella Laurenzo .def(
788a6e7d024SStella Laurenzo "get_minor_submap",
789436c6c9cSStella Laurenzo [](PyAffineMap &self, intptr_t nResults) {
790436c6c9cSStella Laurenzo if (nResults >= mlirAffineMapGetNumResults(self))
791436c6c9cSStella Laurenzo throw py::value_error("number of results out of bounds");
792436c6c9cSStella Laurenzo MlirAffineMap affineMap =
793436c6c9cSStella Laurenzo mlirAffineMapGetMinorSubMap(self, nResults);
794436c6c9cSStella Laurenzo return PyAffineMap(self.getContext(), affineMap);
795a6e7d024SStella Laurenzo },
796a6e7d024SStella Laurenzo py::arg("n_results"))
797a6e7d024SStella Laurenzo .def(
798a6e7d024SStella Laurenzo "replace",
79931f888eaSTobias Gysi [](PyAffineMap &self, PyAffineExpr &expression,
80031f888eaSTobias Gysi PyAffineExpr &replacement, intptr_t numResultDims,
80131f888eaSTobias Gysi intptr_t numResultSyms) {
80231f888eaSTobias Gysi MlirAffineMap affineMap = mlirAffineMapReplace(
80331f888eaSTobias Gysi self, expression, replacement, numResultDims, numResultSyms);
80431f888eaSTobias Gysi return PyAffineMap(self.getContext(), affineMap);
805a6e7d024SStella Laurenzo },
806a6e7d024SStella Laurenzo py::arg("expr"), py::arg("replacement"), py::arg("n_result_dims"),
807a6e7d024SStella Laurenzo py::arg("n_result_syms"))
808436c6c9cSStella Laurenzo .def_property_readonly(
809436c6c9cSStella Laurenzo "is_permutation",
810436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); })
811436c6c9cSStella Laurenzo .def_property_readonly("is_projected_permutation",
812436c6c9cSStella Laurenzo [](PyAffineMap &self) {
813436c6c9cSStella Laurenzo return mlirAffineMapIsProjectedPermutation(self);
814436c6c9cSStella Laurenzo })
815436c6c9cSStella Laurenzo .def_property_readonly(
816436c6c9cSStella Laurenzo "n_dims",
817436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); })
818436c6c9cSStella Laurenzo .def_property_readonly(
819436c6c9cSStella Laurenzo "n_inputs",
820436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); })
821436c6c9cSStella Laurenzo .def_property_readonly(
822436c6c9cSStella Laurenzo "n_symbols",
823436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); })
824436c6c9cSStella Laurenzo .def_property_readonly("results", [](PyAffineMap &self) {
825436c6c9cSStella Laurenzo return PyAffineMapExprList(self);
826436c6c9cSStella Laurenzo });
827436c6c9cSStella Laurenzo PyAffineMapExprList::bind(m);
828436c6c9cSStella Laurenzo
829436c6c9cSStella Laurenzo //----------------------------------------------------------------------------
830436c6c9cSStella Laurenzo // Mapping of PyIntegerSet.
831436c6c9cSStella Laurenzo //----------------------------------------------------------------------------
832f05ff4f7SStella Laurenzo py::class_<PyIntegerSet>(m, "IntegerSet", py::module_local())
833436c6c9cSStella Laurenzo .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
834436c6c9cSStella Laurenzo &PyIntegerSet::getCapsule)
835436c6c9cSStella Laurenzo .def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyIntegerSet::createFromCapsule)
836436c6c9cSStella Laurenzo .def("__eq__", [](PyIntegerSet &self,
837436c6c9cSStella Laurenzo PyIntegerSet &other) { return self == other; })
838436c6c9cSStella Laurenzo .def("__eq__", [](PyIntegerSet &self, py::object other) { return false; })
839436c6c9cSStella Laurenzo .def("__str__",
840436c6c9cSStella Laurenzo [](PyIntegerSet &self) {
841436c6c9cSStella Laurenzo PyPrintAccumulator printAccum;
842436c6c9cSStella Laurenzo mlirIntegerSetPrint(self, printAccum.getCallback(),
843436c6c9cSStella Laurenzo printAccum.getUserData());
844436c6c9cSStella Laurenzo return printAccum.join();
845436c6c9cSStella Laurenzo })
846436c6c9cSStella Laurenzo .def("__repr__",
847436c6c9cSStella Laurenzo [](PyIntegerSet &self) {
848436c6c9cSStella Laurenzo PyPrintAccumulator printAccum;
849436c6c9cSStella Laurenzo printAccum.parts.append("IntegerSet(");
850436c6c9cSStella Laurenzo mlirIntegerSetPrint(self, printAccum.getCallback(),
851436c6c9cSStella Laurenzo printAccum.getUserData());
852436c6c9cSStella Laurenzo printAccum.parts.append(")");
853436c6c9cSStella Laurenzo return printAccum.join();
854436c6c9cSStella Laurenzo })
855fc7594ccSAlex Zinenko .def("__hash__",
856fc7594ccSAlex Zinenko [](PyIntegerSet &self) {
857fc7594ccSAlex Zinenko return static_cast<size_t>(llvm::hash_value(self.get().ptr));
858fc7594ccSAlex Zinenko })
859436c6c9cSStella Laurenzo .def_property_readonly(
860436c6c9cSStella Laurenzo "context",
861436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return self.getContext().getObject(); })
862436c6c9cSStella Laurenzo .def(
863436c6c9cSStella Laurenzo "dump", [](PyIntegerSet &self) { mlirIntegerSetDump(self); },
864436c6c9cSStella Laurenzo kDumpDocstring)
865436c6c9cSStella Laurenzo .def_static(
866436c6c9cSStella Laurenzo "get",
867436c6c9cSStella Laurenzo [](intptr_t numDims, intptr_t numSymbols, py::list exprs,
868436c6c9cSStella Laurenzo std::vector<bool> eqFlags, DefaultingPyMlirContext context) {
869436c6c9cSStella Laurenzo if (exprs.size() != eqFlags.size())
870436c6c9cSStella Laurenzo throw py::value_error(
871436c6c9cSStella Laurenzo "Expected the number of constraints to match "
872436c6c9cSStella Laurenzo "that of equality flags");
873436c6c9cSStella Laurenzo if (exprs.empty())
874436c6c9cSStella Laurenzo throw py::value_error("Expected non-empty list of constraints");
875436c6c9cSStella Laurenzo
876436c6c9cSStella Laurenzo // Copy over to a SmallVector because std::vector has a
877436c6c9cSStella Laurenzo // specialization for booleans that packs data and does not
878436c6c9cSStella Laurenzo // expose a `bool *`.
879436c6c9cSStella Laurenzo SmallVector<bool, 8> flags(eqFlags.begin(), eqFlags.end());
880436c6c9cSStella Laurenzo
881436c6c9cSStella Laurenzo SmallVector<MlirAffineExpr> affineExprs;
882436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr>(exprs, affineExprs,
883436c6c9cSStella Laurenzo "attempting to create an IntegerSet");
884436c6c9cSStella Laurenzo MlirIntegerSet set = mlirIntegerSetGet(
885436c6c9cSStella Laurenzo context->get(), numDims, numSymbols, exprs.size(),
886436c6c9cSStella Laurenzo affineExprs.data(), flags.data());
887436c6c9cSStella Laurenzo return PyIntegerSet(context->getRef(), set);
888436c6c9cSStella Laurenzo },
889436c6c9cSStella Laurenzo py::arg("num_dims"), py::arg("num_symbols"), py::arg("exprs"),
890436c6c9cSStella Laurenzo py::arg("eq_flags"), py::arg("context") = py::none())
891436c6c9cSStella Laurenzo .def_static(
892436c6c9cSStella Laurenzo "get_empty",
893436c6c9cSStella Laurenzo [](intptr_t numDims, intptr_t numSymbols,
894436c6c9cSStella Laurenzo DefaultingPyMlirContext context) {
895436c6c9cSStella Laurenzo MlirIntegerSet set =
896436c6c9cSStella Laurenzo mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols);
897436c6c9cSStella Laurenzo return PyIntegerSet(context->getRef(), set);
898436c6c9cSStella Laurenzo },
899436c6c9cSStella Laurenzo py::arg("num_dims"), py::arg("num_symbols"),
900436c6c9cSStella Laurenzo py::arg("context") = py::none())
901a6e7d024SStella Laurenzo .def(
902a6e7d024SStella Laurenzo "get_replaced",
903436c6c9cSStella Laurenzo [](PyIntegerSet &self, py::list dimExprs, py::list symbolExprs,
904436c6c9cSStella Laurenzo intptr_t numResultDims, intptr_t numResultSymbols) {
905436c6c9cSStella Laurenzo if (static_cast<intptr_t>(dimExprs.size()) !=
906436c6c9cSStella Laurenzo mlirIntegerSetGetNumDims(self))
907436c6c9cSStella Laurenzo throw py::value_error(
908436c6c9cSStella Laurenzo "Expected the number of dimension replacement expressions "
909436c6c9cSStella Laurenzo "to match that of dimensions");
910436c6c9cSStella Laurenzo if (static_cast<intptr_t>(symbolExprs.size()) !=
911436c6c9cSStella Laurenzo mlirIntegerSetGetNumSymbols(self))
912436c6c9cSStella Laurenzo throw py::value_error(
913436c6c9cSStella Laurenzo "Expected the number of symbol replacement expressions "
914436c6c9cSStella Laurenzo "to match that of symbols");
915436c6c9cSStella Laurenzo
916436c6c9cSStella Laurenzo SmallVector<MlirAffineExpr> dimAffineExprs, symbolAffineExprs;
917436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr>(
918436c6c9cSStella Laurenzo dimExprs, dimAffineExprs,
919436c6c9cSStella Laurenzo "attempting to create an IntegerSet by replacing dimensions");
920436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr>(
921436c6c9cSStella Laurenzo symbolExprs, symbolAffineExprs,
922436c6c9cSStella Laurenzo "attempting to create an IntegerSet by replacing symbols");
923436c6c9cSStella Laurenzo MlirIntegerSet set = mlirIntegerSetReplaceGet(
924436c6c9cSStella Laurenzo self, dimAffineExprs.data(), symbolAffineExprs.data(),
925436c6c9cSStella Laurenzo numResultDims, numResultSymbols);
926436c6c9cSStella Laurenzo return PyIntegerSet(self.getContext(), set);
927a6e7d024SStella Laurenzo },
928a6e7d024SStella Laurenzo py::arg("dim_exprs"), py::arg("symbol_exprs"),
929a6e7d024SStella Laurenzo py::arg("num_result_dims"), py::arg("num_result_symbols"))
930436c6c9cSStella Laurenzo .def_property_readonly("is_canonical_empty",
931436c6c9cSStella Laurenzo [](PyIntegerSet &self) {
932436c6c9cSStella Laurenzo return mlirIntegerSetIsCanonicalEmpty(self);
933436c6c9cSStella Laurenzo })
934436c6c9cSStella Laurenzo .def_property_readonly(
935436c6c9cSStella Laurenzo "n_dims",
936436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); })
937436c6c9cSStella Laurenzo .def_property_readonly(
938436c6c9cSStella Laurenzo "n_symbols",
939436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); })
940436c6c9cSStella Laurenzo .def_property_readonly(
941436c6c9cSStella Laurenzo "n_inputs",
942436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); })
943436c6c9cSStella Laurenzo .def_property_readonly("n_equalities",
944436c6c9cSStella Laurenzo [](PyIntegerSet &self) {
945436c6c9cSStella Laurenzo return mlirIntegerSetGetNumEqualities(self);
946436c6c9cSStella Laurenzo })
947436c6c9cSStella Laurenzo .def_property_readonly("n_inequalities",
948436c6c9cSStella Laurenzo [](PyIntegerSet &self) {
949436c6c9cSStella Laurenzo return mlirIntegerSetGetNumInequalities(self);
950436c6c9cSStella Laurenzo })
951436c6c9cSStella Laurenzo .def_property_readonly("constraints", [](PyIntegerSet &self) {
952436c6c9cSStella Laurenzo return PyIntegerSetConstraintList(self);
953436c6c9cSStella Laurenzo });
954436c6c9cSStella Laurenzo PyIntegerSetConstraint::bind(m);
955436c6c9cSStella Laurenzo PyIntegerSetConstraintList::bind(m);
956436c6c9cSStella Laurenzo }
957