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 9*1fc096afSMehdi Amini #include <utility> 10*1fc096afSMehdi 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> 35*1fc096afSMehdi Amini static void pyListToVector(const py::list &list, 36*1fc096afSMehdi 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> 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; 87436c6c9cSStella Laurenzo PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr) 88436c6c9cSStella Laurenzo : BaseTy(std::move(contextRef), affineExpr) {} 89436c6c9cSStella Laurenzo PyConcreteAffineExpr(PyAffineExpr &orig) 90436c6c9cSStella Laurenzo : PyConcreteAffineExpr(orig.getContext(), castFrom(orig)) {} 91436c6c9cSStella Laurenzo 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 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. 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 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 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 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 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 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 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 186436c6c9cSStella Laurenzo PyAffineExpr lhs() { 187436c6c9cSStella Laurenzo MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get()); 188436c6c9cSStella Laurenzo return PyAffineExpr(getContext(), lhsExpr); 189436c6c9cSStella Laurenzo } 190436c6c9cSStella Laurenzo 191436c6c9cSStella Laurenzo PyAffineExpr rhs() { 192436c6c9cSStella Laurenzo MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get()); 193436c6c9cSStella Laurenzo return PyAffineExpr(getContext(), rhsExpr); 194436c6c9cSStella Laurenzo } 195436c6c9cSStella Laurenzo 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 209*1fc096afSMehdi 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 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 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 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 238*1fc096afSMehdi 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 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 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 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 267*1fc096afSMehdi 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 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 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 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 296*1fc096afSMehdi 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 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 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 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 325*1fc096afSMehdi 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 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 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 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 349436c6c9cSStella Laurenzo bool PyAffineExpr::operator==(const PyAffineExpr &other) { 350436c6c9cSStella Laurenzo return mlirAffineExprEqual(affineExpr, other.affineExpr); 351436c6c9cSStella Laurenzo } 352436c6c9cSStella Laurenzo 353436c6c9cSStella Laurenzo py::object PyAffineExpr::getCapsule() { 354436c6c9cSStella Laurenzo return py::reinterpret_steal<py::object>( 355436c6c9cSStella Laurenzo mlirPythonAffineExprToCapsule(*this)); 356436c6c9cSStella Laurenzo } 357436c6c9cSStella Laurenzo 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 381*1fc096afSMehdi 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 388436c6c9cSStella Laurenzo intptr_t getNumElements() { return mlirAffineMapGetNumResults(affineMap); } 389436c6c9cSStella Laurenzo 390436c6c9cSStella Laurenzo PyAffineExpr getElement(intptr_t pos) { 391436c6c9cSStella Laurenzo return PyAffineExpr(affineMap.getContext(), 392436c6c9cSStella Laurenzo mlirAffineMapGetResult(affineMap, pos)); 393436c6c9cSStella Laurenzo } 394436c6c9cSStella Laurenzo 395436c6c9cSStella Laurenzo PyAffineMapExprList slice(intptr_t startIndex, intptr_t length, 396436c6c9cSStella Laurenzo intptr_t step) { 397436c6c9cSStella Laurenzo return PyAffineMapExprList(affineMap, startIndex, length, step); 398436c6c9cSStella Laurenzo } 399436c6c9cSStella Laurenzo 400436c6c9cSStella Laurenzo private: 401436c6c9cSStella Laurenzo PyAffineMap affineMap; 402436c6c9cSStella Laurenzo }; 403be0a7e9fSMehdi Amini } // namespace 404436c6c9cSStella Laurenzo 405436c6c9cSStella Laurenzo bool PyAffineMap::operator==(const PyAffineMap &other) { 406436c6c9cSStella Laurenzo return mlirAffineMapEqual(affineMap, other.affineMap); 407436c6c9cSStella Laurenzo } 408436c6c9cSStella Laurenzo 409436c6c9cSStella Laurenzo py::object PyAffineMap::getCapsule() { 410436c6c9cSStella Laurenzo return py::reinterpret_steal<py::object>(mlirPythonAffineMapToCapsule(*this)); 411436c6c9cSStella Laurenzo } 412436c6c9cSStella Laurenzo 413436c6c9cSStella Laurenzo PyAffineMap PyAffineMap::createFromCapsule(py::object capsule) { 414436c6c9cSStella Laurenzo MlirAffineMap rawAffineMap = mlirPythonCapsuleToAffineMap(capsule.ptr()); 415436c6c9cSStella Laurenzo if (mlirAffineMapIsNull(rawAffineMap)) 416436c6c9cSStella Laurenzo throw py::error_already_set(); 417436c6c9cSStella Laurenzo return PyAffineMap( 418436c6c9cSStella Laurenzo PyMlirContext::forContext(mlirAffineMapGetContext(rawAffineMap)), 419436c6c9cSStella Laurenzo rawAffineMap); 420436c6c9cSStella Laurenzo } 421436c6c9cSStella Laurenzo 422436c6c9cSStella Laurenzo //------------------------------------------------------------------------------ 423436c6c9cSStella Laurenzo // PyIntegerSet and utilities. 424436c6c9cSStella Laurenzo //------------------------------------------------------------------------------ 425436c6c9cSStella Laurenzo namespace { 426436c6c9cSStella Laurenzo 427436c6c9cSStella Laurenzo class PyIntegerSetConstraint { 428436c6c9cSStella Laurenzo public: 429*1fc096afSMehdi Amini PyIntegerSetConstraint(PyIntegerSet set, intptr_t pos) 430*1fc096afSMehdi Amini : set(std::move(set)), pos(pos) {} 431436c6c9cSStella Laurenzo 432436c6c9cSStella Laurenzo PyAffineExpr getExpr() { 433436c6c9cSStella Laurenzo return PyAffineExpr(set.getContext(), 434436c6c9cSStella Laurenzo mlirIntegerSetGetConstraint(set, pos)); 435436c6c9cSStella Laurenzo } 436436c6c9cSStella Laurenzo 437436c6c9cSStella Laurenzo bool isEq() { return mlirIntegerSetIsConstraintEq(set, pos); } 438436c6c9cSStella Laurenzo 439436c6c9cSStella Laurenzo static void bind(py::module &m) { 440f05ff4f7SStella Laurenzo py::class_<PyIntegerSetConstraint>(m, "IntegerSetConstraint", 441f05ff4f7SStella Laurenzo py::module_local()) 442436c6c9cSStella Laurenzo .def_property_readonly("expr", &PyIntegerSetConstraint::getExpr) 443436c6c9cSStella Laurenzo .def_property_readonly("is_eq", &PyIntegerSetConstraint::isEq); 444436c6c9cSStella Laurenzo } 445436c6c9cSStella Laurenzo 446436c6c9cSStella Laurenzo private: 447436c6c9cSStella Laurenzo PyIntegerSet set; 448436c6c9cSStella Laurenzo intptr_t pos; 449436c6c9cSStella Laurenzo }; 450436c6c9cSStella Laurenzo 451436c6c9cSStella Laurenzo class PyIntegerSetConstraintList 452436c6c9cSStella Laurenzo : public Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint> { 453436c6c9cSStella Laurenzo public: 454436c6c9cSStella Laurenzo static constexpr const char *pyClassName = "IntegerSetConstraintList"; 455436c6c9cSStella Laurenzo 456*1fc096afSMehdi Amini PyIntegerSetConstraintList(const PyIntegerSet &set, intptr_t startIndex = 0, 457436c6c9cSStella Laurenzo intptr_t length = -1, intptr_t step = 1) 458436c6c9cSStella Laurenzo : Sliceable(startIndex, 459436c6c9cSStella Laurenzo length == -1 ? mlirIntegerSetGetNumConstraints(set) : length, 460436c6c9cSStella Laurenzo step), 461436c6c9cSStella Laurenzo set(set) {} 462436c6c9cSStella Laurenzo 463436c6c9cSStella Laurenzo intptr_t getNumElements() { return mlirIntegerSetGetNumConstraints(set); } 464436c6c9cSStella Laurenzo 465436c6c9cSStella Laurenzo PyIntegerSetConstraint getElement(intptr_t pos) { 466436c6c9cSStella Laurenzo return PyIntegerSetConstraint(set, pos); 467436c6c9cSStella Laurenzo } 468436c6c9cSStella Laurenzo 469436c6c9cSStella Laurenzo PyIntegerSetConstraintList slice(intptr_t startIndex, intptr_t length, 470436c6c9cSStella Laurenzo intptr_t step) { 471436c6c9cSStella Laurenzo return PyIntegerSetConstraintList(set, startIndex, length, step); 472436c6c9cSStella Laurenzo } 473436c6c9cSStella Laurenzo 474436c6c9cSStella Laurenzo private: 475436c6c9cSStella Laurenzo PyIntegerSet set; 476436c6c9cSStella Laurenzo }; 477436c6c9cSStella Laurenzo } // namespace 478436c6c9cSStella Laurenzo 479436c6c9cSStella Laurenzo bool PyIntegerSet::operator==(const PyIntegerSet &other) { 480436c6c9cSStella Laurenzo return mlirIntegerSetEqual(integerSet, other.integerSet); 481436c6c9cSStella Laurenzo } 482436c6c9cSStella Laurenzo 483436c6c9cSStella Laurenzo py::object PyIntegerSet::getCapsule() { 484436c6c9cSStella Laurenzo return py::reinterpret_steal<py::object>( 485436c6c9cSStella Laurenzo mlirPythonIntegerSetToCapsule(*this)); 486436c6c9cSStella Laurenzo } 487436c6c9cSStella Laurenzo 488436c6c9cSStella Laurenzo PyIntegerSet PyIntegerSet::createFromCapsule(py::object capsule) { 489436c6c9cSStella Laurenzo MlirIntegerSet rawIntegerSet = mlirPythonCapsuleToIntegerSet(capsule.ptr()); 490436c6c9cSStella Laurenzo if (mlirIntegerSetIsNull(rawIntegerSet)) 491436c6c9cSStella Laurenzo throw py::error_already_set(); 492436c6c9cSStella Laurenzo return PyIntegerSet( 493436c6c9cSStella Laurenzo PyMlirContext::forContext(mlirIntegerSetGetContext(rawIntegerSet)), 494436c6c9cSStella Laurenzo rawIntegerSet); 495436c6c9cSStella Laurenzo } 496436c6c9cSStella Laurenzo 497436c6c9cSStella Laurenzo void mlir::python::populateIRAffine(py::module &m) { 498436c6c9cSStella Laurenzo //---------------------------------------------------------------------------- 499436c6c9cSStella Laurenzo // Mapping of PyAffineExpr and derived classes. 500436c6c9cSStella Laurenzo //---------------------------------------------------------------------------- 501f05ff4f7SStella Laurenzo py::class_<PyAffineExpr>(m, "AffineExpr", py::module_local()) 502436c6c9cSStella Laurenzo .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR, 503436c6c9cSStella Laurenzo &PyAffineExpr::getCapsule) 504436c6c9cSStella Laurenzo .def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAffineExpr::createFromCapsule) 505fc7594ccSAlex Zinenko .def("__add__", &PyAffineAddExpr::get) 506fc7594ccSAlex Zinenko .def("__add__", &PyAffineAddExpr::getRHSConstant) 507fc7594ccSAlex Zinenko .def("__radd__", &PyAffineAddExpr::getRHSConstant) 508fc7594ccSAlex Zinenko .def("__mul__", &PyAffineMulExpr::get) 509fc7594ccSAlex Zinenko .def("__mul__", &PyAffineMulExpr::getRHSConstant) 510fc7594ccSAlex Zinenko .def("__rmul__", &PyAffineMulExpr::getRHSConstant) 511fc7594ccSAlex Zinenko .def("__mod__", &PyAffineModExpr::get) 512fc7594ccSAlex Zinenko .def("__mod__", &PyAffineModExpr::getRHSConstant) 513fc7594ccSAlex Zinenko .def("__rmod__", 514fc7594ccSAlex Zinenko [](PyAffineExpr &self, intptr_t other) { 515fc7594ccSAlex Zinenko return PyAffineModExpr::get( 516fc7594ccSAlex Zinenko PyAffineConstantExpr::get(other, *self.getContext().get()), 517fc7594ccSAlex Zinenko self); 518436c6c9cSStella Laurenzo }) 519436c6c9cSStella Laurenzo .def("__sub__", 520436c6c9cSStella Laurenzo [](PyAffineExpr &self, PyAffineExpr &other) { 521436c6c9cSStella Laurenzo auto negOne = 522436c6c9cSStella Laurenzo PyAffineConstantExpr::get(-1, *self.getContext().get()); 523436c6c9cSStella Laurenzo return PyAffineAddExpr::get(self, 524436c6c9cSStella Laurenzo PyAffineMulExpr::get(negOne, other)); 525436c6c9cSStella Laurenzo }) 526fc7594ccSAlex Zinenko .def("__sub__", 527fc7594ccSAlex Zinenko [](PyAffineExpr &self, intptr_t other) { 528fc7594ccSAlex Zinenko return PyAffineAddExpr::get( 529fc7594ccSAlex Zinenko self, 530fc7594ccSAlex Zinenko PyAffineConstantExpr::get(-other, *self.getContext().get())); 531fc7594ccSAlex Zinenko }) 532fc7594ccSAlex Zinenko .def("__rsub__", 533fc7594ccSAlex Zinenko [](PyAffineExpr &self, intptr_t other) { 534fc7594ccSAlex Zinenko return PyAffineAddExpr::getLHSConstant( 535fc7594ccSAlex Zinenko other, PyAffineMulExpr::getLHSConstant(-1, self)); 536fc7594ccSAlex Zinenko }) 537436c6c9cSStella Laurenzo .def("__eq__", [](PyAffineExpr &self, 538436c6c9cSStella Laurenzo PyAffineExpr &other) { return self == other; }) 539436c6c9cSStella Laurenzo .def("__eq__", 540436c6c9cSStella Laurenzo [](PyAffineExpr &self, py::object &other) { return false; }) 541436c6c9cSStella Laurenzo .def("__str__", 542436c6c9cSStella Laurenzo [](PyAffineExpr &self) { 543436c6c9cSStella Laurenzo PyPrintAccumulator printAccum; 544436c6c9cSStella Laurenzo mlirAffineExprPrint(self, printAccum.getCallback(), 545436c6c9cSStella Laurenzo printAccum.getUserData()); 546436c6c9cSStella Laurenzo return printAccum.join(); 547436c6c9cSStella Laurenzo }) 548436c6c9cSStella Laurenzo .def("__repr__", 549436c6c9cSStella Laurenzo [](PyAffineExpr &self) { 550436c6c9cSStella Laurenzo PyPrintAccumulator printAccum; 551436c6c9cSStella Laurenzo printAccum.parts.append("AffineExpr("); 552436c6c9cSStella Laurenzo mlirAffineExprPrint(self, printAccum.getCallback(), 553436c6c9cSStella Laurenzo printAccum.getUserData()); 554436c6c9cSStella Laurenzo printAccum.parts.append(")"); 555436c6c9cSStella Laurenzo return printAccum.join(); 556436c6c9cSStella Laurenzo }) 557fc7594ccSAlex Zinenko .def("__hash__", 558fc7594ccSAlex Zinenko [](PyAffineExpr &self) { 559fc7594ccSAlex Zinenko return static_cast<size_t>(llvm::hash_value(self.get().ptr)); 560fc7594ccSAlex Zinenko }) 561436c6c9cSStella Laurenzo .def_property_readonly( 562436c6c9cSStella Laurenzo "context", 563436c6c9cSStella Laurenzo [](PyAffineExpr &self) { return self.getContext().getObject(); }) 564fc7594ccSAlex Zinenko .def("compose", 565fc7594ccSAlex Zinenko [](PyAffineExpr &self, PyAffineMap &other) { 566fc7594ccSAlex Zinenko return PyAffineExpr(self.getContext(), 567fc7594ccSAlex Zinenko mlirAffineExprCompose(self, other)); 568fc7594ccSAlex Zinenko }) 569436c6c9cSStella Laurenzo .def_static( 570436c6c9cSStella Laurenzo "get_add", &PyAffineAddExpr::get, 571436c6c9cSStella Laurenzo "Gets an affine expression containing a sum of two expressions.") 572fc7594ccSAlex Zinenko .def_static("get_add", &PyAffineAddExpr::getLHSConstant, 573fc7594ccSAlex Zinenko "Gets an affine expression containing a sum of a constant " 574fc7594ccSAlex Zinenko "and another expression.") 575fc7594ccSAlex Zinenko .def_static("get_add", &PyAffineAddExpr::getRHSConstant, 576fc7594ccSAlex Zinenko "Gets an affine expression containing a sum of an expression " 577fc7594ccSAlex Zinenko "and a constant.") 578436c6c9cSStella Laurenzo .def_static( 579436c6c9cSStella Laurenzo "get_mul", &PyAffineMulExpr::get, 580436c6c9cSStella Laurenzo "Gets an affine expression containing a product of two expressions.") 581fc7594ccSAlex Zinenko .def_static("get_mul", &PyAffineMulExpr::getLHSConstant, 582fc7594ccSAlex Zinenko "Gets an affine expression containing a product of a " 583fc7594ccSAlex Zinenko "constant and another expression.") 584fc7594ccSAlex Zinenko .def_static("get_mul", &PyAffineMulExpr::getRHSConstant, 585fc7594ccSAlex Zinenko "Gets an affine expression containing a product of an " 586fc7594ccSAlex Zinenko "expression and a constant.") 587436c6c9cSStella Laurenzo .def_static("get_mod", &PyAffineModExpr::get, 588436c6c9cSStella Laurenzo "Gets an affine expression containing the modulo of dividing " 589436c6c9cSStella Laurenzo "one expression by another.") 590fc7594ccSAlex Zinenko .def_static("get_mod", &PyAffineModExpr::getLHSConstant, 591fc7594ccSAlex Zinenko "Gets a semi-affine expression containing the modulo of " 592fc7594ccSAlex Zinenko "dividing a constant by an expression.") 593fc7594ccSAlex Zinenko .def_static("get_mod", &PyAffineModExpr::getRHSConstant, 594fc7594ccSAlex Zinenko "Gets an affine expression containing the module of dividing" 595fc7594ccSAlex Zinenko "an expression by a constant.") 596436c6c9cSStella Laurenzo .def_static("get_floor_div", &PyAffineFloorDivExpr::get, 597436c6c9cSStella Laurenzo "Gets an affine expression containing the rounded-down " 598436c6c9cSStella Laurenzo "result of dividing one expression by another.") 599fc7594ccSAlex Zinenko .def_static("get_floor_div", &PyAffineFloorDivExpr::getLHSConstant, 600fc7594ccSAlex Zinenko "Gets a semi-affine expression containing the rounded-down " 601fc7594ccSAlex Zinenko "result of dividing a constant by an expression.") 602fc7594ccSAlex Zinenko .def_static("get_floor_div", &PyAffineFloorDivExpr::getRHSConstant, 603fc7594ccSAlex Zinenko "Gets an affine expression containing the rounded-down " 604fc7594ccSAlex Zinenko "result of dividing an expression by a constant.") 605436c6c9cSStella Laurenzo .def_static("get_ceil_div", &PyAffineCeilDivExpr::get, 606436c6c9cSStella Laurenzo "Gets an affine expression containing the rounded-up result " 607436c6c9cSStella Laurenzo "of dividing one expression by another.") 608fc7594ccSAlex Zinenko .def_static("get_ceil_div", &PyAffineCeilDivExpr::getLHSConstant, 609fc7594ccSAlex Zinenko "Gets a semi-affine expression containing the rounded-up " 610fc7594ccSAlex Zinenko "result of dividing a constant by an expression.") 611fc7594ccSAlex Zinenko .def_static("get_ceil_div", &PyAffineCeilDivExpr::getRHSConstant, 612fc7594ccSAlex Zinenko "Gets an affine expression containing the rounded-up result " 613fc7594ccSAlex Zinenko "of dividing an expression by a constant.") 614436c6c9cSStella Laurenzo .def_static("get_constant", &PyAffineConstantExpr::get, py::arg("value"), 615436c6c9cSStella Laurenzo py::arg("context") = py::none(), 616436c6c9cSStella Laurenzo "Gets a constant affine expression with the given value.") 617436c6c9cSStella Laurenzo .def_static( 618436c6c9cSStella Laurenzo "get_dim", &PyAffineDimExpr::get, py::arg("position"), 619436c6c9cSStella Laurenzo py::arg("context") = py::none(), 620436c6c9cSStella Laurenzo "Gets an affine expression of a dimension at the given position.") 621436c6c9cSStella Laurenzo .def_static( 622436c6c9cSStella Laurenzo "get_symbol", &PyAffineSymbolExpr::get, py::arg("position"), 623436c6c9cSStella Laurenzo py::arg("context") = py::none(), 624436c6c9cSStella Laurenzo "Gets an affine expression of a symbol at the given position.") 625436c6c9cSStella Laurenzo .def( 626436c6c9cSStella Laurenzo "dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); }, 627436c6c9cSStella Laurenzo kDumpDocstring); 628436c6c9cSStella Laurenzo PyAffineConstantExpr::bind(m); 629436c6c9cSStella Laurenzo PyAffineDimExpr::bind(m); 630436c6c9cSStella Laurenzo PyAffineSymbolExpr::bind(m); 631436c6c9cSStella Laurenzo PyAffineBinaryExpr::bind(m); 632436c6c9cSStella Laurenzo PyAffineAddExpr::bind(m); 633436c6c9cSStella Laurenzo PyAffineMulExpr::bind(m); 634436c6c9cSStella Laurenzo PyAffineModExpr::bind(m); 635436c6c9cSStella Laurenzo PyAffineFloorDivExpr::bind(m); 636436c6c9cSStella Laurenzo PyAffineCeilDivExpr::bind(m); 637436c6c9cSStella Laurenzo 638436c6c9cSStella Laurenzo //---------------------------------------------------------------------------- 639436c6c9cSStella Laurenzo // Mapping of PyAffineMap. 640436c6c9cSStella Laurenzo //---------------------------------------------------------------------------- 641f05ff4f7SStella Laurenzo py::class_<PyAffineMap>(m, "AffineMap", py::module_local()) 642436c6c9cSStella Laurenzo .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR, 643436c6c9cSStella Laurenzo &PyAffineMap::getCapsule) 644436c6c9cSStella Laurenzo .def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyAffineMap::createFromCapsule) 645436c6c9cSStella Laurenzo .def("__eq__", 646436c6c9cSStella Laurenzo [](PyAffineMap &self, PyAffineMap &other) { return self == other; }) 647436c6c9cSStella Laurenzo .def("__eq__", [](PyAffineMap &self, py::object &other) { return false; }) 648436c6c9cSStella Laurenzo .def("__str__", 649436c6c9cSStella Laurenzo [](PyAffineMap &self) { 650436c6c9cSStella Laurenzo PyPrintAccumulator printAccum; 651436c6c9cSStella Laurenzo mlirAffineMapPrint(self, printAccum.getCallback(), 652436c6c9cSStella Laurenzo printAccum.getUserData()); 653436c6c9cSStella Laurenzo return printAccum.join(); 654436c6c9cSStella Laurenzo }) 655436c6c9cSStella Laurenzo .def("__repr__", 656436c6c9cSStella Laurenzo [](PyAffineMap &self) { 657436c6c9cSStella Laurenzo PyPrintAccumulator printAccum; 658436c6c9cSStella Laurenzo printAccum.parts.append("AffineMap("); 659436c6c9cSStella Laurenzo mlirAffineMapPrint(self, printAccum.getCallback(), 660436c6c9cSStella Laurenzo printAccum.getUserData()); 661436c6c9cSStella Laurenzo printAccum.parts.append(")"); 662436c6c9cSStella Laurenzo return printAccum.join(); 663436c6c9cSStella Laurenzo }) 664fc7594ccSAlex Zinenko .def("__hash__", 665fc7594ccSAlex Zinenko [](PyAffineMap &self) { 666fc7594ccSAlex Zinenko return static_cast<size_t>(llvm::hash_value(self.get().ptr)); 667fc7594ccSAlex Zinenko }) 668335d2df5SNicolas Vasilache .def_static("compress_unused_symbols", 669335d2df5SNicolas Vasilache [](py::list affineMaps, DefaultingPyMlirContext context) { 670335d2df5SNicolas Vasilache SmallVector<MlirAffineMap> maps; 671335d2df5SNicolas Vasilache pyListToVector<PyAffineMap, MlirAffineMap>( 672335d2df5SNicolas Vasilache affineMaps, maps, "attempting to create an AffineMap"); 673335d2df5SNicolas Vasilache std::vector<MlirAffineMap> compressed(affineMaps.size()); 674335d2df5SNicolas Vasilache auto populate = [](void *result, intptr_t idx, 675335d2df5SNicolas Vasilache MlirAffineMap m) { 676335d2df5SNicolas Vasilache static_cast<MlirAffineMap *>(result)[idx] = (m); 677335d2df5SNicolas Vasilache }; 678335d2df5SNicolas Vasilache mlirAffineMapCompressUnusedSymbols( 679335d2df5SNicolas Vasilache maps.data(), maps.size(), compressed.data(), populate); 680335d2df5SNicolas Vasilache std::vector<PyAffineMap> res; 681e2f16be5SMehdi Amini res.reserve(compressed.size()); 682335d2df5SNicolas Vasilache for (auto m : compressed) 683e5639b3fSMehdi Amini res.emplace_back(context->getRef(), m); 684335d2df5SNicolas Vasilache return res; 685335d2df5SNicolas Vasilache }) 686436c6c9cSStella Laurenzo .def_property_readonly( 687436c6c9cSStella Laurenzo "context", 688436c6c9cSStella Laurenzo [](PyAffineMap &self) { return self.getContext().getObject(); }, 689436c6c9cSStella Laurenzo "Context that owns the Affine Map") 690436c6c9cSStella Laurenzo .def( 691436c6c9cSStella Laurenzo "dump", [](PyAffineMap &self) { mlirAffineMapDump(self); }, 692436c6c9cSStella Laurenzo kDumpDocstring) 693436c6c9cSStella Laurenzo .def_static( 694436c6c9cSStella Laurenzo "get", 695436c6c9cSStella Laurenzo [](intptr_t dimCount, intptr_t symbolCount, py::list exprs, 696436c6c9cSStella Laurenzo DefaultingPyMlirContext context) { 697436c6c9cSStella Laurenzo SmallVector<MlirAffineExpr> affineExprs; 698436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr, MlirAffineExpr>( 699*1fc096afSMehdi Amini std::move(exprs), affineExprs, 700*1fc096afSMehdi Amini "attempting to create an AffineMap"); 701436c6c9cSStella Laurenzo MlirAffineMap map = 702436c6c9cSStella Laurenzo mlirAffineMapGet(context->get(), dimCount, symbolCount, 703436c6c9cSStella Laurenzo affineExprs.size(), affineExprs.data()); 704436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), map); 705436c6c9cSStella Laurenzo }, 706436c6c9cSStella Laurenzo py::arg("dim_count"), py::arg("symbol_count"), py::arg("exprs"), 707436c6c9cSStella Laurenzo py::arg("context") = py::none(), 708436c6c9cSStella Laurenzo "Gets a map with the given expressions as results.") 709436c6c9cSStella Laurenzo .def_static( 710436c6c9cSStella Laurenzo "get_constant", 711436c6c9cSStella Laurenzo [](intptr_t value, DefaultingPyMlirContext context) { 712436c6c9cSStella Laurenzo MlirAffineMap affineMap = 713436c6c9cSStella Laurenzo mlirAffineMapConstantGet(context->get(), value); 714436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap); 715436c6c9cSStella Laurenzo }, 716436c6c9cSStella Laurenzo py::arg("value"), py::arg("context") = py::none(), 717436c6c9cSStella Laurenzo "Gets an affine map with a single constant result") 718436c6c9cSStella Laurenzo .def_static( 719436c6c9cSStella Laurenzo "get_empty", 720436c6c9cSStella Laurenzo [](DefaultingPyMlirContext context) { 721436c6c9cSStella Laurenzo MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get()); 722436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap); 723436c6c9cSStella Laurenzo }, 724436c6c9cSStella Laurenzo py::arg("context") = py::none(), "Gets an empty affine map.") 725436c6c9cSStella Laurenzo .def_static( 726436c6c9cSStella Laurenzo "get_identity", 727436c6c9cSStella Laurenzo [](intptr_t nDims, DefaultingPyMlirContext context) { 728436c6c9cSStella Laurenzo MlirAffineMap affineMap = 729436c6c9cSStella Laurenzo mlirAffineMapMultiDimIdentityGet(context->get(), nDims); 730436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap); 731436c6c9cSStella Laurenzo }, 732436c6c9cSStella Laurenzo py::arg("n_dims"), py::arg("context") = py::none(), 733436c6c9cSStella Laurenzo "Gets an identity map with the given number of dimensions.") 734436c6c9cSStella Laurenzo .def_static( 735436c6c9cSStella Laurenzo "get_minor_identity", 736436c6c9cSStella Laurenzo [](intptr_t nDims, intptr_t nResults, 737436c6c9cSStella Laurenzo DefaultingPyMlirContext context) { 738436c6c9cSStella Laurenzo MlirAffineMap affineMap = 739436c6c9cSStella Laurenzo mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults); 740436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap); 741436c6c9cSStella Laurenzo }, 742436c6c9cSStella Laurenzo py::arg("n_dims"), py::arg("n_results"), 743436c6c9cSStella Laurenzo py::arg("context") = py::none(), 744436c6c9cSStella Laurenzo "Gets a minor identity map with the given number of dimensions and " 745436c6c9cSStella Laurenzo "results.") 746436c6c9cSStella Laurenzo .def_static( 747436c6c9cSStella Laurenzo "get_permutation", 748436c6c9cSStella Laurenzo [](std::vector<unsigned> permutation, 749436c6c9cSStella Laurenzo DefaultingPyMlirContext context) { 750436c6c9cSStella Laurenzo if (!isPermutation(permutation)) 751436c6c9cSStella Laurenzo throw py::cast_error("Invalid permutation when attempting to " 752436c6c9cSStella Laurenzo "create an AffineMap"); 753436c6c9cSStella Laurenzo MlirAffineMap affineMap = mlirAffineMapPermutationGet( 754436c6c9cSStella Laurenzo context->get(), permutation.size(), permutation.data()); 755436c6c9cSStella Laurenzo return PyAffineMap(context->getRef(), affineMap); 756436c6c9cSStella Laurenzo }, 757436c6c9cSStella Laurenzo py::arg("permutation"), py::arg("context") = py::none(), 758436c6c9cSStella Laurenzo "Gets an affine map that permutes its inputs.") 759a6e7d024SStella Laurenzo .def( 760a6e7d024SStella Laurenzo "get_submap", 761436c6c9cSStella Laurenzo [](PyAffineMap &self, std::vector<intptr_t> &resultPos) { 762436c6c9cSStella Laurenzo intptr_t numResults = mlirAffineMapGetNumResults(self); 763436c6c9cSStella Laurenzo for (intptr_t pos : resultPos) { 764436c6c9cSStella Laurenzo if (pos < 0 || pos >= numResults) 765436c6c9cSStella Laurenzo throw py::value_error("result position out of bounds"); 766436c6c9cSStella Laurenzo } 767436c6c9cSStella Laurenzo MlirAffineMap affineMap = mlirAffineMapGetSubMap( 768436c6c9cSStella Laurenzo self, resultPos.size(), resultPos.data()); 769436c6c9cSStella Laurenzo return PyAffineMap(self.getContext(), affineMap); 770a6e7d024SStella Laurenzo }, 771a6e7d024SStella Laurenzo py::arg("result_positions")) 772a6e7d024SStella Laurenzo .def( 773a6e7d024SStella Laurenzo "get_major_submap", 774436c6c9cSStella Laurenzo [](PyAffineMap &self, intptr_t nResults) { 775436c6c9cSStella Laurenzo if (nResults >= mlirAffineMapGetNumResults(self)) 776436c6c9cSStella Laurenzo throw py::value_error("number of results out of bounds"); 777436c6c9cSStella Laurenzo MlirAffineMap affineMap = 778436c6c9cSStella Laurenzo mlirAffineMapGetMajorSubMap(self, nResults); 779436c6c9cSStella Laurenzo return PyAffineMap(self.getContext(), affineMap); 780a6e7d024SStella Laurenzo }, 781a6e7d024SStella Laurenzo py::arg("n_results")) 782a6e7d024SStella Laurenzo .def( 783a6e7d024SStella Laurenzo "get_minor_submap", 784436c6c9cSStella Laurenzo [](PyAffineMap &self, intptr_t nResults) { 785436c6c9cSStella Laurenzo if (nResults >= mlirAffineMapGetNumResults(self)) 786436c6c9cSStella Laurenzo throw py::value_error("number of results out of bounds"); 787436c6c9cSStella Laurenzo MlirAffineMap affineMap = 788436c6c9cSStella Laurenzo mlirAffineMapGetMinorSubMap(self, nResults); 789436c6c9cSStella Laurenzo return PyAffineMap(self.getContext(), affineMap); 790a6e7d024SStella Laurenzo }, 791a6e7d024SStella Laurenzo py::arg("n_results")) 792a6e7d024SStella Laurenzo .def( 793a6e7d024SStella Laurenzo "replace", 79431f888eaSTobias Gysi [](PyAffineMap &self, PyAffineExpr &expression, 79531f888eaSTobias Gysi PyAffineExpr &replacement, intptr_t numResultDims, 79631f888eaSTobias Gysi intptr_t numResultSyms) { 79731f888eaSTobias Gysi MlirAffineMap affineMap = mlirAffineMapReplace( 79831f888eaSTobias Gysi self, expression, replacement, numResultDims, numResultSyms); 79931f888eaSTobias Gysi return PyAffineMap(self.getContext(), affineMap); 800a6e7d024SStella Laurenzo }, 801a6e7d024SStella Laurenzo py::arg("expr"), py::arg("replacement"), py::arg("n_result_dims"), 802a6e7d024SStella Laurenzo py::arg("n_result_syms")) 803436c6c9cSStella Laurenzo .def_property_readonly( 804436c6c9cSStella Laurenzo "is_permutation", 805436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); }) 806436c6c9cSStella Laurenzo .def_property_readonly("is_projected_permutation", 807436c6c9cSStella Laurenzo [](PyAffineMap &self) { 808436c6c9cSStella Laurenzo return mlirAffineMapIsProjectedPermutation(self); 809436c6c9cSStella Laurenzo }) 810436c6c9cSStella Laurenzo .def_property_readonly( 811436c6c9cSStella Laurenzo "n_dims", 812436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); }) 813436c6c9cSStella Laurenzo .def_property_readonly( 814436c6c9cSStella Laurenzo "n_inputs", 815436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); }) 816436c6c9cSStella Laurenzo .def_property_readonly( 817436c6c9cSStella Laurenzo "n_symbols", 818436c6c9cSStella Laurenzo [](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); }) 819436c6c9cSStella Laurenzo .def_property_readonly("results", [](PyAffineMap &self) { 820436c6c9cSStella Laurenzo return PyAffineMapExprList(self); 821436c6c9cSStella Laurenzo }); 822436c6c9cSStella Laurenzo PyAffineMapExprList::bind(m); 823436c6c9cSStella Laurenzo 824436c6c9cSStella Laurenzo //---------------------------------------------------------------------------- 825436c6c9cSStella Laurenzo // Mapping of PyIntegerSet. 826436c6c9cSStella Laurenzo //---------------------------------------------------------------------------- 827f05ff4f7SStella Laurenzo py::class_<PyIntegerSet>(m, "IntegerSet", py::module_local()) 828436c6c9cSStella Laurenzo .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR, 829436c6c9cSStella Laurenzo &PyIntegerSet::getCapsule) 830436c6c9cSStella Laurenzo .def(MLIR_PYTHON_CAPI_FACTORY_ATTR, &PyIntegerSet::createFromCapsule) 831436c6c9cSStella Laurenzo .def("__eq__", [](PyIntegerSet &self, 832436c6c9cSStella Laurenzo PyIntegerSet &other) { return self == other; }) 833436c6c9cSStella Laurenzo .def("__eq__", [](PyIntegerSet &self, py::object other) { return false; }) 834436c6c9cSStella Laurenzo .def("__str__", 835436c6c9cSStella Laurenzo [](PyIntegerSet &self) { 836436c6c9cSStella Laurenzo PyPrintAccumulator printAccum; 837436c6c9cSStella Laurenzo mlirIntegerSetPrint(self, printAccum.getCallback(), 838436c6c9cSStella Laurenzo printAccum.getUserData()); 839436c6c9cSStella Laurenzo return printAccum.join(); 840436c6c9cSStella Laurenzo }) 841436c6c9cSStella Laurenzo .def("__repr__", 842436c6c9cSStella Laurenzo [](PyIntegerSet &self) { 843436c6c9cSStella Laurenzo PyPrintAccumulator printAccum; 844436c6c9cSStella Laurenzo printAccum.parts.append("IntegerSet("); 845436c6c9cSStella Laurenzo mlirIntegerSetPrint(self, printAccum.getCallback(), 846436c6c9cSStella Laurenzo printAccum.getUserData()); 847436c6c9cSStella Laurenzo printAccum.parts.append(")"); 848436c6c9cSStella Laurenzo return printAccum.join(); 849436c6c9cSStella Laurenzo }) 850fc7594ccSAlex Zinenko .def("__hash__", 851fc7594ccSAlex Zinenko [](PyIntegerSet &self) { 852fc7594ccSAlex Zinenko return static_cast<size_t>(llvm::hash_value(self.get().ptr)); 853fc7594ccSAlex Zinenko }) 854436c6c9cSStella Laurenzo .def_property_readonly( 855436c6c9cSStella Laurenzo "context", 856436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return self.getContext().getObject(); }) 857436c6c9cSStella Laurenzo .def( 858436c6c9cSStella Laurenzo "dump", [](PyIntegerSet &self) { mlirIntegerSetDump(self); }, 859436c6c9cSStella Laurenzo kDumpDocstring) 860436c6c9cSStella Laurenzo .def_static( 861436c6c9cSStella Laurenzo "get", 862436c6c9cSStella Laurenzo [](intptr_t numDims, intptr_t numSymbols, py::list exprs, 863436c6c9cSStella Laurenzo std::vector<bool> eqFlags, DefaultingPyMlirContext context) { 864436c6c9cSStella Laurenzo if (exprs.size() != eqFlags.size()) 865436c6c9cSStella Laurenzo throw py::value_error( 866436c6c9cSStella Laurenzo "Expected the number of constraints to match " 867436c6c9cSStella Laurenzo "that of equality flags"); 868436c6c9cSStella Laurenzo if (exprs.empty()) 869436c6c9cSStella Laurenzo throw py::value_error("Expected non-empty list of constraints"); 870436c6c9cSStella Laurenzo 871436c6c9cSStella Laurenzo // Copy over to a SmallVector because std::vector has a 872436c6c9cSStella Laurenzo // specialization for booleans that packs data and does not 873436c6c9cSStella Laurenzo // expose a `bool *`. 874436c6c9cSStella Laurenzo SmallVector<bool, 8> flags(eqFlags.begin(), eqFlags.end()); 875436c6c9cSStella Laurenzo 876436c6c9cSStella Laurenzo SmallVector<MlirAffineExpr> affineExprs; 877436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr>(exprs, affineExprs, 878436c6c9cSStella Laurenzo "attempting to create an IntegerSet"); 879436c6c9cSStella Laurenzo MlirIntegerSet set = mlirIntegerSetGet( 880436c6c9cSStella Laurenzo context->get(), numDims, numSymbols, exprs.size(), 881436c6c9cSStella Laurenzo affineExprs.data(), flags.data()); 882436c6c9cSStella Laurenzo return PyIntegerSet(context->getRef(), set); 883436c6c9cSStella Laurenzo }, 884436c6c9cSStella Laurenzo py::arg("num_dims"), py::arg("num_symbols"), py::arg("exprs"), 885436c6c9cSStella Laurenzo py::arg("eq_flags"), py::arg("context") = py::none()) 886436c6c9cSStella Laurenzo .def_static( 887436c6c9cSStella Laurenzo "get_empty", 888436c6c9cSStella Laurenzo [](intptr_t numDims, intptr_t numSymbols, 889436c6c9cSStella Laurenzo DefaultingPyMlirContext context) { 890436c6c9cSStella Laurenzo MlirIntegerSet set = 891436c6c9cSStella Laurenzo mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols); 892436c6c9cSStella Laurenzo return PyIntegerSet(context->getRef(), set); 893436c6c9cSStella Laurenzo }, 894436c6c9cSStella Laurenzo py::arg("num_dims"), py::arg("num_symbols"), 895436c6c9cSStella Laurenzo py::arg("context") = py::none()) 896a6e7d024SStella Laurenzo .def( 897a6e7d024SStella Laurenzo "get_replaced", 898436c6c9cSStella Laurenzo [](PyIntegerSet &self, py::list dimExprs, py::list symbolExprs, 899436c6c9cSStella Laurenzo intptr_t numResultDims, intptr_t numResultSymbols) { 900436c6c9cSStella Laurenzo if (static_cast<intptr_t>(dimExprs.size()) != 901436c6c9cSStella Laurenzo mlirIntegerSetGetNumDims(self)) 902436c6c9cSStella Laurenzo throw py::value_error( 903436c6c9cSStella Laurenzo "Expected the number of dimension replacement expressions " 904436c6c9cSStella Laurenzo "to match that of dimensions"); 905436c6c9cSStella Laurenzo if (static_cast<intptr_t>(symbolExprs.size()) != 906436c6c9cSStella Laurenzo mlirIntegerSetGetNumSymbols(self)) 907436c6c9cSStella Laurenzo throw py::value_error( 908436c6c9cSStella Laurenzo "Expected the number of symbol replacement expressions " 909436c6c9cSStella Laurenzo "to match that of symbols"); 910436c6c9cSStella Laurenzo 911436c6c9cSStella Laurenzo SmallVector<MlirAffineExpr> dimAffineExprs, symbolAffineExprs; 912436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr>( 913436c6c9cSStella Laurenzo dimExprs, dimAffineExprs, 914436c6c9cSStella Laurenzo "attempting to create an IntegerSet by replacing dimensions"); 915436c6c9cSStella Laurenzo pyListToVector<PyAffineExpr>( 916436c6c9cSStella Laurenzo symbolExprs, symbolAffineExprs, 917436c6c9cSStella Laurenzo "attempting to create an IntegerSet by replacing symbols"); 918436c6c9cSStella Laurenzo MlirIntegerSet set = mlirIntegerSetReplaceGet( 919436c6c9cSStella Laurenzo self, dimAffineExprs.data(), symbolAffineExprs.data(), 920436c6c9cSStella Laurenzo numResultDims, numResultSymbols); 921436c6c9cSStella Laurenzo return PyIntegerSet(self.getContext(), set); 922a6e7d024SStella Laurenzo }, 923a6e7d024SStella Laurenzo py::arg("dim_exprs"), py::arg("symbol_exprs"), 924a6e7d024SStella Laurenzo py::arg("num_result_dims"), py::arg("num_result_symbols")) 925436c6c9cSStella Laurenzo .def_property_readonly("is_canonical_empty", 926436c6c9cSStella Laurenzo [](PyIntegerSet &self) { 927436c6c9cSStella Laurenzo return mlirIntegerSetIsCanonicalEmpty(self); 928436c6c9cSStella Laurenzo }) 929436c6c9cSStella Laurenzo .def_property_readonly( 930436c6c9cSStella Laurenzo "n_dims", 931436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); }) 932436c6c9cSStella Laurenzo .def_property_readonly( 933436c6c9cSStella Laurenzo "n_symbols", 934436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); }) 935436c6c9cSStella Laurenzo .def_property_readonly( 936436c6c9cSStella Laurenzo "n_inputs", 937436c6c9cSStella Laurenzo [](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); }) 938436c6c9cSStella Laurenzo .def_property_readonly("n_equalities", 939436c6c9cSStella Laurenzo [](PyIntegerSet &self) { 940436c6c9cSStella Laurenzo return mlirIntegerSetGetNumEqualities(self); 941436c6c9cSStella Laurenzo }) 942436c6c9cSStella Laurenzo .def_property_readonly("n_inequalities", 943436c6c9cSStella Laurenzo [](PyIntegerSet &self) { 944436c6c9cSStella Laurenzo return mlirIntegerSetGetNumInequalities(self); 945436c6c9cSStella Laurenzo }) 946436c6c9cSStella Laurenzo .def_property_readonly("constraints", [](PyIntegerSet &self) { 947436c6c9cSStella Laurenzo return PyIntegerSetConstraintList(self); 948436c6c9cSStella Laurenzo }); 949436c6c9cSStella Laurenzo PyIntegerSetConstraint::bind(m); 950436c6c9cSStella Laurenzo PyIntegerSetConstraintList::bind(m); 951436c6c9cSStella Laurenzo } 952