[Mlir-commits] [mlir] [Python] Develop python bindings for Presburger library (PR #113233)
Maksim Levental
llvmlistbot at llvm.org
Wed Nov 20 22:39:34 PST 2024
================
@@ -0,0 +1,767 @@
+//===- Presburger.cpp - Presburger library --------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir-c/Presburger.h"
+#include "mlir-c/Bindings/Python/Interop.h"
+#include "llvm/ADT/ScopeExit.h"
+#include <pybind11/detail/common.h>
+#include <pybind11/pybind11.h>
+
+namespace py = pybind11;
+
+static bool isSignedIntegerFormat(std::string_view format) {
+ if (format.empty())
+ return false;
+ char code = format[0];
+ return code == 'i' || code == 'b' || code == 'h' || code == 'l' ||
+ code == 'q';
+}
+
+namespace {
+struct PyPresburgerIntegerRelation {
+ PyPresburgerIntegerRelation(MlirPresburgerIntegerRelation relation)
+ : relation(relation) {}
+ PyPresburgerIntegerRelation(const PyPresburgerIntegerRelation &other) =
+ default;
+ PyPresburgerIntegerRelation(PyPresburgerIntegerRelation &&other) noexcept
+ : relation(other.relation) {
+ other.relation.ptr = nullptr;
+ }
+ virtual ~PyPresburgerIntegerRelation() {
+ if (relation.ptr) {
+ mlirPresburgerIntegerRelationDestroy(relation);
+ relation.ptr = {nullptr};
+ }
+ }
+ static std::unique_ptr<PyPresburgerIntegerRelation>
+ getFromNumConstrainsAndVars(uint64_t numReservedInequalities,
+ uint64_t numReservedEqualities,
+ uint64_t numReservedCols);
+ static std::unique_ptr<PyPresburgerIntegerRelation>
+ getFromBuffers(py::buffer inequalitiesCoefficients,
+ py::buffer equalityCoefficients, unsigned numDomainVars,
+ unsigned numRangeVars);
+ py::object getCapsule();
+ static void bind(py::module &module);
+ MlirPresburgerIntegerRelation relation{nullptr};
+};
+
+/// A utility that enables accessing/modifying the underlying coefficients
+/// easier.
+struct PyPresburgerTableau {
+ enum class Kind { Equalities, Inequalities };
+ PyPresburgerTableau(MlirPresburgerIntegerRelation relation, Kind kind)
+ : relation(relation), kind(kind) {}
+ static void bind(py::module &module);
+ int64_t at64(int64_t row, int64_t col) const {
+ if (kind == Kind::Equalities)
+ return mlirPresburgerIntegerRelationAtEq64(relation, row, col);
+ return mlirPresburgerIntegerRelationAtIneq64(relation, row, col);
+ }
+ MlirPresburgerIntegerRelation relation;
+ Kind kind;
+};
+
+struct PyPresburgerMaybeOptimum {
+ PyPresburgerMaybeOptimum(MlirMaybeOptimum optimum)
+ : kind(optimum.kind), integerPoint(optimum.vector.data),
+ integerPointSize(optimum.vector.size) {}
+ ~PyPresburgerMaybeOptimum() {
+ if (integerPoint) {
+ delete[] integerPoint;
+ integerPoint = nullptr;
+ }
+ }
+ static void bind(py::module &module);
+ MlirPresburgerOptimumKind kind;
+ const int64_t *integerPoint{nullptr};
+ int64_t integerPointSize;
+};
+} // namespace
+
+std::unique_ptr<PyPresburgerIntegerRelation>
+PyPresburgerIntegerRelation::getFromBuffers(py::buffer inequalitiesCoefficients,
+ py::buffer equalityCoefficients,
+ unsigned numDomainVars,
+ unsigned numRangeVars) {
+ // Request a contiguous view. In exotic cases, this will cause a copy.
+ int flags = PyBUF_ND;
+ flags |= PyBUF_FORMAT;
+ // Get the view of the inequality coefficients.
+ std::unique_ptr<Py_buffer> ineqView = std::make_unique<Py_buffer>();
+ if (PyObject_GetBuffer(inequalitiesCoefficients.ptr(), ineqView.get(),
+ flags) != 0)
+ throw py::error_already_set();
+ auto freeIneqBuffer = llvm::make_scope_exit([&]() {
+ if (ineqView)
+ PyBuffer_Release(ineqView.get());
+ });
+ if (!PyBuffer_IsContiguous(ineqView.get(), 'A'))
+ throw std::invalid_argument("Contiguous buffer is required.");
+ if (!isSignedIntegerFormat(ineqView->format) || ineqView->itemsize != 8)
+ throw std::invalid_argument(
+ std::string("IntegerRelation can only be created from a buffer of "
+ "i64 values but got buffer with format: ") +
+ std::string(ineqView->format));
+ if (ineqView->ndim != 2)
+ throw std::invalid_argument(
+ std::string("expected 2d inequality coefficients but got rank ") +
+ std::to_string(ineqView->ndim));
+ unsigned numInequalities = ineqView->shape[0];
+ // Get the view of the eequality coefficients.
+ std::unique_ptr<Py_buffer> eqView = std::make_unique<Py_buffer>();
+ if (PyObject_GetBuffer(equalityCoefficients.ptr(), eqView.get(), flags) != 0)
+ throw py::error_already_set();
+ auto freeEqBuffer = llvm::make_scope_exit([&]() {
+ if (eqView)
+ PyBuffer_Release(eqView.get());
+ });
+ if (!PyBuffer_IsContiguous(eqView.get(), 'A'))
+ throw std::invalid_argument("Contiguous buffer is required.");
+ if (!isSignedIntegerFormat(eqView->format) || eqView->itemsize != 8)
+ throw std::invalid_argument(
+ std::string("IntegerRelation can only be created from a buffer of "
+ "i64 values but got buffer with format: ") +
+ std::string(eqView->format));
+ if (eqView->ndim != 2)
+ throw std::invalid_argument(
+ std::string("expected 2d equality coefficients but got rank ") +
+ std::to_string(eqView->ndim));
+ unsigned numEqualities = eqView->shape[0];
+ if (eqView->shape[1] != numDomainVars + numRangeVars + 1 ||
+ eqView->shape[1] != ineqView->shape[1])
+ throw std::invalid_argument(
+ "expected number of columns of inequality and equality coefficient "
+ "matrices to equal numRangeVars + numDomainVars + 1");
+ MlirPresburgerIntegerRelation relation =
+ mlirPresburgerIntegerRelationCreateFromCoefficients(
+ reinterpret_cast<const int64_t *>(ineqView->buf), numInequalities,
+ reinterpret_cast<const int64_t *>(eqView->buf), numEqualities,
+ numDomainVars, numRangeVars);
+ return std::make_unique<PyPresburgerIntegerRelation>(relation);
+}
+
+std::unique_ptr<PyPresburgerIntegerRelation>
+PyPresburgerIntegerRelation::getFromNumConstrainsAndVars(
+ uint64_t numReservedInequalities, uint64_t numReservedEqualities,
+ uint64_t numReservedCols) {
+ MlirPresburgerIntegerRelation relation = mlirPresburgerIntegerRelationCreate(
+ numReservedInequalities, numReservedEqualities, numReservedCols);
+ return std::make_unique<PyPresburgerIntegerRelation>(relation);
+}
+
+py::object PyPresburgerIntegerRelation::getCapsule() {
+ throw std::invalid_argument("unimplemented");
+}
+
+void PyPresburgerTableau::bind(py::module &m) {
+ py::class_<PyPresburgerTableau>(m, "IntegerRelationTableau",
+ py::module_local())
+ .def("__getitem__", [](PyPresburgerTableau &self,
+ const py::tuple &index) {
+ return self.at64(index[0].cast<int64_t>(), index[1].cast<int64_t>());
+ });
+}
+
+void PyPresburgerMaybeOptimum::bind(py::module &m) {
+ py::class_<PyPresburgerMaybeOptimum>(m, "IntegerRelationMaybeOptimum",
+ py::module_local())
+ .def("is_empty",
+ [](PyPresburgerMaybeOptimum &self) {
+ return self.kind == MlirPresburgerOptimumKind::Empty;
+ })
+ .def("is_unbounded",
+ [](PyPresburgerMaybeOptimum &self) {
+ return self.kind == MlirPresburgerOptimumKind::Unbounded;
+ })
+ .def("is_bounded",
+ [](PyPresburgerMaybeOptimum &self) {
+ return self.kind == MlirPresburgerOptimumKind::Bounded;
+ })
+ .def("get_integer_point", [](PyPresburgerMaybeOptimum &self) {
+ if (self.kind != MlirPresburgerOptimumKind::Bounded)
+ return std::vector<int64_t>();
+ std::vector<int64_t> r{self.integerPoint,
+ self.integerPoint + self.integerPointSize};
+ return r;
+ });
+}
+
+void PyPresburgerIntegerRelation::bind(py::module &m) {
+ py::class_<PyPresburgerIntegerRelation>(m, "IntegerRelation",
+ py::module_local())
+ .def(py::init<>(&PyPresburgerIntegerRelation::getFromBuffers),
+ py::arg("inequalities_coefficients"),
+ py::arg("equalities_coefficients"), py::arg("num_domain_vars"),
+ py::arg("num_range_vars"))
+ .def(
+ py::init<>(&PyPresburgerIntegerRelation::getFromNumConstrainsAndVars),
+ py::arg("num_reserved_inequalities"),
+ py::arg("num_reserved_equalities"), py::arg("num_reserved_cols"))
+ .def_property_readonly(MLIR_PYTHON_CAPI_PTR_ATTR,
+ &PyPresburgerIntegerRelation::getCapsule)
+ .def("__eq__",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationIsEqual(self.relation,
+ other.relation);
+ })
+ .def(
+ "append",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationAppend(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "intersect",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ PyPresburgerIntegerRelation intersection(
+ mlirPresburgerIntegerRelationIntersect(self.relation,
+ other.relation));
+ return intersection;
+ },
+ py::arg("other"))
+ .def(
+ "is_equal",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationIsEqual(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "is_obviously_equal",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationIsObviouslyEqual(
+ self.relation, other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "is_subset_of",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationIsSubsetOf(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "merge_and_align_symbols",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationMergeAndAlignSymbols(
+ self.relation, other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "merge_local_vars",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationMergeLocalVars(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "compose",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationCompose(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "apply_domain",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationApplyDomain(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "apply_range",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationApplyRange(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "merge_and_composite",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ return mlirPresburgerIntegerRelationMergeAndCompose(self.relation,
+ other.relation);
+ },
+ py::arg("other"))
+ .def(
+ "union_bounding_box",
+ [](PyPresburgerIntegerRelation &self,
+ PyPresburgerIntegerRelation &other) {
+ auto r = mlirPresburgerIntegerRelationUnionBoundingBox(
+ self.relation, other.relation);
+ return mlirLogicalResultIsSuccess(r);
+ },
+ py::arg("other"))
+ .def(
+ "inequalities",
+ [](PyPresburgerIntegerRelation &self) {
+ PyPresburgerTableau tableau(
+ self.relation, PyPresburgerTableau::Kind::Inequalities);
+ return tableau;
+ },
+ py::keep_alive<0, 1>())
+ .def(
+ "equalities",
+ [](PyPresburgerIntegerRelation &self) {
+ PyPresburgerTableau tableau(self.relation,
+ PyPresburgerTableau::Kind::Equalities);
+ return tableau;
+ },
+ py::keep_alive<0, 1>())
+ .def("get_equality",
+ [](PyPresburgerIntegerRelation &self, int64_t row) {
+ unsigned numCol =
+ mlirPresburgerIntegerRelationNumCols(self.relation);
+ std::vector<int64_t> result(numCol);
+ for (unsigned i = 0; i < numCol; i++)
+ result[i] =
+ mlirPresburgerIntegerRelationAtEq64(self.relation, row, i);
+ return result;
+ })
+ .def("get_inequality",
+ [](PyPresburgerIntegerRelation &self, int64_t row) {
+ unsigned numCol =
+ mlirPresburgerIntegerRelationNumCols(self.relation);
+ std::vector<int64_t> result(numCol);
+ for (unsigned i = 0; i < numCol; i++)
+ result[i] =
+ mlirPresburgerIntegerRelationAtIneq64(self.relation, row, i);
+ return result;
+ })
+ .def(
+ "get_num_vars_of_kind",
+ [](PyPresburgerIntegerRelation &self,
+ MlirPresburgerVariableKind kind) {
+ return mlirPresburgerIntegerRelationGetNumVarKind(self.relation,
+ kind);
+ },
+ py::arg("kind"))
+ .def(
+ "get_var_kind_offset",
+ [](PyPresburgerIntegerRelation &self,
+ MlirPresburgerVariableKind kind) {
+ return mlirPresburgerIntegerRelationGetVarKindOffset(self.relation,
+ kind);
+ },
+ py::arg("kind"))
+ .def(
+ "get_var_kind_end",
+ [](PyPresburgerIntegerRelation &self,
+ MlirPresburgerVariableKind kind) {
+ return mlirPresburgerIntegerRelationGetVarKindEnd(self.relation,
+ kind);
+ },
+ py::arg("kind"))
+ .def(
+ "get_var_kind_overlap",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerVariableKind kind,
+ int64_t varStart, int64_t varLimit) {
+ return mlirPresburgerIntegerRelationGetVarKindOverLap(
+ self.relation, kind, varStart, varLimit);
+ },
+ py::arg("kind"), py::arg("start"), py::arg("limit"))
+ .def(
+ "get_var_kind_at",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos) {
+ return mlirPresburgerIntegerRelationGetVarKindAt(self.relation,
+ pos);
+ },
+ py::arg("pos"))
+ .def(
+ "get_constant_bound",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerBoundType type,
+ uint64_t pos) -> std::optional<int64_t> {
+ auto r = mlirPresburgerIntegerRelationGetConstantBound64(
+ self.relation, type, pos);
+ if (!r.hasValue)
+ return std::nullopt;
+ return r.value;
+ },
+ py::arg("bound_type"), py::arg("pos"))
+ .def("is_full_dim",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationIsFullDim(self.relation);
+ })
+ .def(
+ "contains_point",
+ [](PyPresburgerIntegerRelation &self, std::vector<int64_t> &point) {
+ return mlirPresburgerIntegerRelationContainsPoint(
+ self.relation, point.data(), point.size());
+ },
+ py::arg("point"))
+ .def("has_only_div_locals",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationHasOnlyDivLocals(
+ self.relation);
+ })
+ .def("remove_trivial_equalities",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationRemoveTrivialEqualities(
+ self.relation);
+ })
+ .def(
+ "insert_var",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerVariableKind kind,
+ uint64_t pos, uint64_t num) {
+ return mlirPresburgerIntegerRelationInsertVar(self.relation, kind,
+ pos, num);
+ },
+ py::arg("kind"), py::arg("pos"), py::arg("num") = 1)
+ .def(
+ "append_var",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerVariableKind kind,
+ uint64_t num) {
+ return mlirPresburgerIntegerRelationAppendVar(self.relation, kind,
+ num);
+ },
+ py::arg("kind"), py::arg("num") = 1)
+ .def(
+ "add_equality",
+ [](PyPresburgerIntegerRelation &self,
+ const std::vector<int64_t> &eq) {
+ return mlirPresburgerIntegerRelationAddEquality(
+ self.relation, eq.data(), eq.size());
+ },
+ py::arg("coefficients"))
+ .def(
+ "add_inequality",
+ [](PyPresburgerIntegerRelation &self,
+ const std::vector<int64_t> &inEq) {
+ return mlirPresburgerIntegerRelationAddInequality(
+ self.relation, inEq.data(), inEq.size());
+ },
+ py::arg("coefficients"))
+ .def(
+ "eliminate_redundant_local_var",
+ [](PyPresburgerIntegerRelation &self, uint64_t posA, uint64_t posB) {
+ return mlirPresburgerIntegerRelationEliminateRedundantLocalVar(
+ self.relation, posA, posB);
+ },
+ py::arg("pos_a"), py::arg("pos_b"))
+ .def(
+ "remove_var_of_kind",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerVariableKind kind,
+ uint64_t pos) {
+ return mlirPresburgerIntegerRelationRemoveVarKind(self.relation,
+ kind, pos);
+ },
+ py::arg("kind"), py::arg("pos"))
+ .def(
+ "remove_var_range_of_kind",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerVariableKind kind,
+ uint64_t varStart, uint64_t varLimit) {
+ return mlirPresburgerIntegerRelationRemoveVarRangeKind(
+ self.relation, kind, varStart, varLimit);
+ },
+ py::arg("kind"), py::arg("start"), py::arg("limit"))
+ .def(
+ "remove_var",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos) {
+ return mlirPresburgerIntegerRelationRemoveVar(self.relation, pos);
+ },
+ py::arg("pos"))
+ .def(
+ "remove_equality",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos) {
+ return mlirPresburgerIntegerRelationRemoveEquality(self.relation,
+ pos);
+ },
+ py::arg("pos"))
+ .def(
+ "remove_inequality",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos) {
+ return mlirPresburgerIntegerRelationRemoveInequality(self.relation,
+ pos);
+ },
+ py::arg("pos"))
+ .def(
+ "remove_equality_range",
+ [](PyPresburgerIntegerRelation &self, uint64_t start, uint64_t end) {
+ return mlirPresburgerIntegerRelationRemoveEqualityRange(
+ self.relation, start, end);
+ },
+ py::arg("start"), py::arg("end"))
+ .def(
+ "remove_inequality_range",
+ [](PyPresburgerIntegerRelation &self, uint64_t start, uint64_t end) {
+ return mlirPresburgerIntegerRelationRemoveInequalityRange(
+ self.relation, start, end);
+ },
+ py::arg("start"), py::arg("end"))
+ .def(
+ "find_integer_lex_min",
+ [](PyPresburgerIntegerRelation &self) {
+ auto r =
+ mlirPresburgerIntegerRelationFindIntegerLexMin(self.relation);
+ auto mayBeOptimum = std::make_unique<PyPresburgerMaybeOptimum>(r);
+ return mayBeOptimum.release();
+ },
+ py::return_value_policy::take_ownership)
+ .def("find_integer_sample",
+ [](PyPresburgerIntegerRelation &self)
+ -> std::optional<std::vector<int64_t>> {
+ auto r =
+ mlirPresburgerIntegerRelationFindIntegerSample(self.relation);
+ if (!r.hasValue)
+ return std::nullopt;
+ std::vector<int64_t> integerSample{r.data, r.data + r.size};
+ return integerSample;
+ })
+ .def("compute_volume",
+ [](PyPresburgerIntegerRelation &self) -> std::optional<int64_t> {
+ auto r = mlirPresburgerIntegerRelationComputeVolume(self.relation);
+ if (!r.hasValue)
+ return std::nullopt;
+ return r.value;
+ })
+ .def(
+ "swap_var",
+ [](PyPresburgerIntegerRelation &self, uint64_t posA, uint64_t posB) {
+ return mlirPresburgerIntegerRelationSwapVar(self.relation, posA,
+ posB);
+ },
+ py::arg("pos_a"), py::arg("pos_b"))
+ .def("clear_constraints",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationClearConstraints(
+ self.relation);
+ })
+ .def(
+ "set_and_eliminate",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos,
+ std::vector<int64_t> &values) {
+ return mlirPresburgerIntegerRelationSetAndEliminate(
+ self.relation, pos, values.data(), values.size());
+ },
+ py::arg("pos"), py::arg("values"))
+ .def(
+ "remove_independent_constraints",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos, uint64_t num) {
+ return mlirPresburgerIntegerRelationRemoveIndependentConstraints(
+ self.relation, pos, num);
+ },
+ py::arg("pos"), py::arg("num"))
+ .def(
+ "is_hyper_rectangular",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos, uint64_t num) {
+ return mlirPresburgerIntegerRelationIsHyperRectangular(
+ self.relation, pos, num);
+ },
+ py::arg("pos"), py::arg("num"))
+ .def("remove_trivial_redundancy",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationRemoveTrivialRedundancy(
+ self.relation);
+ })
+ .def("remove_redundant_inequalities",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationRemoveRedundantInequalities(
+ self.relation);
+ })
+ .def("remove_redundant_constraints",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationRemoveRedundantConstraints(
+ self.relation);
+ })
+ .def("remove_duplicate_divs",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationRemoveDuplicateDivs(
+ self.relation);
+ })
+ .def("simplify",
+ [](PyPresburgerIntegerRelation &self) {
+ return mlirPresburgerIntegerRelationSimplify(self.relation);
+ })
+ .def(
+ "convert_var_kind",
+ [](PyPresburgerIntegerRelation &self,
+ MlirPresburgerVariableKind srcKind, uint64_t vatStart,
+ uint64_t varLimit, MlirPresburgerVariableKind dstKind,
+ py::object &pos) {
+ if (pos.is_none())
+ return mlirPresburgerIntegerRelationConvertVarKindNoPos(
+ self.relation, srcKind, vatStart, varLimit, dstKind);
+ return mlirPresburgerIntegerRelationConvertVarKind(
+ self.relation, srcKind, vatStart, varLimit, dstKind,
+ pos.cast<uint64_t>());
+ },
+ py::arg("src_kind"), py::arg("start"), py::arg("limit"),
+ py::arg("dst_kind"), py::arg("pos") = py::none())
+ .def(
+ "convert_to_local",
+ [](PyPresburgerIntegerRelation &self,
+ MlirPresburgerVariableKind srcKind, uint64_t vatStart,
+ uint64_t varLimit) {
+ return mlirPresburgerIntegerRelationConvertVarKindNoPos(
+ self.relation, srcKind, vatStart, varLimit,
+ MlirPresburgerVariableKind::Local);
+ },
+ py::arg("src_kind"), py::arg("start"), py::arg("limit"))
+ .def(
+ "add_bound",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerBoundType type,
+ uint64_t pos, int64_t value) {
+ return mlirPresburgerIntegerRelationAddBound(self.relation, type,
+ pos, value);
+ },
+ py::arg("bound_type"), py::arg("pos"), py::arg("value"))
+ .def(
+ "add_bound",
+ [](PyPresburgerIntegerRelation &self, MlirPresburgerBoundType type,
+ std::vector<int64_t> &expr, int64_t value) {
+ return mlirPresburgerIntegerRelationAddBoundExpr(
+ self.relation, type, expr.data(), expr.size(), value);
+ },
+ py::arg("bound_type"), py::arg("expr"), py::arg("value"))
+ .def(
+ "constant_fold_var",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos) {
+ auto r = mlirPresburgerIntegerRelationConstantFoldVar(self.relation,
+ pos);
+ return mlirLogicalResultIsSuccess(r);
+ },
+ py::arg("pos"))
+ .def(
+ "constant_fold_var_range",
+ [](PyPresburgerIntegerRelation &self, uint64_t pos, uint64_t num) {
+ return mlirPresburgerIntegerRelationConstantFoldVarRange(
+ self.relation, pos, num);
+ },
+ py::arg("pos"), py::arg("num"))
+ .def_property_readonly(
----------------
makslevental wrote:
> However, this is readonly. Looks like we can't set individual element of internal
You can make it writeable:
```c++
py::class_<Pet>(m, "Pet")
.def(py::init<const std::string &>())
.def_property("name", &Pet::getName, &Pet::setName)
```
ctrl+f `call the setter and getter functions` @ https://pybind11.readthedocs.io/en/stable/classes.html
https://github.com/llvm/llvm-project/pull/113233
More information about the Mlir-commits
mailing list