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

Arjun P llvmlistbot at llvm.org
Tue Dec 19 09:06:10 PST 2023


================
@@ -0,0 +1,113 @@
+//===- QuasiPolynomial.h - Quasipolynomial Class ----------------*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Definition of the QuasiPolynomial class for Barvinok's algorithm,
+// which represents a single-valued function on a set of parameters.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_ANALYSIS_PRESBURGER_QUASIPOLYNOMIAL_H
+#define MLIR_ANALYSIS_PRESBURGER_QUASIPOLYNOMIAL_H
+
+#include "mlir/Analysis/Presburger/Fraction.h"
+#include "mlir/Analysis/Presburger/Matrix.h"
+
+namespace mlir {
+namespace presburger {
+
+// A class to describe the quasi-polynomials obtained by
+// substituting the unit vector in the type of generating
+// function described above.
+// Consists of a set of terms.
+// The ith term is a constant `coefficients[i]`, multiplied
+// by the product of a set of affine functions on n parameters.
+// Represents functions f : Q^n -> Q of the form
+//
+// f(x) = \sum_i c_i * \prod_j ⌊g_{ij}(x)⌋
+//
+// where c_i \in Q and
+// g_{ij} : Q^n -> Q are affine functionals.
+class QuasiPolynomial {
+public:
+  QuasiPolynomial(unsigned numParam, SmallVector<Fraction> coeffs = {},
+                  std::vector<std::vector<SmallVector<Fraction>>> aff = {});
+
+  unsigned getNumParams();
+  SmallVector<Fraction> getCoefficients();
+  std::vector<std::vector<SmallVector<Fraction>>> getAffine();
+
+  QuasiPolynomial operator+(QuasiPolynomial &x) {
+    assert(numParam == x.getNumParams() &&
+           "two quasi-polynomials with different numbers of parameters cannot "
+           "be added!");
+    SmallVector<Fraction> sumCoeffs;
+    sumCoeffs.append(coefficients);
+    sumCoeffs.append(x.coefficients);
+    std::vector<std::vector<SmallVector<Fraction>>> sumAff;
+    sumAff.insert(sumAff.end(), affine.begin(), affine.end());
+    sumAff.insert(sumAff.end(), x.affine.begin(), x.affine.end());
+    return QuasiPolynomial(numParam, sumCoeffs, sumAff);
+  }
+
+  QuasiPolynomial operator-(QuasiPolynomial &x) {
+    assert(numParam == x.getNumParams() &&
+           "two quasi-polynomials with different numbers of parameters cannot "
+           "be subtracted!");
+    QuasiPolynomial qp(numParam, x.coefficients, x.affine);
+    for (Fraction &coeff : qp.coefficients)
+      coeff = -coeff;
+    return *this + qp;
+  }
+
+  QuasiPolynomial operator*(QuasiPolynomial &x) {
+    assert(numParam == x.getNumParams() &&
+           "two quasi-polynomials with different numbers of "
+           "parameters cannot be multiplied!");
+
+    SmallVector<Fraction> coeffs;
+    for (const Fraction &coeff : coefficients) {
+      for (const Fraction &xcoeff : x.coefficients) {
+        coeffs.append({coeff * xcoeff});
+      }
+    }
+
+    std::vector<SmallVector<Fraction>> product;
+    std::vector<std::vector<SmallVector<Fraction>>> aff;
+    for (const std::vector<SmallVector<Fraction>> &term : affine) {
+      for (const std::vector<SmallVector<Fraction>> &xterm : x.affine) {
+        product.clear();
+        product.insert(product.end(), term.begin(), term.end());
+        product.insert(product.end(), xterm.begin(), xterm.end());
+        aff.push_back(product);
+      }
+    }
+
+    return QuasiPolynomial(numParam, coeffs, aff);
+  }
+
+  QuasiPolynomial operator/(Fraction x) {
----------------
Superty wrote:

const please

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


More information about the Mlir-commits mailing list