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