MLIR  17.0.0git
IRAffine.cpp
Go to the documentation of this file.
1 //===- IRAffine.cpp - Exports 'ir' module affine related bindings ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <utility>
10 
11 #include "IRModule.h"
12 
13 #include "PybindUtils.h"
14 
15 #include "mlir-c/AffineMap.h"
17 #include "mlir-c/IntegerSet.h"
18 #include "llvm/ADT/Hashing.h"
19 
20 namespace py = pybind11;
21 using namespace mlir;
22 using namespace mlir::python;
23 
24 using llvm::SmallVector;
25 using llvm::StringRef;
26 using llvm::Twine;
27 
28 static const char kDumpDocstring[] =
29  R"(Dumps a debug representation of the object to stderr.)";
30 
31 /// Attempts to populate `result` with the content of `list` casted to the
32 /// appropriate type (Python and C types are provided as template arguments).
33 /// Throws errors in case of failure, using "action" to describe what the caller
34 /// was attempting to do.
35 template <typename PyType, typename CType>
36 static void pyListToVector(const py::list &list,
38  StringRef action) {
39  result.reserve(py::len(list));
40  for (py::handle item : list) {
41  try {
42  result.push_back(item.cast<PyType>());
43  } catch (py::cast_error &err) {
44  std::string msg = (llvm::Twine("Invalid expression when ") + action +
45  " (" + err.what() + ")")
46  .str();
47  throw py::cast_error(msg);
48  } catch (py::reference_cast_error &err) {
49  std::string msg = (llvm::Twine("Invalid expression (None?) when ") +
50  action + " (" + err.what() + ")")
51  .str();
52  throw py::cast_error(msg);
53  }
54  }
55 }
56 
57 template <typename PermutationTy>
58 static bool isPermutation(std::vector<PermutationTy> permutation) {
59  llvm::SmallVector<bool, 8> seen(permutation.size(), false);
60  for (auto val : permutation) {
61  if (val < permutation.size()) {
62  if (seen[val])
63  return false;
64  seen[val] = true;
65  continue;
66  }
67  return false;
68  }
69  return true;
70 }
71 
72 namespace {
73 
74 /// CRTP base class for Python MLIR affine expressions that subclass AffineExpr
75 /// and should be castable from it. Intermediate hierarchy classes can be
76 /// modeled by specifying BaseTy.
77 template <typename DerivedTy, typename BaseTy = PyAffineExpr>
78 class PyConcreteAffineExpr : public BaseTy {
79 public:
80  // Derived classes must define statics for:
81  // IsAFunctionTy isaFunction
82  // const char *pyClassName
83  // and redefine bindDerived.
84  using ClassTy = py::class_<DerivedTy, BaseTy>;
85  using IsAFunctionTy = bool (*)(MlirAffineExpr);
86 
87  PyConcreteAffineExpr() = default;
88  PyConcreteAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
89  : BaseTy(std::move(contextRef), affineExpr) {}
90  PyConcreteAffineExpr(PyAffineExpr &orig)
91  : PyConcreteAffineExpr(orig.getContext(), castFrom(orig)) {}
92 
93  static MlirAffineExpr castFrom(PyAffineExpr &orig) {
94  if (!DerivedTy::isaFunction(orig)) {
95  auto origRepr = py::repr(py::cast(orig)).cast<std::string>();
96  throw py::value_error((Twine("Cannot cast affine expression to ") +
97  DerivedTy::pyClassName + " (from " + origRepr +
98  ")")
99  .str());
100  }
101  return orig;
102  }
103 
104  static void bind(py::module &m) {
105  auto cls = ClassTy(m, DerivedTy::pyClassName, py::module_local());
106  cls.def(py::init<PyAffineExpr &>(), py::arg("expr"));
107  cls.def_static(
108  "isinstance",
109  [](PyAffineExpr &otherAffineExpr) -> bool {
110  return DerivedTy::isaFunction(otherAffineExpr);
111  },
112  py::arg("other"));
113  DerivedTy::bindDerived(cls);
114  }
115 
116  /// Implemented by derived classes to add methods to the Python subclass.
117  static void bindDerived(ClassTy &m) {}
118 };
119 
120 class PyAffineConstantExpr : public PyConcreteAffineExpr<PyAffineConstantExpr> {
121 public:
122  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAConstant;
123  static constexpr const char *pyClassName = "AffineConstantExpr";
124  using PyConcreteAffineExpr::PyConcreteAffineExpr;
125 
126  static PyAffineConstantExpr get(intptr_t value,
127  DefaultingPyMlirContext context) {
128  MlirAffineExpr affineExpr =
129  mlirAffineConstantExprGet(context->get(), static_cast<int64_t>(value));
130  return PyAffineConstantExpr(context->getRef(), affineExpr);
131  }
132 
133  static void bindDerived(ClassTy &c) {
134  c.def_static("get", &PyAffineConstantExpr::get, py::arg("value"),
135  py::arg("context") = py::none());
136  c.def_property_readonly("value", [](PyAffineConstantExpr &self) {
137  return mlirAffineConstantExprGetValue(self);
138  });
139  }
140 };
141 
142 class PyAffineDimExpr : public PyConcreteAffineExpr<PyAffineDimExpr> {
143 public:
144  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsADim;
145  static constexpr const char *pyClassName = "AffineDimExpr";
146  using PyConcreteAffineExpr::PyConcreteAffineExpr;
147 
148  static PyAffineDimExpr get(intptr_t pos, DefaultingPyMlirContext context) {
149  MlirAffineExpr affineExpr = mlirAffineDimExprGet(context->get(), pos);
150  return PyAffineDimExpr(context->getRef(), affineExpr);
151  }
152 
153  static void bindDerived(ClassTy &c) {
154  c.def_static("get", &PyAffineDimExpr::get, py::arg("position"),
155  py::arg("context") = py::none());
156  c.def_property_readonly("position", [](PyAffineDimExpr &self) {
157  return mlirAffineDimExprGetPosition(self);
158  });
159  }
160 };
161 
162 class PyAffineSymbolExpr : public PyConcreteAffineExpr<PyAffineSymbolExpr> {
163 public:
164  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsASymbol;
165  static constexpr const char *pyClassName = "AffineSymbolExpr";
166  using PyConcreteAffineExpr::PyConcreteAffineExpr;
167 
168  static PyAffineSymbolExpr get(intptr_t pos, DefaultingPyMlirContext context) {
169  MlirAffineExpr affineExpr = mlirAffineSymbolExprGet(context->get(), pos);
170  return PyAffineSymbolExpr(context->getRef(), affineExpr);
171  }
172 
173  static void bindDerived(ClassTy &c) {
174  c.def_static("get", &PyAffineSymbolExpr::get, py::arg("position"),
175  py::arg("context") = py::none());
176  c.def_property_readonly("position", [](PyAffineSymbolExpr &self) {
177  return mlirAffineSymbolExprGetPosition(self);
178  });
179  }
180 };
181 
182 class PyAffineBinaryExpr : public PyConcreteAffineExpr<PyAffineBinaryExpr> {
183 public:
184  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsABinary;
185  static constexpr const char *pyClassName = "AffineBinaryExpr";
186  using PyConcreteAffineExpr::PyConcreteAffineExpr;
187 
188  PyAffineExpr lhs() {
189  MlirAffineExpr lhsExpr = mlirAffineBinaryOpExprGetLHS(get());
190  return PyAffineExpr(getContext(), lhsExpr);
191  }
192 
193  PyAffineExpr rhs() {
194  MlirAffineExpr rhsExpr = mlirAffineBinaryOpExprGetRHS(get());
195  return PyAffineExpr(getContext(), rhsExpr);
196  }
197 
198  static void bindDerived(ClassTy &c) {
199  c.def_property_readonly("lhs", &PyAffineBinaryExpr::lhs);
200  c.def_property_readonly("rhs", &PyAffineBinaryExpr::rhs);
201  }
202 };
203 
204 class PyAffineAddExpr
205  : public PyConcreteAffineExpr<PyAffineAddExpr, PyAffineBinaryExpr> {
206 public:
207  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAAdd;
208  static constexpr const char *pyClassName = "AffineAddExpr";
209  using PyConcreteAffineExpr::PyConcreteAffineExpr;
210 
211  static PyAffineAddExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
212  MlirAffineExpr expr = mlirAffineAddExprGet(lhs, rhs);
213  return PyAffineAddExpr(lhs.getContext(), expr);
214  }
215 
216  static PyAffineAddExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
217  MlirAffineExpr expr = mlirAffineAddExprGet(
219  return PyAffineAddExpr(lhs.getContext(), expr);
220  }
221 
222  static PyAffineAddExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
223  MlirAffineExpr expr = mlirAffineAddExprGet(
225  return PyAffineAddExpr(rhs.getContext(), expr);
226  }
227 
228  static void bindDerived(ClassTy &c) {
229  c.def_static("get", &PyAffineAddExpr::get);
230  }
231 };
232 
233 class PyAffineMulExpr
234  : public PyConcreteAffineExpr<PyAffineMulExpr, PyAffineBinaryExpr> {
235 public:
236  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAMul;
237  static constexpr const char *pyClassName = "AffineMulExpr";
238  using PyConcreteAffineExpr::PyConcreteAffineExpr;
239 
240  static PyAffineMulExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
241  MlirAffineExpr expr = mlirAffineMulExprGet(lhs, rhs);
242  return PyAffineMulExpr(lhs.getContext(), expr);
243  }
244 
245  static PyAffineMulExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
246  MlirAffineExpr expr = mlirAffineMulExprGet(
248  return PyAffineMulExpr(lhs.getContext(), expr);
249  }
250 
251  static PyAffineMulExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
252  MlirAffineExpr expr = mlirAffineMulExprGet(
254  return PyAffineMulExpr(rhs.getContext(), expr);
255  }
256 
257  static void bindDerived(ClassTy &c) {
258  c.def_static("get", &PyAffineMulExpr::get);
259  }
260 };
261 
262 class PyAffineModExpr
263  : public PyConcreteAffineExpr<PyAffineModExpr, PyAffineBinaryExpr> {
264 public:
265  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAMod;
266  static constexpr const char *pyClassName = "AffineModExpr";
267  using PyConcreteAffineExpr::PyConcreteAffineExpr;
268 
269  static PyAffineModExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
270  MlirAffineExpr expr = mlirAffineModExprGet(lhs, rhs);
271  return PyAffineModExpr(lhs.getContext(), expr);
272  }
273 
274  static PyAffineModExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
275  MlirAffineExpr expr = mlirAffineModExprGet(
277  return PyAffineModExpr(lhs.getContext(), expr);
278  }
279 
280  static PyAffineModExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
281  MlirAffineExpr expr = mlirAffineModExprGet(
283  return PyAffineModExpr(rhs.getContext(), expr);
284  }
285 
286  static void bindDerived(ClassTy &c) {
287  c.def_static("get", &PyAffineModExpr::get);
288  }
289 };
290 
291 class PyAffineFloorDivExpr
292  : public PyConcreteAffineExpr<PyAffineFloorDivExpr, PyAffineBinaryExpr> {
293 public:
294  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsAFloorDiv;
295  static constexpr const char *pyClassName = "AffineFloorDivExpr";
296  using PyConcreteAffineExpr::PyConcreteAffineExpr;
297 
298  static PyAffineFloorDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
299  MlirAffineExpr expr = mlirAffineFloorDivExprGet(lhs, rhs);
300  return PyAffineFloorDivExpr(lhs.getContext(), expr);
301  }
302 
303  static PyAffineFloorDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
304  MlirAffineExpr expr = mlirAffineFloorDivExprGet(
306  return PyAffineFloorDivExpr(lhs.getContext(), expr);
307  }
308 
309  static PyAffineFloorDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
310  MlirAffineExpr expr = mlirAffineFloorDivExprGet(
312  return PyAffineFloorDivExpr(rhs.getContext(), expr);
313  }
314 
315  static void bindDerived(ClassTy &c) {
316  c.def_static("get", &PyAffineFloorDivExpr::get);
317  }
318 };
319 
320 class PyAffineCeilDivExpr
321  : public PyConcreteAffineExpr<PyAffineCeilDivExpr, PyAffineBinaryExpr> {
322 public:
323  static constexpr IsAFunctionTy isaFunction = mlirAffineExprIsACeilDiv;
324  static constexpr const char *pyClassName = "AffineCeilDivExpr";
325  using PyConcreteAffineExpr::PyConcreteAffineExpr;
326 
327  static PyAffineCeilDivExpr get(PyAffineExpr lhs, const PyAffineExpr &rhs) {
328  MlirAffineExpr expr = mlirAffineCeilDivExprGet(lhs, rhs);
329  return PyAffineCeilDivExpr(lhs.getContext(), expr);
330  }
331 
332  static PyAffineCeilDivExpr getRHSConstant(PyAffineExpr lhs, intptr_t rhs) {
333  MlirAffineExpr expr = mlirAffineCeilDivExprGet(
335  return PyAffineCeilDivExpr(lhs.getContext(), expr);
336  }
337 
338  static PyAffineCeilDivExpr getLHSConstant(intptr_t lhs, PyAffineExpr rhs) {
339  MlirAffineExpr expr = mlirAffineCeilDivExprGet(
341  return PyAffineCeilDivExpr(rhs.getContext(), expr);
342  }
343 
344  static void bindDerived(ClassTy &c) {
345  c.def_static("get", &PyAffineCeilDivExpr::get);
346  }
347 };
348 
349 } // namespace
350 
351 bool PyAffineExpr::operator==(const PyAffineExpr &other) const {
352  return mlirAffineExprEqual(affineExpr, other.affineExpr);
353 }
354 
356  return py::reinterpret_steal<py::object>(
358 }
359 
361  MlirAffineExpr rawAffineExpr = mlirPythonCapsuleToAffineExpr(capsule.ptr());
362  if (mlirAffineExprIsNull(rawAffineExpr))
363  throw py::error_already_set();
364  return PyAffineExpr(
366  rawAffineExpr);
367 }
368 
369 //------------------------------------------------------------------------------
370 // PyAffineMap and utilities.
371 //------------------------------------------------------------------------------
372 namespace {
373 
374 /// A list of expressions contained in an affine map. Internally these are
375 /// stored as a consecutive array leading to inexpensive random access. Both
376 /// the map and the expression are owned by the context so we need not bother
377 /// with lifetime extension.
378 class PyAffineMapExprList
379  : public Sliceable<PyAffineMapExprList, PyAffineExpr> {
380 public:
381  static constexpr const char *pyClassName = "AffineExprList";
382 
383  PyAffineMapExprList(const PyAffineMap &map, intptr_t startIndex = 0,
384  intptr_t length = -1, intptr_t step = 1)
385  : Sliceable(startIndex,
386  length == -1 ? mlirAffineMapGetNumResults(map) : length,
387  step),
388  affineMap(map) {}
389 
390 private:
391  /// Give the parent CRTP class access to hook implementations below.
392  friend class Sliceable<PyAffineMapExprList, PyAffineExpr>;
393 
394  intptr_t getRawNumElements() { return mlirAffineMapGetNumResults(affineMap); }
395 
396  PyAffineExpr getRawElement(intptr_t pos) {
397  return PyAffineExpr(affineMap.getContext(),
398  mlirAffineMapGetResult(affineMap, pos));
399  }
400 
401  PyAffineMapExprList slice(intptr_t startIndex, intptr_t length,
402  intptr_t step) {
403  return PyAffineMapExprList(affineMap, startIndex, length, step);
404  }
405 
406  PyAffineMap affineMap;
407 };
408 } // namespace
409 
410 bool PyAffineMap::operator==(const PyAffineMap &other) const {
411  return mlirAffineMapEqual(affineMap, other.affineMap);
412 }
413 
415  return py::reinterpret_steal<py::object>(mlirPythonAffineMapToCapsule(*this));
416 }
417 
419  MlirAffineMap rawAffineMap = mlirPythonCapsuleToAffineMap(capsule.ptr());
420  if (mlirAffineMapIsNull(rawAffineMap))
421  throw py::error_already_set();
422  return PyAffineMap(
424  rawAffineMap);
425 }
426 
427 //------------------------------------------------------------------------------
428 // PyIntegerSet and utilities.
429 //------------------------------------------------------------------------------
430 namespace {
431 
432 class PyIntegerSetConstraint {
433 public:
434  PyIntegerSetConstraint(PyIntegerSet set, intptr_t pos)
435  : set(std::move(set)), pos(pos) {}
436 
437  PyAffineExpr getExpr() {
438  return PyAffineExpr(set.getContext(),
439  mlirIntegerSetGetConstraint(set, pos));
440  }
441 
442  bool isEq() { return mlirIntegerSetIsConstraintEq(set, pos); }
443 
444  static void bind(py::module &m) {
445  py::class_<PyIntegerSetConstraint>(m, "IntegerSetConstraint",
446  py::module_local())
447  .def_property_readonly("expr", &PyIntegerSetConstraint::getExpr)
448  .def_property_readonly("is_eq", &PyIntegerSetConstraint::isEq);
449  }
450 
451 private:
452  PyIntegerSet set;
453  intptr_t pos;
454 };
455 
456 class PyIntegerSetConstraintList
457  : public Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint> {
458 public:
459  static constexpr const char *pyClassName = "IntegerSetConstraintList";
460 
461  PyIntegerSetConstraintList(const PyIntegerSet &set, intptr_t startIndex = 0,
462  intptr_t length = -1, intptr_t step = 1)
463  : Sliceable(startIndex,
464  length == -1 ? mlirIntegerSetGetNumConstraints(set) : length,
465  step),
466  set(set) {}
467 
468 private:
469  /// Give the parent CRTP class access to hook implementations below.
470  friend class Sliceable<PyIntegerSetConstraintList, PyIntegerSetConstraint>;
471 
472  intptr_t getRawNumElements() { return mlirIntegerSetGetNumConstraints(set); }
473 
474  PyIntegerSetConstraint getRawElement(intptr_t pos) {
475  return PyIntegerSetConstraint(set, pos);
476  }
477 
478  PyIntegerSetConstraintList slice(intptr_t startIndex, intptr_t length,
479  intptr_t step) {
480  return PyIntegerSetConstraintList(set, startIndex, length, step);
481  }
482 
483  PyIntegerSet set;
484 };
485 } // namespace
486 
487 bool PyIntegerSet::operator==(const PyIntegerSet &other) const {
488  return mlirIntegerSetEqual(integerSet, other.integerSet);
489 }
490 
492  return py::reinterpret_steal<py::object>(
494 }
495 
497  MlirIntegerSet rawIntegerSet = mlirPythonCapsuleToIntegerSet(capsule.ptr());
498  if (mlirIntegerSetIsNull(rawIntegerSet))
499  throw py::error_already_set();
500  return PyIntegerSet(
502  rawIntegerSet);
503 }
504 
505 void mlir::python::populateIRAffine(py::module &m) {
506  //----------------------------------------------------------------------------
507  // Mapping of PyAffineExpr and derived classes.
508  //----------------------------------------------------------------------------
509  py::class_<PyAffineExpr>(m, "AffineExpr", py::module_local())
510  .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
513  .def("__add__", &PyAffineAddExpr::get)
514  .def("__add__", &PyAffineAddExpr::getRHSConstant)
515  .def("__radd__", &PyAffineAddExpr::getRHSConstant)
516  .def("__mul__", &PyAffineMulExpr::get)
517  .def("__mul__", &PyAffineMulExpr::getRHSConstant)
518  .def("__rmul__", &PyAffineMulExpr::getRHSConstant)
519  .def("__mod__", &PyAffineModExpr::get)
520  .def("__mod__", &PyAffineModExpr::getRHSConstant)
521  .def("__rmod__",
522  [](PyAffineExpr &self, intptr_t other) {
523  return PyAffineModExpr::get(
524  PyAffineConstantExpr::get(other, *self.getContext().get()),
525  self);
526  })
527  .def("__sub__",
528  [](PyAffineExpr &self, PyAffineExpr &other) {
529  auto negOne =
530  PyAffineConstantExpr::get(-1, *self.getContext().get());
531  return PyAffineAddExpr::get(self,
532  PyAffineMulExpr::get(negOne, other));
533  })
534  .def("__sub__",
535  [](PyAffineExpr &self, intptr_t other) {
536  return PyAffineAddExpr::get(
537  self,
538  PyAffineConstantExpr::get(-other, *self.getContext().get()));
539  })
540  .def("__rsub__",
541  [](PyAffineExpr &self, intptr_t other) {
542  return PyAffineAddExpr::getLHSConstant(
543  other, PyAffineMulExpr::getLHSConstant(-1, self));
544  })
545  .def("__eq__", [](PyAffineExpr &self,
546  PyAffineExpr &other) { return self == other; })
547  .def("__eq__",
548  [](PyAffineExpr &self, py::object &other) { return false; })
549  .def("__str__",
550  [](PyAffineExpr &self) {
551  PyPrintAccumulator printAccum;
552  mlirAffineExprPrint(self, printAccum.getCallback(),
553  printAccum.getUserData());
554  return printAccum.join();
555  })
556  .def("__repr__",
557  [](PyAffineExpr &self) {
558  PyPrintAccumulator printAccum;
559  printAccum.parts.append("AffineExpr(");
560  mlirAffineExprPrint(self, printAccum.getCallback(),
561  printAccum.getUserData());
562  printAccum.parts.append(")");
563  return printAccum.join();
564  })
565  .def("__hash__",
566  [](PyAffineExpr &self) {
567  return static_cast<size_t>(llvm::hash_value(self.get().ptr));
568  })
569  .def_property_readonly(
570  "context",
571  [](PyAffineExpr &self) { return self.getContext().getObject(); })
572  .def("compose",
573  [](PyAffineExpr &self, PyAffineMap &other) {
574  return PyAffineExpr(self.getContext(),
575  mlirAffineExprCompose(self, other));
576  })
577  .def_static(
578  "get_add", &PyAffineAddExpr::get,
579  "Gets an affine expression containing a sum of two expressions.")
580  .def_static("get_add", &PyAffineAddExpr::getLHSConstant,
581  "Gets an affine expression containing a sum of a constant "
582  "and another expression.")
583  .def_static("get_add", &PyAffineAddExpr::getRHSConstant,
584  "Gets an affine expression containing a sum of an expression "
585  "and a constant.")
586  .def_static(
587  "get_mul", &PyAffineMulExpr::get,
588  "Gets an affine expression containing a product of two expressions.")
589  .def_static("get_mul", &PyAffineMulExpr::getLHSConstant,
590  "Gets an affine expression containing a product of a "
591  "constant and another expression.")
592  .def_static("get_mul", &PyAffineMulExpr::getRHSConstant,
593  "Gets an affine expression containing a product of an "
594  "expression and a constant.")
595  .def_static("get_mod", &PyAffineModExpr::get,
596  "Gets an affine expression containing the modulo of dividing "
597  "one expression by another.")
598  .def_static("get_mod", &PyAffineModExpr::getLHSConstant,
599  "Gets a semi-affine expression containing the modulo of "
600  "dividing a constant by an expression.")
601  .def_static("get_mod", &PyAffineModExpr::getRHSConstant,
602  "Gets an affine expression containing the module of dividing"
603  "an expression by a constant.")
604  .def_static("get_floor_div", &PyAffineFloorDivExpr::get,
605  "Gets an affine expression containing the rounded-down "
606  "result of dividing one expression by another.")
607  .def_static("get_floor_div", &PyAffineFloorDivExpr::getLHSConstant,
608  "Gets a semi-affine expression containing the rounded-down "
609  "result of dividing a constant by an expression.")
610  .def_static("get_floor_div", &PyAffineFloorDivExpr::getRHSConstant,
611  "Gets an affine expression containing the rounded-down "
612  "result of dividing an expression by a constant.")
613  .def_static("get_ceil_div", &PyAffineCeilDivExpr::get,
614  "Gets an affine expression containing the rounded-up result "
615  "of dividing one expression by another.")
616  .def_static("get_ceil_div", &PyAffineCeilDivExpr::getLHSConstant,
617  "Gets a semi-affine expression containing the rounded-up "
618  "result of dividing a constant by an expression.")
619  .def_static("get_ceil_div", &PyAffineCeilDivExpr::getRHSConstant,
620  "Gets an affine expression containing the rounded-up result "
621  "of dividing an expression by a constant.")
622  .def_static("get_constant", &PyAffineConstantExpr::get, py::arg("value"),
623  py::arg("context") = py::none(),
624  "Gets a constant affine expression with the given value.")
625  .def_static(
626  "get_dim", &PyAffineDimExpr::get, py::arg("position"),
627  py::arg("context") = py::none(),
628  "Gets an affine expression of a dimension at the given position.")
629  .def_static(
630  "get_symbol", &PyAffineSymbolExpr::get, py::arg("position"),
631  py::arg("context") = py::none(),
632  "Gets an affine expression of a symbol at the given position.")
633  .def(
634  "dump", [](PyAffineExpr &self) { mlirAffineExprDump(self); },
636  PyAffineConstantExpr::bind(m);
637  PyAffineDimExpr::bind(m);
638  PyAffineSymbolExpr::bind(m);
639  PyAffineBinaryExpr::bind(m);
640  PyAffineAddExpr::bind(m);
641  PyAffineMulExpr::bind(m);
642  PyAffineModExpr::bind(m);
643  PyAffineFloorDivExpr::bind(m);
644  PyAffineCeilDivExpr::bind(m);
645 
646  //----------------------------------------------------------------------------
647  // Mapping of PyAffineMap.
648  //----------------------------------------------------------------------------
649  py::class_<PyAffineMap>(m, "AffineMap", py::module_local())
650  .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
653  .def("__eq__",
654  [](PyAffineMap &self, PyAffineMap &other) { return self == other; })
655  .def("__eq__", [](PyAffineMap &self, py::object &other) { return false; })
656  .def("__str__",
657  [](PyAffineMap &self) {
658  PyPrintAccumulator printAccum;
659  mlirAffineMapPrint(self, printAccum.getCallback(),
660  printAccum.getUserData());
661  return printAccum.join();
662  })
663  .def("__repr__",
664  [](PyAffineMap &self) {
665  PyPrintAccumulator printAccum;
666  printAccum.parts.append("AffineMap(");
667  mlirAffineMapPrint(self, printAccum.getCallback(),
668  printAccum.getUserData());
669  printAccum.parts.append(")");
670  return printAccum.join();
671  })
672  .def("__hash__",
673  [](PyAffineMap &self) {
674  return static_cast<size_t>(llvm::hash_value(self.get().ptr));
675  })
676  .def_static("compress_unused_symbols",
677  [](py::list affineMaps, DefaultingPyMlirContext context) {
679  pyListToVector<PyAffineMap, MlirAffineMap>(
680  affineMaps, maps, "attempting to create an AffineMap");
681  std::vector<MlirAffineMap> compressed(affineMaps.size());
682  auto populate = [](void *result, intptr_t idx,
683  MlirAffineMap m) {
684  static_cast<MlirAffineMap *>(result)[idx] = (m);
685  };
687  maps.data(), maps.size(), compressed.data(), populate);
688  std::vector<PyAffineMap> res;
689  res.reserve(compressed.size());
690  for (auto m : compressed)
691  res.emplace_back(context->getRef(), m);
692  return res;
693  })
694  .def_property_readonly(
695  "context",
696  [](PyAffineMap &self) { return self.getContext().getObject(); },
697  "Context that owns the Affine Map")
698  .def(
699  "dump", [](PyAffineMap &self) { mlirAffineMapDump(self); },
701  .def_static(
702  "get",
703  [](intptr_t dimCount, intptr_t symbolCount, py::list exprs,
704  DefaultingPyMlirContext context) {
705  SmallVector<MlirAffineExpr> affineExprs;
706  pyListToVector<PyAffineExpr, MlirAffineExpr>(
707  exprs, affineExprs, "attempting to create an AffineMap");
708  MlirAffineMap map =
709  mlirAffineMapGet(context->get(), dimCount, symbolCount,
710  affineExprs.size(), affineExprs.data());
711  return PyAffineMap(context->getRef(), map);
712  },
713  py::arg("dim_count"), py::arg("symbol_count"), py::arg("exprs"),
714  py::arg("context") = py::none(),
715  "Gets a map with the given expressions as results.")
716  .def_static(
717  "get_constant",
718  [](intptr_t value, DefaultingPyMlirContext context) {
719  MlirAffineMap affineMap =
720  mlirAffineMapConstantGet(context->get(), value);
721  return PyAffineMap(context->getRef(), affineMap);
722  },
723  py::arg("value"), py::arg("context") = py::none(),
724  "Gets an affine map with a single constant result")
725  .def_static(
726  "get_empty",
727  [](DefaultingPyMlirContext context) {
728  MlirAffineMap affineMap = mlirAffineMapEmptyGet(context->get());
729  return PyAffineMap(context->getRef(), affineMap);
730  },
731  py::arg("context") = py::none(), "Gets an empty affine map.")
732  .def_static(
733  "get_identity",
734  [](intptr_t nDims, DefaultingPyMlirContext context) {
735  MlirAffineMap affineMap =
736  mlirAffineMapMultiDimIdentityGet(context->get(), nDims);
737  return PyAffineMap(context->getRef(), affineMap);
738  },
739  py::arg("n_dims"), py::arg("context") = py::none(),
740  "Gets an identity map with the given number of dimensions.")
741  .def_static(
742  "get_minor_identity",
743  [](intptr_t nDims, intptr_t nResults,
744  DefaultingPyMlirContext context) {
745  MlirAffineMap affineMap =
746  mlirAffineMapMinorIdentityGet(context->get(), nDims, nResults);
747  return PyAffineMap(context->getRef(), affineMap);
748  },
749  py::arg("n_dims"), py::arg("n_results"),
750  py::arg("context") = py::none(),
751  "Gets a minor identity map with the given number of dimensions and "
752  "results.")
753  .def_static(
754  "get_permutation",
755  [](std::vector<unsigned> permutation,
756  DefaultingPyMlirContext context) {
757  if (!isPermutation(permutation))
758  throw py::cast_error("Invalid permutation when attempting to "
759  "create an AffineMap");
760  MlirAffineMap affineMap = mlirAffineMapPermutationGet(
761  context->get(), permutation.size(), permutation.data());
762  return PyAffineMap(context->getRef(), affineMap);
763  },
764  py::arg("permutation"), py::arg("context") = py::none(),
765  "Gets an affine map that permutes its inputs.")
766  .def(
767  "get_submap",
768  [](PyAffineMap &self, std::vector<intptr_t> &resultPos) {
769  intptr_t numResults = mlirAffineMapGetNumResults(self);
770  for (intptr_t pos : resultPos) {
771  if (pos < 0 || pos >= numResults)
772  throw py::value_error("result position out of bounds");
773  }
774  MlirAffineMap affineMap = mlirAffineMapGetSubMap(
775  self, resultPos.size(), resultPos.data());
776  return PyAffineMap(self.getContext(), affineMap);
777  },
778  py::arg("result_positions"))
779  .def(
780  "get_major_submap",
781  [](PyAffineMap &self, intptr_t nResults) {
782  if (nResults >= mlirAffineMapGetNumResults(self))
783  throw py::value_error("number of results out of bounds");
784  MlirAffineMap affineMap =
785  mlirAffineMapGetMajorSubMap(self, nResults);
786  return PyAffineMap(self.getContext(), affineMap);
787  },
788  py::arg("n_results"))
789  .def(
790  "get_minor_submap",
791  [](PyAffineMap &self, intptr_t nResults) {
792  if (nResults >= mlirAffineMapGetNumResults(self))
793  throw py::value_error("number of results out of bounds");
794  MlirAffineMap affineMap =
795  mlirAffineMapGetMinorSubMap(self, nResults);
796  return PyAffineMap(self.getContext(), affineMap);
797  },
798  py::arg("n_results"))
799  .def(
800  "replace",
801  [](PyAffineMap &self, PyAffineExpr &expression,
802  PyAffineExpr &replacement, intptr_t numResultDims,
803  intptr_t numResultSyms) {
804  MlirAffineMap affineMap = mlirAffineMapReplace(
805  self, expression, replacement, numResultDims, numResultSyms);
806  return PyAffineMap(self.getContext(), affineMap);
807  },
808  py::arg("expr"), py::arg("replacement"), py::arg("n_result_dims"),
809  py::arg("n_result_syms"))
810  .def_property_readonly(
811  "is_permutation",
812  [](PyAffineMap &self) { return mlirAffineMapIsPermutation(self); })
813  .def_property_readonly("is_projected_permutation",
814  [](PyAffineMap &self) {
816  })
817  .def_property_readonly(
818  "n_dims",
819  [](PyAffineMap &self) { return mlirAffineMapGetNumDims(self); })
820  .def_property_readonly(
821  "n_inputs",
822  [](PyAffineMap &self) { return mlirAffineMapGetNumInputs(self); })
823  .def_property_readonly(
824  "n_symbols",
825  [](PyAffineMap &self) { return mlirAffineMapGetNumSymbols(self); })
826  .def_property_readonly("results", [](PyAffineMap &self) {
827  return PyAffineMapExprList(self);
828  });
829  PyAffineMapExprList::bind(m);
830 
831  //----------------------------------------------------------------------------
832  // Mapping of PyIntegerSet.
833  //----------------------------------------------------------------------------
834  py::class_<PyIntegerSet>(m, "IntegerSet", py::module_local())
835  .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
838  .def("__eq__", [](PyIntegerSet &self,
839  PyIntegerSet &other) { return self == other; })
840  .def("__eq__", [](PyIntegerSet &self, py::object other) { return false; })
841  .def("__str__",
842  [](PyIntegerSet &self) {
843  PyPrintAccumulator printAccum;
844  mlirIntegerSetPrint(self, printAccum.getCallback(),
845  printAccum.getUserData());
846  return printAccum.join();
847  })
848  .def("__repr__",
849  [](PyIntegerSet &self) {
850  PyPrintAccumulator printAccum;
851  printAccum.parts.append("IntegerSet(");
852  mlirIntegerSetPrint(self, printAccum.getCallback(),
853  printAccum.getUserData());
854  printAccum.parts.append(")");
855  return printAccum.join();
856  })
857  .def("__hash__",
858  [](PyIntegerSet &self) {
859  return static_cast<size_t>(llvm::hash_value(self.get().ptr));
860  })
861  .def_property_readonly(
862  "context",
863  [](PyIntegerSet &self) { return self.getContext().getObject(); })
864  .def(
865  "dump", [](PyIntegerSet &self) { mlirIntegerSetDump(self); },
867  .def_static(
868  "get",
869  [](intptr_t numDims, intptr_t numSymbols, py::list exprs,
870  std::vector<bool> eqFlags, DefaultingPyMlirContext context) {
871  if (exprs.size() != eqFlags.size())
872  throw py::value_error(
873  "Expected the number of constraints to match "
874  "that of equality flags");
875  if (exprs.empty())
876  throw py::value_error("Expected non-empty list of constraints");
877 
878  // Copy over to a SmallVector because std::vector has a
879  // specialization for booleans that packs data and does not
880  // expose a `bool *`.
881  SmallVector<bool, 8> flags(eqFlags.begin(), eqFlags.end());
882 
883  SmallVector<MlirAffineExpr> affineExprs;
884  pyListToVector<PyAffineExpr>(exprs, affineExprs,
885  "attempting to create an IntegerSet");
886  MlirIntegerSet set = mlirIntegerSetGet(
887  context->get(), numDims, numSymbols, exprs.size(),
888  affineExprs.data(), flags.data());
889  return PyIntegerSet(context->getRef(), set);
890  },
891  py::arg("num_dims"), py::arg("num_symbols"), py::arg("exprs"),
892  py::arg("eq_flags"), py::arg("context") = py::none())
893  .def_static(
894  "get_empty",
895  [](intptr_t numDims, intptr_t numSymbols,
896  DefaultingPyMlirContext context) {
897  MlirIntegerSet set =
898  mlirIntegerSetEmptyGet(context->get(), numDims, numSymbols);
899  return PyIntegerSet(context->getRef(), set);
900  },
901  py::arg("num_dims"), py::arg("num_symbols"),
902  py::arg("context") = py::none())
903  .def(
904  "get_replaced",
905  [](PyIntegerSet &self, py::list dimExprs, py::list symbolExprs,
906  intptr_t numResultDims, intptr_t numResultSymbols) {
907  if (static_cast<intptr_t>(dimExprs.size()) !=
909  throw py::value_error(
910  "Expected the number of dimension replacement expressions "
911  "to match that of dimensions");
912  if (static_cast<intptr_t>(symbolExprs.size()) !=
914  throw py::value_error(
915  "Expected the number of symbol replacement expressions "
916  "to match that of symbols");
917 
918  SmallVector<MlirAffineExpr> dimAffineExprs, symbolAffineExprs;
919  pyListToVector<PyAffineExpr>(
920  dimExprs, dimAffineExprs,
921  "attempting to create an IntegerSet by replacing dimensions");
922  pyListToVector<PyAffineExpr>(
923  symbolExprs, symbolAffineExprs,
924  "attempting to create an IntegerSet by replacing symbols");
925  MlirIntegerSet set = mlirIntegerSetReplaceGet(
926  self, dimAffineExprs.data(), symbolAffineExprs.data(),
927  numResultDims, numResultSymbols);
928  return PyIntegerSet(self.getContext(), set);
929  },
930  py::arg("dim_exprs"), py::arg("symbol_exprs"),
931  py::arg("num_result_dims"), py::arg("num_result_symbols"))
932  .def_property_readonly("is_canonical_empty",
933  [](PyIntegerSet &self) {
934  return mlirIntegerSetIsCanonicalEmpty(self);
935  })
936  .def_property_readonly(
937  "n_dims",
938  [](PyIntegerSet &self) { return mlirIntegerSetGetNumDims(self); })
939  .def_property_readonly(
940  "n_symbols",
941  [](PyIntegerSet &self) { return mlirIntegerSetGetNumSymbols(self); })
942  .def_property_readonly(
943  "n_inputs",
944  [](PyIntegerSet &self) { return mlirIntegerSetGetNumInputs(self); })
945  .def_property_readonly("n_equalities",
946  [](PyIntegerSet &self) {
947  return mlirIntegerSetGetNumEqualities(self);
948  })
949  .def_property_readonly("n_inequalities",
950  [](PyIntegerSet &self) {
952  })
953  .def_property_readonly("constraints", [](PyIntegerSet &self) {
954  return PyIntegerSetConstraintList(self);
955  });
956  PyIntegerSetConstraint::bind(m);
957  PyIntegerSetConstraintList::bind(m);
958 }
static void pyListToVector(const py::list &list, llvm::SmallVectorImpl< CType > &result, StringRef action)
Attempts to populate result with the content of list casted to the appropriate type (Python and C typ...
Definition: IRAffine.cpp:36
static const char kDumpDocstring[]
Definition: IRAffine.cpp:28
static bool isPermutation(std::vector< PermutationTy > permutation)
Definition: IRAffine.cpp:58
static MlirIntegerSet mlirPythonCapsuleToIntegerSet(PyObject *capsule)
Extracts an MlirIntegerSet from a capsule as produced from mlirPythonIntegerSetToCapsule.
Definition: Interop.h:360
#define MLIR_PYTHON_CAPI_PTR_ATTR
Attribute on MLIR Python objects that expose their C-API pointer.
Definition: Interop.h:95
static PyObject * mlirPythonIntegerSetToCapsule(MlirIntegerSet integerSet)
Creates a capsule object encapsulating the raw C-API MlirIntegerSet.
Definition: Interop.h:351
static MlirAffineMap mlirPythonCapsuleToAffineMap(PyObject *capsule)
Extracts an MlirAffineMap from a capsule as produced from mlirPythonAffineMapToCapsule.
Definition: Interop.h:341
#define MLIR_PYTHON_CAPI_FACTORY_ATTR
Attribute on MLIR Python objects that exposes a factory function for constructing the corresponding P...
Definition: Interop.h:108
static PyObject * mlirPythonAffineExprToCapsule(MlirAffineExpr expr)
Creates a capsule object encapsulating the raw C-API MlirAffineExpr.
Definition: Interop.h:144
static PyObject * mlirPythonAffineMapToCapsule(MlirAffineMap affineMap)
Creates a capsule object encapsulating the raw C-API MlirAffineMap.
Definition: Interop.h:332
static MlirAffineExpr mlirPythonCapsuleToAffineExpr(PyObject *capsule)
Extracts an MlirAffineExpr from a capsule as produced from mlirPythonAffineExprToCapsule.
Definition: Interop.h:153
A CRTP base class for pseudo-containers willing to support Python-type slicing access on top of index...
Definition: PybindUtils.h:208
PyMlirContextRef & getContext()
Accesses the context reference.
Definition: IRModule.h:287
Used in function arguments when None should resolve to the current context manager set instance.
Definition: IRModule.h:268
ReferrentTy * get() const
Definition: PybindUtils.h:46
Wrapper around MlirAffineExpr. Affine expressions are owned by the context.
Definition: IRModule.h:1057
static PyAffineExpr createFromCapsule(pybind11::object capsule)
Creates a PyAffineExpr from the MlirAffineExpr wrapped by a capsule.
Definition: IRAffine.cpp:360
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineExpr.
Definition: IRAffine.cpp:355
PyAffineExpr(PyMlirContextRef contextRef, MlirAffineExpr affineExpr)
Definition: IRModule.h:1059
bool operator==(const PyAffineExpr &other) const
Definition: IRAffine.cpp:351
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirAffineMap.
Definition: IRAffine.cpp:414
PyAffineMap(PyMlirContextRef contextRef, MlirAffineMap affineMap)
Definition: IRModule.h:1086
bool operator==(const PyAffineMap &other) const
Definition: IRAffine.cpp:410
static PyAffineMap createFromCapsule(pybind11::object capsule)
Creates a PyAffineMap from the MlirAffineMap wrapped by a capsule.
Definition: IRAffine.cpp:418
static PyIntegerSet createFromCapsule(pybind11::object capsule)
Creates a PyIntegerSet from the MlirAffineMap wrapped by a capsule.
Definition: IRAffine.cpp:496
bool operator==(const PyIntegerSet &other) const
Definition: IRAffine.cpp:487
pybind11::object getCapsule()
Gets a capsule wrapping the void* within the MlirIntegerSet.
Definition: IRAffine.cpp:491
PyIntegerSet(PyMlirContextRef contextRef, MlirIntegerSet integerSet)
Definition: IRModule.h:1107
static PyMlirContextRef forContext(MlirContext context)
Returns a context reference for the singleton PyMlirContext wrapper for the given context.
Definition: IRCore.cpp:591
Wrapper around the generic MlirType.
Definition: IRModule.h:810
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAConstant(MlirAffineExpr affineExpr)
Checks whether the given affine expression is a constant expression.
Definition: AffineExpr.cpp:100
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineBinaryOpExprGetLHS(MlirAffineExpr affineExpr)
Returns the left hand side affine expression of the given affine binary operation expression.
Definition: AffineExpr.cpp:187
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineMulExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine mul expression with 'lhs' and 'rhs'.
Definition: AffineExpr.cpp:133
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineConstantExprGet(MlirContext ctx, int64_t constant)
Creates an affine constant expression with 'constant' in the context.
Definition: AffineExpr.cpp:104
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineBinaryOpExprGetRHS(MlirAffineExpr affineExpr)
Returns the right hand side affine expression of the given affine binary operation expression.
Definition: AffineExpr.cpp:191
MLIR_CAPI_EXPORTED void mlirAffineExprPrint(MlirAffineExpr affineExpr, MlirStringCallback callback, void *userData)
Prints an affine expression by sending chunks of the string representation and forwarding userData to...
Definition: AffineExpr.cpp:28
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineAddExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine add expression with 'lhs' and 'rhs'.
Definition: AffineExpr.cpp:120
MLIR_CAPI_EXPORTED intptr_t mlirAffineDimExprGetPosition(MlirAffineExpr affineExpr)
Returns the position of the given affine dimension expression.
Definition: AffineExpr.cpp:76
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAAdd(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an add expression.
Definition: AffineExpr.cpp:116
MLIR_CAPI_EXPORTED bool mlirAffineExprIsABinary(MlirAffineExpr affineExpr)
Checks whether the given affine expression is binary.
Definition: AffineExpr.cpp:183
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAMul(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an mul expression.
Definition: AffineExpr.cpp:129
MLIR_CAPI_EXPORTED int64_t mlirAffineConstantExprGetValue(MlirAffineExpr affineExpr)
Returns the value of the given affine constant expression.
Definition: AffineExpr.cpp:108
MLIR_CAPI_EXPORTED MlirContext mlirAffineExprGetContext(MlirAffineExpr affineExpr)
Gets the context that owns the affine expression.
Definition: AffineExpr.cpp:20
MLIR_CAPI_EXPORTED bool mlirAffineExprIsASymbol(MlirAffineExpr affineExpr)
Checks whether the given affine expression is a symbol expression.
Definition: AffineExpr.cpp:84
MLIR_CAPI_EXPORTED bool mlirAffineExprIsACeilDiv(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an ceildiv expression.
Definition: AffineExpr.cpp:169
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineFloorDivExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine floordiv expression with 'lhs' and 'rhs'.
Definition: AffineExpr.cpp:159
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAFloorDiv(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an floordiv expression.
Definition: AffineExpr.cpp:155
MLIR_CAPI_EXPORTED bool mlirAffineExprEqual(MlirAffineExpr lhs, MlirAffineExpr rhs)
Returns true if the two affine expressions are equal.
Definition: AffineExpr.cpp:24
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineDimExprGet(MlirContext ctx, intptr_t position)
Creates an affine dimension expression with 'position' in the context.
Definition: AffineExpr.cpp:72
MLIR_CAPI_EXPORTED bool mlirAffineExprIsAMod(MlirAffineExpr affineExpr)
Checks whether the given affine expression is an mod expression.
Definition: AffineExpr.cpp:142
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineModExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine mod expression with 'lhs' and 'rhs'.
Definition: AffineExpr.cpp:146
MLIR_CAPI_EXPORTED void mlirAffineExprDump(MlirAffineExpr affineExpr)
Prints the affine expression to the standard error stream.
Definition: AffineExpr.cpp:34
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineExprCompose(MlirAffineExpr affineExpr, struct MlirAffineMap affineMap)
Composes the given map with the given expression.
Definition: AffineExpr.cpp:59
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineSymbolExprGet(MlirContext ctx, intptr_t position)
Creates an affine symbol expression with 'position' in the context.
Definition: AffineExpr.cpp:88
static bool mlirAffineExprIsNull(MlirAffineExpr affineExpr)
Returns true if the given affine expression is a null expression.
Definition: AffineExpr.h:54
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineCeilDivExprGet(MlirAffineExpr lhs, MlirAffineExpr rhs)
Creates an affine ceildiv expression with 'lhs' and 'rhs'.
Definition: AffineExpr.cpp:173
MLIR_CAPI_EXPORTED intptr_t mlirAffineSymbolExprGetPosition(MlirAffineExpr affineExpr)
Returns the position of the given affine symbol expression.
Definition: AffineExpr.cpp:92
MLIR_CAPI_EXPORTED bool mlirAffineExprIsADim(MlirAffineExpr affineExpr)
Checks whether the given affine expression is a dimension expression.
Definition: AffineExpr.cpp:68
MLIR_CAPI_EXPORTED bool mlirAffineMapEqual(MlirAffineMap a1, MlirAffineMap a2)
Checks if two affine maps are equal.
Definition: AffineMap.cpp:25
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapEmptyGet(MlirContext ctx)
Creates a zero result affine map with no dimensions or symbols in the context.
Definition: AffineMap.cpp:37
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapGet(MlirContext ctx, intptr_t dimCount, intptr_t symbolCount, intptr_t nAffineExprs, MlirAffineExpr *affineExprs)
Creates an affine map with results defined by the given list of affine expressions.
Definition: AffineMap.cpp:46
MLIR_CAPI_EXPORTED intptr_t mlirAffineMapGetNumDims(MlirAffineMap affineMap)
Returns the number of dimensions of the given affine map.
Definition: AffineMap.cpp:94
MLIR_CAPI_EXPORTED MlirContext mlirAffineMapGetContext(MlirAffineMap affineMap)
Gets the context that the given affine map was created with.
Definition: AffineMap.cpp:21
MLIR_CAPI_EXPORTED MlirAffineExpr mlirAffineMapGetResult(MlirAffineMap affineMap, intptr_t pos)
Returns the result at the given position.
Definition: AffineMap.cpp:106
MLIR_CAPI_EXPORTED void mlirAffineMapDump(MlirAffineMap affineMap)
Prints the affine map to the standard error stream.
Definition: AffineMap.cpp:35
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapConstantGet(MlirContext ctx, int64_t val)
Creates a single constant result affine map in the context.
Definition: AffineMap.cpp:54
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapMultiDimIdentityGet(MlirContext ctx, intptr_t numDims)
Creates an affine map with 'numDims' identity in the context.
Definition: AffineMap.cpp:58
MLIR_CAPI_EXPORTED void mlirAffineMapPrint(MlirAffineMap affineMap, MlirStringCallback callback, void *userData)
Prints an affine map by sending chunks of the string representation and forwarding userData tocallbac...
Definition: AffineMap.cpp:29
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapGetMinorSubMap(MlirAffineMap affineMap, intptr_t numResults)
Returns the affine map consisting of the most minor numResults results.
Definition: AffineMap.cpp:136
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapGetMajorSubMap(MlirAffineMap affineMap, intptr_t numResults)
Returns the affine map consisting of the most major numResults results.
Definition: AffineMap.cpp:131
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapGetSubMap(MlirAffineMap affineMap, intptr_t size, intptr_t *resultPos)
Returns the affine map consisting of the resultPos subset.
Definition: AffineMap.cpp:122
MLIR_CAPI_EXPORTED intptr_t mlirAffineMapGetNumResults(MlirAffineMap affineMap)
Returns the number of results of the given affine map.
Definition: AffineMap.cpp:102
MLIR_CAPI_EXPORTED intptr_t mlirAffineMapGetNumSymbols(MlirAffineMap affineMap)
Returns the number of symbols of the given affine map.
Definition: AffineMap.cpp:98
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapPermutationGet(MlirContext ctx, intptr_t size, unsigned *permutation)
Creates an affine map with a permutation expression and its size in the context.
Definition: AffineMap.cpp:68
MLIR_CAPI_EXPORTED void mlirAffineMapCompressUnusedSymbols(MlirAffineMap *affineMaps, intptr_t size, void *result, void(*populateResult)(void *res, intptr_t idx, MlirAffineMap m))
Returns the simplified affine map resulting from dropping the symbols that do not appear in any of th...
Definition: AffineMap.cpp:150
MLIR_CAPI_EXPORTED bool mlirAffineMapIsProjectedPermutation(MlirAffineMap affineMap)
Checks whether the given affine map represents a subset of a symbol-less permutation map.
Definition: AffineMap.cpp:114
MLIR_CAPI_EXPORTED intptr_t mlirAffineMapGetNumInputs(MlirAffineMap affineMap)
Returns the number of inputs (dimensions + symbols) of the given affine map.
Definition: AffineMap.cpp:110
MLIR_CAPI_EXPORTED bool mlirAffineMapIsPermutation(MlirAffineMap affineMap)
Checks whether the given affine map represents a symbol-less permutation map.
Definition: AffineMap.cpp:118
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapReplace(MlirAffineMap affineMap, MlirAffineExpr expression, MlirAffineExpr replacement, intptr_t numResultDims, intptr_t numResultSyms)
Apply AffineExpr::replace(map) to each of the results and return a new new AffineMap with the new res...
Definition: AffineMap.cpp:141
MLIR_CAPI_EXPORTED MlirAffineMap mlirAffineMapMinorIdentityGet(MlirContext ctx, intptr_t dims, intptr_t results)
Creates an identity affine map on the most minor dimensions in the context.
Definition: AffineMap.cpp:63
static bool mlirAffineMapIsNull(MlirAffineMap affineMap)
Checks whether an affine map is null.
Definition: AffineMap.h:47
MLIR_CAPI_EXPORTED intptr_t mlirIntegerSetGetNumConstraints(MlirIntegerSet set)
Returns the number of constraints (equalities + inequalities) in the given set.
Definition: IntegerSet.cpp:85
MLIR_CAPI_EXPORTED MlirAffineExpr mlirIntegerSetGetConstraint(MlirIntegerSet set, intptr_t pos)
Returns pos-th constraint of the set.
Definition: IntegerSet.cpp:97
MLIR_CAPI_EXPORTED bool mlirIntegerSetIsCanonicalEmpty(MlirIntegerSet set)
Checks whether the given set is a canonical empty set, e.g., the set returned by mlirIntegerSetEmptyG...
Definition: IntegerSet.cpp:69
MLIR_CAPI_EXPORTED intptr_t mlirIntegerSetGetNumInputs(MlirIntegerSet set)
Returns the number of inputs (dimensions + symbols) in the given set.
Definition: IntegerSet.cpp:81
MLIR_CAPI_EXPORTED MlirIntegerSet mlirIntegerSetEmptyGet(MlirContext context, intptr_t numDims, intptr_t numSymbols)
Gets or creates a new canonically empty integer set with the give number of dimensions and symbols in...
Definition: IntegerSet.cpp:35
MLIR_CAPI_EXPORTED MlirIntegerSet mlirIntegerSetGet(MlirContext context, intptr_t numDims, intptr_t numSymbols, intptr_t numConstraints, const MlirAffineExpr *constraints, const bool *eqFlags)
Gets or creates a new integer set in the given context.
Definition: IntegerSet.cpp:42
MLIR_CAPI_EXPORTED intptr_t mlirIntegerSetGetNumEqualities(MlirIntegerSet set)
Returns the number of equalities in the given set.
Definition: IntegerSet.cpp:89
MLIR_CAPI_EXPORTED intptr_t mlirIntegerSetGetNumDims(MlirIntegerSet set)
Returns the number of dimensions in the given set.
Definition: IntegerSet.cpp:73
MLIR_CAPI_EXPORTED MlirIntegerSet mlirIntegerSetReplaceGet(MlirIntegerSet set, const MlirAffineExpr *dimReplacements, const MlirAffineExpr *symbolReplacements, intptr_t numResultDims, intptr_t numResultSymbols)
Gets or creates a new integer set in which the values and dimensions of the given set are replaced wi...
Definition: IntegerSet.cpp:56
MLIR_CAPI_EXPORTED intptr_t mlirIntegerSetGetNumSymbols(MlirIntegerSet set)
Returns the number of symbols in the given set.
Definition: IntegerSet.cpp:77
static bool mlirIntegerSetIsNull(MlirIntegerSet set)
Checks whether an integer set is a null object.
Definition: IntegerSet.h:46
MLIR_CAPI_EXPORTED MlirContext mlirIntegerSetGetContext(MlirIntegerSet set)
Gets the context in which the given integer set lives.
Definition: IntegerSet.cpp:19
MLIR_CAPI_EXPORTED void mlirIntegerSetPrint(MlirIntegerSet set, MlirStringCallback callback, void *userData)
Prints an integer set by sending chunks of the string representation and forwarding userData tocallba...
Definition: IntegerSet.cpp:27
MLIR_CAPI_EXPORTED bool mlirIntegerSetEqual(MlirIntegerSet s1, MlirIntegerSet s2)
Checks if two integer set objects are equal.
Definition: IntegerSet.cpp:23
MLIR_CAPI_EXPORTED bool mlirIntegerSetIsConstraintEq(MlirIntegerSet set, intptr_t pos)
Returns true of the pos-th constraint of the set is an equality constraint, false otherwise.
Definition: IntegerSet.cpp:101
MLIR_CAPI_EXPORTED void mlirIntegerSetDump(MlirIntegerSet set)
Prints an integer set to the standard error stream.
Definition: IntegerSet.cpp:33
MLIR_CAPI_EXPORTED intptr_t mlirIntegerSetGetNumInequalities(MlirIntegerSet set)
Returns the number of inequalities in the given set.
Definition: IntegerSet.cpp:93
llvm::hash_code hash_value(const MPInt &x)
Redeclarations of friend declaration above to make it discoverable by lookups.
Definition: MPInt.cpp:15
void populateIRAffine(pybind11::module &m)
This header declares functions that assit transformations in the MemRef dialect.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
Accumulates into a python string from a method that accepts an MlirStringCallback.
Definition: PybindUtils.h:101
pybind11::list parts
Definition: PybindUtils.h:102
pybind11::str join()
Definition: PybindUtils.h:116
MlirStringCallback getCallback()
Definition: PybindUtils.h:106