[Mlir-commits] [mlir] [MLIR][Presburger] Generating functions and quasi-polynomials for Barvinok's algorithm (PR #75702)

Arjun P llvmlistbot at llvm.org
Sat Dec 16 08:42:12 PST 2023


================
@@ -0,0 +1,235 @@
+//===- Barvinok.h - Barvinok's Algorithm -----------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Functions and classes for Barvinok's algorithm in MLIR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_ANALYSIS_PRESBURGER_BARVINOK_H
+#define MLIR_ANALYSIS_PRESBURGER_BARVINOK_H
+
+#include "mlir/Analysis/Presburger/Fraction.h"
+#include "mlir/Analysis/Presburger/IntegerRelation.h"
+#include "mlir/Analysis/Presburger/Matrix.h"
+#include "mlir/Analysis/Presburger/PresburgerSpace.h"
+#include "mlir/Analysis/Presburger/Utils.h"
+#include "mlir/Support/LogicalResult.h"
+#include <optional>
+
+namespace mlir {
+namespace presburger {
+
+// The H (inequality) representation of both general
+// polyhedra and cones specifically is an integer relation.
+using PolyhedronH = IntegerRelation;
+using ConeH = PolyhedronH;
+
+// The V (generator) representation of both general
+// polyhedra and cones specifically is simply a matrix
+// whose rows are the generators.
+using PolyhedronV = Matrix<MPInt>;
+using ConeV = PolyhedronV;
+
+// A parametric point is a vector, each of whose elements
+// is an affine function of n parameters. Each row
+// in the matrix represents the affine function and
+// has n+1 elements.
+using ParamPoint = Matrix<Fraction>;
+
+// A point is simply a vector.
+using Point = SmallVector<Fraction>;
+
+// A class to describe the type of generating function
+// used to enumerate the integer points in a polytope.
+// Consists of a set of terms, where the ith term has
+// * a sign, ±1, stored in `signs[i]`
+// * a numerator, of the form x^{n},
+//      where n, stored in `numerators[i]`,
+//      is a parametric point (a vertex).
+// * a denominator, of the form (1 - x^{d1})...(1 - x^{dn}),
+//      where each dj, stored in `denominators[i][j]`,
+//      is a vector (a generator).
+class GeneratingFunction {
+public:
+  GeneratingFunction(SmallVector<int, 16> s, std::vector<ParamPoint> nums,
+                     std::vector<std::vector<Point>> dens)
+      : signs(s), numerators(nums), denominators(dens){};
+
+  // Find the number of parameters involved in the function
+  // from the dimensionality of the affine functions.
+  unsigned getNumParams() {
+    for (auto term : numerators)
+      // The number of elements in the affine function is
+      // one more than the number of parameters.
+      return (term.getNumColumns() - 1);
+    // The polynomial can be treated as having any number
+    // of parameters.
+    return -1;
+  }
+
+  bool operator==(const GeneratingFunction &gf) const {
+    if (signs != gf.signs || numerators != gf.numerators ||
+        denominators != gf.denominators)
+      return false;
+    return true;
+  }
+
+  GeneratingFunction operator+(const GeneratingFunction &gf) {
+    bool sameNumParams = (getNumParams() == -1) || (gf.getNumParams() == -1) ||
+                         (getNumParams() == gf.getNumParams());
+    assert(
+        sameNumParams &&
+        "two generators with different numbers of parameters cannot be added!");
+    signs.insert(signs.end(), gf.signs.begin(), gf.signs.end());
+    numerators.insert(numerators.end(), gf.numerators.begin(),
+                      gf.numerators.end());
+    denominators.insert(denominators.end(), gf.denominators.begin(),
+                        gf.denominators.end());
+    return *this;
+  }
+
+  llvm::raw_ostream &print(llvm::raw_ostream &os) const {
+    for (unsigned i = 0; i < signs.size(); i++) {
+      if (signs[i] == 1)
+        os << "+";
+      else
+        os << "-";
+
+      os << "*(x^[";
----------------
Superty wrote:

I don't understand why the `*` is here. You can remove it along with the brackets around the numerator. And add spaces on both sides of the +-.

https://github.com/llvm/llvm-project/pull/75702


More information about the Mlir-commits mailing list