[Mlir-commits] [mlir] [MLIR][Presburger] Generating functions and quasi-polynomials for Barvinok's algorithm (PR #75702)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Sat Dec 16 23:22:12 PST 2023
https://github.com/Abhinav271828 updated https://github.com/llvm/llvm-project/pull/75702
>From b65a078edbbd8d711b1bb9ec12b938f47c550e9a Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sat, 16 Dec 2023 19:37:00 +0530
Subject: [PATCH 1/8] Definitions for gf and qp classes
---
.../mlir/Analysis/Presburger/Barvinok.h | 229 ++++++++++++++++++
1 file changed, 229 insertions(+)
create mode 100644 mlir/include/mlir/Analysis/Presburger/Barvinok.h
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
new file mode 100644
index 00000000000000..3ee9d5dc452d0e
--- /dev/null
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -0,0 +1,229 @@
+//===- 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){};
+
+ unsigned getNumParams() {
+ for (auto term : numerators)
+ return (term.getNumColumns() - 1);
+ 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^[";
+ for (unsigned j = 0; j < numerators[i].size() - 1; j++)
+ os << numerators[i][j] << ",";
+ os << numerators[i][numerators[i].size() - 1] << "])/";
+
+ for (Point den : denominators[i]) {
+ os << "(x^[";
+ for (unsigned j = 0; j < den.size(); j++)
+ os << den[j] << ",";
+ os << den[den.size() - 1] << "])";
+ }
+ }
+ return os;
+ }
+
+ SmallVector<int, 16> signs;
+ std::vector<ParamPoint> numerators;
+ std::vector<std::vector<Point>> denominators;
+};
+
+// 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.
+class QuasiPolynomial {
+public:
+ QuasiPolynomial(SmallVector<Fraction> coeffs = {},
+ std::vector<std::vector<SmallVector<Fraction>>> aff = {})
+ : coefficients(coeffs), affine(aff){};
+
+ QuasiPolynomial(Fraction cons) : coefficients({cons}), affine({{}}){};
+
+ QuasiPolynomial(QuasiPolynomial const &) = default;
+
+ SmallVector<Fraction> coefficients;
+ std::vector<std::vector<SmallVector<Fraction>>> affine;
+
+ // Find the number of parameters involved in the polynomial
+ // from the dimensionality of the affine functions.
+ unsigned getNumParams() {
+ // Find the first term which involves some affine function.
+ for (auto term : affine) {
+ if (term.size() == 0)
+ continue;
+ // The number of elements in the affine function is
+ // one more than the number of parameters.
+ return (term[0].size() - 1);
+ }
+ // The polynomial can be treated as having any number
+ // of parameters.
+ return -1;
+ }
+
+ QuasiPolynomial operator+(const QuasiPolynomial &x) {
+ bool sameNumParams = (getNumParams() == -1) || (x.getNumParams() == -1) ||
+ (getNumParams() == x.getNumParams());
+ assert(sameNumParams && "two quasi-polynomials with different numbers of "
+ "parameters cannot be added!");
+ coefficients.append(x.coefficients);
+ affine.insert(affine.end(), x.affine.begin(), x.affine.end());
+ return *this;
+ }
+
+ QuasiPolynomial operator-(const QuasiPolynomial &x) {
+ bool sameNumParams = (getNumParams() == -1) || (x.getNumParams() == -1) ||
+ (getNumParams() == x.getNumParams());
+ assert(sameNumParams && "two quasi-polynomials with different numbers of "
+ "parameters cannot be subtracted!");
+ QuasiPolynomial qp(x.coefficients, x.affine);
+ for (unsigned i = 0; i < x.coefficients.size(); i++)
+ qp.coefficients[i] = -qp.coefficients[i];
+ return (*this + qp);
+ }
+
+ QuasiPolynomial operator*(const QuasiPolynomial &x) {
+ bool sameNumParams = (getNumParams() == -1) || (x.getNumParams() == -1) ||
+ (getNumParams() == x.getNumParams());
+ assert(sameNumParams && "two quasi-polynomials with different numbers of "
+ "parameters cannot be multiplied!");
+ QuasiPolynomial qp();
+ std::vector<SmallVector<Fraction>> product;
+ for (unsigned i = 0; i < coefficients.size(); i++) {
+ for (unsigned j = 0; j < x.coefficients.size(); j++) {
+ qp.coefficients.append({coefficients[i] * x.coefficients[j]});
+
+ product.clear();
+ product.insert(product.end(), affine[i].begin(), affine[i].end());
+ product.insert(product.end(), x.affine[j].begin(), x.affine[j].end());
+
+ qp.affine.push_back(product);
+ }
+ }
+
+ return qp;
+ }
+
+ QuasiPolynomial operator/(Fraction x) {
+ assert(x != 0 && "division by zero!");
+ for (unsigned i = 0; i < coefficients.size(); i++)
+ coefficients[i] = coefficients[i] / x;
+ return *this;
+ };
+
+ // Removes terms which evaluate to zero from the expression.
+ QuasiPolynomial reduce() {
+ SmallVector<Fraction> newCoeffs({});
+ std::vector<std::vector<SmallVector<Fraction>>> newAffine({});
+ bool prodIsNonz, sumIsNonz;
+ for (unsigned i = 0; i < coefficients.size(); i++) {
+ prodIsNonz = true;
+ for (unsigned j = 0; j < affine[i].size(); j++) {
+ sumIsNonz = false;
+ for (unsigned k = 0; k < affine[i][j].size(); k++)
+ if (affine[i][j][k] != Fraction(0, 1))
+ sumIsNonz = true;
+ if (sumIsNonz == false)
+ prodIsNonz = false;
+ }
+ if (prodIsNonz == true && coefficients[i] != Fraction(0, 1)) {
+ newCoeffs.append({coefficients[i]});
+ newAffine.push_back({affine[i]});
+ }
+ }
+ return QuasiPolynomial(newCoeffs, newAffine);
+ }
+};
+
+} // namespace presburger
+} // namespace mlir
+
+#endif // MLIR_ANALYSIS_PRESBURGER_BARVINOK_H
\ No newline at end of file
>From 6101acb97250f3455bf3aaf4cf3b88165b2c740b Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sat, 16 Dec 2023 21:02:51 +0530
Subject: [PATCH 2/8] Comments
---
mlir/include/mlir/Analysis/Presburger/Barvinok.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
index 3ee9d5dc452d0e..d753f97d3bcf74 100644
--- a/mlir/include/mlir/Analysis/Presburger/Barvinok.h
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -60,9 +60,15 @@ class GeneratingFunction {
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;
}
>From 5d425bd2c83576f3ba389aed3aa3291375dab185 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sun, 17 Dec 2023 01:27:14 +0530
Subject: [PATCH 3/8] Miscellaneous reformatting
---
.../mlir/Analysis/Presburger/Barvinok.h | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
index d753f97d3bcf74..bbd4baf3dd8cd8 100644
--- a/mlir/include/mlir/Analysis/Presburger/Barvinok.h
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -56,9 +56,9 @@ using Point = SmallVector<Fraction>;
// is a vector (a generator).
class GeneratingFunction {
public:
- GeneratingFunction(SmallVector<int, 16> s, std::vector<ParamPoint> nums,
+ GeneratingFunction(SmallVector<int, 16> signs, std::vector<ParamPoint> nums,
std::vector<std::vector<Point>> dens)
- : signs(s), numerators(nums), denominators(dens){};
+ : signs(signs), numerators(nums), denominators(dens) {}
// Find the number of parameters involved in the function
// from the dimensionality of the affine functions.
@@ -96,18 +96,18 @@ class GeneratingFunction {
llvm::raw_ostream &print(llvm::raw_ostream &os) const {
for (unsigned i = 0; i < signs.size(); i++) {
if (signs[i] == 1)
- os << "+";
+ os << " + ";
else
- os << "-";
+ os << " - ";
- os << "*(x^[";
+ os << "(x^[";
for (unsigned j = 0; j < numerators[i].size() - 1; j++)
os << numerators[i][j] << ",";
- os << numerators[i][numerators[i].size() - 1] << "])/";
+ os << numerators[i].back() << "])/";
for (Point den : denominators[i]) {
os << "(x^[";
- for (unsigned j = 0; j < den.size(); j++)
+ for (unsigned j = 0; j < den.size() - 1; j++)
os << den[j] << ",";
os << den[den.size() - 1] << "])";
}
@@ -115,7 +115,7 @@ class GeneratingFunction {
return os;
}
- SmallVector<int, 16> signs;
+ SmallVector<int, 8> signs;
std::vector<ParamPoint> numerators;
std::vector<std::vector<Point>> denominators;
};
@@ -130,9 +130,9 @@ class QuasiPolynomial {
public:
QuasiPolynomial(SmallVector<Fraction> coeffs = {},
std::vector<std::vector<SmallVector<Fraction>>> aff = {})
- : coefficients(coeffs), affine(aff){};
+ : coefficients(coeffs), affine(aff) {}
- QuasiPolynomial(Fraction cons) : coefficients({cons}), affine({{}}){};
+ QuasiPolynomial(Fraction cons) : coefficients({cons}), affine({{}}) {}
QuasiPolynomial(QuasiPolynomial const &) = default;
>From 883e99356b4875c83eb79bba4bf591d5f5a95444 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sun, 17 Dec 2023 01:31:44 +0530
Subject: [PATCH 4/8] Remove superfluous == operator
---
mlir/include/mlir/Analysis/Presburger/Barvinok.h | 7 -------
1 file changed, 7 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
index bbd4baf3dd8cd8..d99ec62bd93a41 100644
--- a/mlir/include/mlir/Analysis/Presburger/Barvinok.h
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -72,13 +72,6 @@ class GeneratingFunction {
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());
>From 2812e75ff47666d56053c1396b9157d52031ed88 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sun, 17 Dec 2023 01:40:04 +0530
Subject: [PATCH 5/8] Use SmallVector::append() instead of insert()
---
mlir/include/mlir/Analysis/Presburger/Barvinok.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
index d99ec62bd93a41..b7dd528f92ffd3 100644
--- a/mlir/include/mlir/Analysis/Presburger/Barvinok.h
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -78,7 +78,7 @@ class GeneratingFunction {
assert(
sameNumParams &&
"two generators with different numbers of parameters cannot be added!");
- signs.insert(signs.end(), gf.signs.begin(), gf.signs.end());
+ signs.append(gf.signs);
numerators.insert(numerators.end(), gf.numerators.begin(),
gf.numerators.end());
denominators.insert(denominators.end(), gf.denominators.begin(),
>From 625b1b1bbe0c95addf9af0a00d2bbb7aa470d8a7 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sun, 17 Dec 2023 01:51:01 +0530
Subject: [PATCH 6/8] Refactor numParam as private attribute
---
.../mlir/Analysis/Presburger/Barvinok.h | 87 +++++++++----------
1 file changed, 43 insertions(+), 44 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
index b7dd528f92ffd3..64e5d98b20adbc 100644
--- a/mlir/include/mlir/Analysis/Presburger/Barvinok.h
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -56,28 +56,24 @@ using Point = SmallVector<Fraction>;
// is a vector (a generator).
class GeneratingFunction {
public:
- GeneratingFunction(SmallVector<int, 16> signs, std::vector<ParamPoint> nums,
+ GeneratingFunction(unsigned numParam, SmallVector<int, 8> signs,
+ std::vector<ParamPoint> nums,
std::vector<std::vector<Point>> dens)
- : signs(signs), numerators(nums), denominators(dens) {}
+ : numParam(numParam), signs(signs), numerators(nums), denominators(dens) {
+ for (auto term : numerators)
+ assert(term.getNumColumns() - 1 == numParam &&
+ "dimensionality of numerator exponents does not match number of "
+ "parameters!");
+ }
// 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;
- }
+ unsigned getNumParams() { return numParam; }
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!");
+ assert(numParam == gf.getNumParams() &&
+ "two generating functions with different numbers of parameters "
+ "cannot be added!");
signs.append(gf.signs);
numerators.insert(numerators.end(), gf.numerators.begin(),
gf.numerators.end());
@@ -111,6 +107,9 @@ class GeneratingFunction {
SmallVector<int, 8> signs;
std::vector<ParamPoint> numerators;
std::vector<std::vector<Point>> denominators;
+
+private:
+ unsigned numParam;
};
// A class to describe the quasi-polynomials obtained by
@@ -121,38 +120,32 @@ class GeneratingFunction {
// by the product of a set of affine functions on n parameters.
class QuasiPolynomial {
public:
- QuasiPolynomial(SmallVector<Fraction> coeffs = {},
+ QuasiPolynomial(unsigned numParam, SmallVector<Fraction> coeffs = {},
std::vector<std::vector<SmallVector<Fraction>>> aff = {})
- : coefficients(coeffs), affine(aff) {}
+ : numParam(numParam), coefficients(coeffs), affine(aff) {
+ // Find the first term which involves some affine function.
+ for (auto term : affine)
+ if (term.size() == 0)
+ continue;
+ // The number of elements in the affine function is
+ // one more than the number of parameters.
+ assert(term[0].size() - 1 == numParam &&
+ "dimensionality of affine functions does not match number of "
+ "parameters!")
+ }
QuasiPolynomial(Fraction cons) : coefficients({cons}), affine({{}}) {}
QuasiPolynomial(QuasiPolynomial const &) = default;
- SmallVector<Fraction> coefficients;
- std::vector<std::vector<SmallVector<Fraction>>> affine;
-
// Find the number of parameters involved in the polynomial
// from the dimensionality of the affine functions.
- unsigned getNumParams() {
- // Find the first term which involves some affine function.
- for (auto term : affine) {
- if (term.size() == 0)
- continue;
- // The number of elements in the affine function is
- // one more than the number of parameters.
- return (term[0].size() - 1);
- }
- // The polynomial can be treated as having any number
- // of parameters.
- return -1;
- }
+ unsigned getNumParams() { return numParam; }
QuasiPolynomial operator+(const QuasiPolynomial &x) {
- bool sameNumParams = (getNumParams() == -1) || (x.getNumParams() == -1) ||
- (getNumParams() == x.getNumParams());
- assert(sameNumParams && "two quasi-polynomials with different numbers of "
- "parameters cannot be added!");
+ assert(numParam == x.getNumParams() &&
+ "two quasi-polynomials with different numbers of parameters cannot "
+ "be added!");
coefficients.append(x.coefficients);
affine.insert(affine.end(), x.affine.begin(), x.affine.end());
return *this;
@@ -161,8 +154,9 @@ class QuasiPolynomial {
QuasiPolynomial operator-(const QuasiPolynomial &x) {
bool sameNumParams = (getNumParams() == -1) || (x.getNumParams() == -1) ||
(getNumParams() == x.getNumParams());
- assert(sameNumParams && "two quasi-polynomials with different numbers of "
- "parameters cannot be subtracted!");
+ assert(numParam == x.getNumParams() &&
+ "two quasi-polynomials with different numbers of parameters cannot "
+ "be subtracted!");
QuasiPolynomial qp(x.coefficients, x.affine);
for (unsigned i = 0; i < x.coefficients.size(); i++)
qp.coefficients[i] = -qp.coefficients[i];
@@ -170,10 +164,9 @@ class QuasiPolynomial {
}
QuasiPolynomial operator*(const QuasiPolynomial &x) {
- bool sameNumParams = (getNumParams() == -1) || (x.getNumParams() == -1) ||
- (getNumParams() == x.getNumParams());
- assert(sameNumParams && "two quasi-polynomials with different numbers of "
- "parameters cannot be multiplied!");
+ assert(numParam = x.getNumParams() &&
+ "two quasi-polynomials with different numbers of "
+ "parameters cannot be multiplied!");
QuasiPolynomial qp();
std::vector<SmallVector<Fraction>> product;
for (unsigned i = 0; i < coefficients.size(); i++) {
@@ -220,6 +213,12 @@ class QuasiPolynomial {
}
return QuasiPolynomial(newCoeffs, newAffine);
}
+
+ SmallVector<Fraction> coefficients;
+ std::vector<std::vector<SmallVector<Fraction>>> affine;
+
+private:
+ unsigned numParam;
};
} // namespace presburger
>From 94b5996de245280e1e9cd60673d46f793b995416 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sun, 17 Dec 2023 12:49:32 +0530
Subject: [PATCH 7/8] Formatting fixes
---
.../mlir/Analysis/Presburger/Barvinok.h | 68 +++++++++++--------
1 file changed, 39 insertions(+), 29 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
index 64e5d98b20adbc..80ab8fb4df1ef7 100644
--- a/mlir/include/mlir/Analysis/Presburger/Barvinok.h
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -1,4 +1,4 @@
-//===- Barvinok.h - Barvinok's Algorithm -----------*- C++ -*-===//
+//===- 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.
@@ -54,13 +54,21 @@ using Point = SmallVector<Fraction>;
// * a denominator, of the form (1 - x^{d1})...(1 - x^{dn}),
// where each dj, stored in `denominators[i][j]`,
// is a vector (a generator).
+//
+// Represents functions f : Q^n -> Q of the form
+//
+// f(x) = \sum_i s_i * (x^n_i(p)) / (\prod_j (1 - x^d_{ij})
+//
+// where s_i is ±1,
+// n_i \in (Q^d -> Q)^n is an n-vector of affine functions on d parameters, and
+// g_{ij} \in Q^n are vectors.
class GeneratingFunction {
public:
GeneratingFunction(unsigned numParam, SmallVector<int, 8> signs,
std::vector<ParamPoint> nums,
std::vector<std::vector<Point>> dens)
: numParam(numParam), signs(signs), numerators(nums), denominators(dens) {
- for (auto term : numerators)
+ for (const auto &term : numerators)
assert(term.getNumColumns() - 1 == numParam &&
"dimensionality of numerator exponents does not match number of "
"parameters!");
@@ -83,20 +91,20 @@ class GeneratingFunction {
}
llvm::raw_ostream &print(llvm::raw_ostream &os) const {
- for (unsigned i = 0; i < signs.size(); i++) {
+ for (unsigned i = 0, e = signs.size(); i < e; i++) {
if (signs[i] == 1)
os << " + ";
else
os << " - ";
- os << "(x^[";
- for (unsigned j = 0; j < numerators[i].size() - 1; j++)
+ os << "x^[";
+ for (unsigned j = 0, e = numerators[i].size(); j < e - 1; j++)
os << numerators[i][j] << ",";
- os << numerators[i].back() << "])/";
+ os << numerators[i].back() << "]/";
for (Point den : denominators[i]) {
os << "(x^[";
- for (unsigned j = 0; j < den.size() - 1; j++)
+ for (unsigned j = 0, e = den.size(); j < e - 1; j++)
os << den[j] << ",";
os << den[den.size() - 1] << "])";
}
@@ -118,28 +126,30 @@ class GeneratingFunction {
// 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 = {})
: numParam(numParam), coefficients(coeffs), affine(aff) {
// Find the first term which involves some affine function.
- for (auto term : affine)
+ for (auto term : affine) {
if (term.size() == 0)
continue;
- // The number of elements in the affine function is
- // one more than the number of parameters.
- assert(term[0].size() - 1 == numParam &&
- "dimensionality of affine functions does not match number of "
- "parameters!")
+ // The number of elements in the affine function is
+ // one more than the number of parameters.
+ assert(term[0].size() - 1 == numParam &&
+ "dimensionality of affine functions does not match number of "
+ "parameters!")
+ }
}
- QuasiPolynomial(Fraction cons) : coefficients({cons}), affine({{}}) {}
-
- QuasiPolynomial(QuasiPolynomial const &) = default;
-
- // Find the number of parameters involved in the polynomial
- // from the dimensionality of the affine functions.
+ // Find the number of parameters involved in the polynomial.
unsigned getNumParams() { return numParam; }
QuasiPolynomial operator+(const QuasiPolynomial &x) {
@@ -158,7 +168,7 @@ class QuasiPolynomial {
"two quasi-polynomials with different numbers of parameters cannot "
"be subtracted!");
QuasiPolynomial qp(x.coefficients, x.affine);
- for (unsigned i = 0; i < x.coefficients.size(); i++)
+ for (unsigned i = 0, e = x.coefficients.size(); i < e; i++)
qp.coefficients[i] = -qp.coefficients[i];
return (*this + qp);
}
@@ -169,8 +179,8 @@ class QuasiPolynomial {
"parameters cannot be multiplied!");
QuasiPolynomial qp();
std::vector<SmallVector<Fraction>> product;
- for (unsigned i = 0; i < coefficients.size(); i++) {
- for (unsigned j = 0; j < x.coefficients.size(); j++) {
+ for (unsigned i = 0, e = coefficients.size(); i < e; i++) {
+ for (unsigned j = 0, e = x.coefficients.size(); j < e; j++) {
qp.coefficients.append({coefficients[i] * x.coefficients[j]});
product.clear();
@@ -186,27 +196,27 @@ class QuasiPolynomial {
QuasiPolynomial operator/(Fraction x) {
assert(x != 0 && "division by zero!");
- for (unsigned i = 0; i < coefficients.size(); i++)
- coefficients[i] = coefficients[i] / x;
+ for (Fraction &coeff : coefficients)
+ coeff /= x;
return *this;
};
// Removes terms which evaluate to zero from the expression.
- QuasiPolynomial reduce() {
+ QuasiPolynomial simplify() {
SmallVector<Fraction> newCoeffs({});
std::vector<std::vector<SmallVector<Fraction>>> newAffine({});
bool prodIsNonz, sumIsNonz;
- for (unsigned i = 0; i < coefficients.size(); i++) {
+ for (unsigned i = 0, e = coefficients.size(); i < e; i++) {
prodIsNonz = true;
- for (unsigned j = 0; j < affine[i].size(); j++) {
+ for (unsigned j = 0, e = affine[i].size(); j < e; j++) {
sumIsNonz = false;
- for (unsigned k = 0; k < affine[i][j].size(); k++)
+ for (unsigned k = 0, e = affine[i][j].size(); k < e; k++)
if (affine[i][j][k] != Fraction(0, 1))
sumIsNonz = true;
if (sumIsNonz == false)
prodIsNonz = false;
}
- if (prodIsNonz == true && coefficients[i] != Fraction(0, 1)) {
+ if (prodIsNonz && coefficients[i] != Fraction(0, 1)) {
newCoeffs.append({coefficients[i]});
newAffine.push_back({affine[i]});
}
>From f005fdc6cdac0b7b859066e5d8d3cd6c47b9a312 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Sun, 17 Dec 2023 12:51:58 +0530
Subject: [PATCH 8/8] Add type instead of auto
---
mlir/include/mlir/Analysis/Presburger/Barvinok.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/Barvinok.h b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
index 80ab8fb4df1ef7..682099ed84b029 100644
--- a/mlir/include/mlir/Analysis/Presburger/Barvinok.h
+++ b/mlir/include/mlir/Analysis/Presburger/Barvinok.h
@@ -68,7 +68,7 @@ class GeneratingFunction {
std::vector<ParamPoint> nums,
std::vector<std::vector<Point>> dens)
: numParam(numParam), signs(signs), numerators(nums), denominators(dens) {
- for (const auto &term : numerators)
+ for (const ParamPoint &term : numerators)
assert(term.getNumColumns() - 1 == numParam &&
"dimensionality of numerator exponents does not match number of "
"parameters!");
@@ -138,7 +138,7 @@ class QuasiPolynomial {
std::vector<std::vector<SmallVector<Fraction>>> aff = {})
: numParam(numParam), coefficients(coeffs), affine(aff) {
// Find the first term which involves some affine function.
- for (auto term : affine) {
+ for (const std::vector<SmallVector<Fraction>> &term : affine) {
if (term.size() == 0)
continue;
// The number of elements in the affine function is
More information about the Mlir-commits
mailing list