[Mlir-commits] [mlir] [WIP][MLIR][Presburger] Fix a bunch of minor style choices etc. (PR #82782)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Feb 23 08:12:20 PST 2024
https://github.com/Abhinav271828 created https://github.com/llvm/llvm-project/pull/82782
* Use range-style for-loops
* Use `int` instead of `unsigned`
* Define and use `+=` for QuasiPolynomials
* Use "numSymbols" instead of "numParams"
>From 2036fca61ef57c39db2e2aebe1d0c3d2d86bfb8d Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Fri, 16 Feb 2024 22:54:44 +0530
Subject: [PATCH 1/6] Change loop format
---
.../Analysis/Presburger/GeneratingFunction.h | 11 ++--
mlir/lib/Analysis/Presburger/Barvinok.cpp | 53 +++++++++----------
mlir/lib/Analysis/Presburger/Matrix.cpp | 43 +++++++--------
.../Analysis/Presburger/QuasiPolynomial.cpp | 9 ++--
mlir/lib/Analysis/Presburger/Utils.cpp | 7 +--
.../Analysis/Presburger/BarvinokTest.cpp | 12 ++---
.../Analysis/Presburger/MatrixTest.cpp | 18 +++----
mlir/unittests/Analysis/Presburger/Utils.h | 36 ++++++-------
8 files changed, 96 insertions(+), 93 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
index db5b6b6a959186..e90a991d5c4809 100644
--- a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
+++ b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
@@ -16,6 +16,7 @@
#include "mlir/Analysis/Presburger/Fraction.h"
#include "mlir/Analysis/Presburger/Matrix.h"
+#include "llvm/ADT/Sequence.h"
namespace mlir {
namespace presburger {
@@ -91,7 +92,7 @@ class GeneratingFunction {
}
llvm::raw_ostream &print(llvm::raw_ostream &os) const {
- for (unsigned i = 0, e = signs.size(); i < e; i++) {
+ for (int i : llvm::seq<int>(0, signs.size())) {
if (i == 0) {
if (signs[i] == -1)
os << "- ";
@@ -104,20 +105,20 @@ class GeneratingFunction {
os << "x^[";
unsigned r = numerators[i].getNumRows();
- for (unsigned j = 0; j < r - 1; j++) {
+ for (unsigned j = 0; j < r - 1; ++j) {
os << "[";
- for (unsigned k = 0, c = numerators[i].getNumColumns(); k < c - 1; k++)
+ for (int k : llvm::seq<int>(0, numerators[i].getNumColumns() - 1))
os << numerators[i].at(j, k) << ",";
os << numerators[i].getRow(j).back() << "],";
}
os << "[";
- for (unsigned k = 0, c = numerators[i].getNumColumns(); k < c - 1; k++)
+ for (int k : llvm::seq<int>(0, numerators[i].getNumColumns() - 1))
os << numerators[i].at(r - 1, k) << ",";
os << numerators[i].getRow(r - 1).back() << "]]/";
for (const Point &den : denominators[i]) {
os << "(x^[";
- for (unsigned j = 0, e = den.size(); j < e - 1; j++)
+ for (int j : llvm::seq<int>(0, den.size() - 1))
os << den[j] << ",";
os << den.back() << "])";
}
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index b6d1f99df8ba55..c483b9a4b81f37 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -28,12 +28,10 @@ ConeV mlir::presburger::detail::getDual(ConeH cone) {
// is represented as a row [a1, ..., an, b]
// and that b = 0.
- for (auto i : llvm::seq<int>(0, numIneq)) {
+ for (int i : llvm::seq<int>(0, numIneq)) {
assert(cone.atIneq(i, numVar) == 0 &&
"H-representation of cone is not centred at the origin!");
- for (unsigned j = 0; j < numVar; ++j) {
- dual.at(i, j) = cone.atIneq(i, j);
- }
+ dual.setRow(i, cone.getInequality(i).take_front(numVar));
}
// Now dual is of the form [ [a1, ..., an] , ... ]
@@ -130,8 +128,8 @@ mlir::presburger::detail::computeUnimodularConeGeneratingFunction(
unsigned numRows = vertex.getNumRows();
ParamPoint numerator(numColumns, numRows);
SmallVector<Fraction> ithCol(numRows);
- for (auto i : llvm::seq<int>(0, numColumns)) {
- for (auto j : llvm::seq<int>(0, numRows))
+ for (int i : llvm::seq<int>(0, numColumns)) {
+ for (int j : llvm::seq<int>(0, numRows))
ithCol[j] = vertex(j, i);
numerator.setRow(i, transp.preMultiplyWithRow(ithCol));
numerator.negateRow(i);
@@ -176,12 +174,12 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
// Perform row operations to make each column all zeros except for the
// diagonal element, which is made to be one.
- for (unsigned i = 0; i < d; ++i) {
+ for (int i : llvm::seq<int>(0, d)) {
// First ensure that the diagonal element is nonzero, by swapping
// it with a row that is non-zero at column i.
if (equations(i, i) != 0)
continue;
- for (unsigned j = i + 1; j < d; ++j) {
+ for (int j : llvm::seq<int>(i + 1, d)) {
if (equations(j, i) == 0)
continue;
equations.swapRows(j, i);
@@ -191,7 +189,7 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
Fraction diagElement = equations(i, i);
// Apply row operations to make all elements except the diagonal to zero.
- for (unsigned j = 0; j < d; ++j) {
+ for (int j : llvm::seq<int>(0, d)) {
if (i == j)
continue;
if (equations(j, i) == 0)
@@ -205,7 +203,7 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
}
// Rescale diagonal elements to 1.
- for (unsigned i = 0; i < d; ++i)
+ for (int i : llvm::seq<int>(0, d))
equations.scaleRow(i, 1 / equations(i, i));
// Now we have reduced the equations to the form
@@ -332,7 +330,7 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
//
// We start with the permutation that takes the last numVars inequalities.
SmallVector<int> indicator(numIneqs);
- for (unsigned i = numIneqs - numVars; i < numIneqs; ++i)
+ for (int i : llvm::seq<int>(numIneqs - numVars, numIneqs))
indicator[i] = 1;
do {
@@ -393,7 +391,7 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
// Thus we premultiply [X | y] with each row of A2
// and add each row of [B2 | c2].
FracMatrix activeRegion(numIneqs - numVars, numSymbols + 1);
- for (unsigned i = 0; i < numIneqs - numVars; i++) {
+ for (int i : llvm::seq<int>(0, numIneqs - numVars)) {
activeRegion.setRow(i, vertex->preMultiplyWithRow(a2.getRow(i)));
activeRegion.addToRow(i, b2c2.getRow(i), 1);
}
@@ -412,9 +410,9 @@ mlir::presburger::detail::computePolytopeGeneratingFunction(
// We translate the cones to be pointed at the origin by making the
// constant terms zero.
ConeH tangentCone = defineHRep(numVars);
- for (unsigned j = 0, e = subset.getNumRows(); j < e; ++j) {
+ for (int j : llvm::seq<int>(0, subset.getNumRows())) {
SmallVector<MPInt> ineq(numVars + 1);
- for (unsigned k = 0; k < numVars; ++k)
+ for (int k : llvm::seq<int>(0, numVars))
ineq[k] = subset(j, k);
tangentCone.addInequality(ineq);
}
@@ -482,7 +480,7 @@ Point mlir::presburger::detail::getNonOrthogonalVector(
Fraction maxDisallowedValue = -Fraction(1, 0),
disallowedValue = Fraction(0, 1);
- for (unsigned d = 1; d < dim; ++d) {
+ for (int d : llvm::seq<int>(1, dim)) {
// Compute the disallowed values - <x_i[:d-1], vs> / x_i[d] for each i.
maxDisallowedValue = -Fraction(1, 0);
for (const Point &vector : vectors) {
@@ -530,7 +528,7 @@ QuasiPolynomial mlir::presburger::detail::getCoefficientInRationalFunction(
coefficients.reserve(power + 1);
coefficients.push_back(num[0] / den[0]);
- for (unsigned i = 1; i <= power; ++i) {
+ for (unsigned i : llvm::seq<int>(1, power + 1)) {
// If the power is not there in the numerator, the coefficient is zero.
coefficients.push_back(i < num.size() ? num[i]
: QuasiPolynomial(numParam, 0));
@@ -538,7 +536,7 @@ QuasiPolynomial mlir::presburger::detail::getCoefficientInRationalFunction(
// After den.size(), the coefficients are zero, so we stop
// subtracting at that point (if it is less than i).
unsigned limit = std::min<unsigned long>(i, den.size() - 1);
- for (unsigned j = 1; j <= limit; ++j)
+ for (int j : llvm::seq<int>(1, limit + 1))
coefficients[i] = coefficients[i] -
coefficients[i - j] * QuasiPolynomial(numParam, den[j]);
@@ -582,7 +580,7 @@ substituteMuInTerm(unsigned numParams, ParamPoint v, std::vector<Point> ds,
ParamPoint vTranspose = v.transpose();
std::vector<std::vector<SmallVector<Fraction>>> affine;
affine.reserve(numDims);
- for (unsigned j = 0; j < numDims; ++j)
+ for (int j : llvm::seq<int>(0, numDims))
affine.push_back({SmallVector<Fraction>(vTranspose.getRow(j))});
QuasiPolynomial num(numParams, coefficients, affine);
@@ -613,10 +611,10 @@ void normalizeDenominatorExponents(int &sign, QuasiPolynomial &num,
// denominator, and convert them to their absolute values.
unsigned numNegExps = 0;
Fraction sumNegExps(0, 1);
- for (unsigned j = 0, e = dens.size(); j < e; ++j) {
- if (dens[j] < 0) {
+ for (const Fraction &den : dens) {
+ if (den < 0) {
numNegExps += 1;
- sumNegExps += dens[j];
+ sumNegExps += den;
}
}
@@ -641,7 +639,7 @@ std::vector<QuasiPolynomial> getBinomialCoefficients(QuasiPolynomial n,
std::vector<QuasiPolynomial> coefficients;
coefficients.reserve(r + 1);
coefficients.push_back(QuasiPolynomial(numParams, 1));
- for (unsigned j = 1; j <= r; ++j)
+ for (int j : llvm::seq<int>(1, r + 1))
// We use the recursive formula for binomial coefficients here and below.
coefficients.push_back(
(coefficients[j - 1] * (n - QuasiPolynomial(numParams, j - 1)) /
@@ -701,7 +699,7 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
unsigned numParams = gf.getNumParams();
const std::vector<std::vector<Point>> &ds = gf.getDenominators();
QuasiPolynomial totalTerm(numParams, 0);
- for (unsigned i = 0, e = ds.size(); i < e; ++i) {
+ for (int i : llvm::seq<int>(0, ds.size())) {
int sign = gf.getSigns()[i];
// Compute the new exponents of (s+1) for the numerator and the
@@ -722,7 +720,7 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
// Then, using the formula for geometric series, we replace each (1 -
// (s+1)^(dens[j])) with
// (-s)(\sum_{0 ≤ k < dens[j]} (s+1)^k).
- for (unsigned j = 0, e = dens.size(); j < e; ++j)
+ for (int j : llvm::seq<int>(0, dens.size()))
dens[j] = abs(dens[j]) - 1;
// Note that at this point, the semantics of `dens[j]` changes to mean
// a term (\sum_{0 ≤ k ≤ dens[j]} (s+1)^k). The denominator is, as before,
@@ -774,9 +772,10 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
// of all the terms.
std::vector<Fraction> denominatorCoefficients;
denominatorCoefficients = eachTermDenCoefficients[0];
- for (unsigned j = 1, e = eachTermDenCoefficients.size(); j < e; ++j)
- denominatorCoefficients = multiplyPolynomials(denominatorCoefficients,
- eachTermDenCoefficients[j]);
+ for (const std::vector<Fraction> &eachTermDenCoefficient :
+ eachTermDenCoefficients)
+ denominatorCoefficients =
+ multiplyPolynomials(denominatorCoefficients, eachTermDenCoefficient);
totalTerm =
totalTerm + getCoefficientInRationalFunction(r, numeratorCoefficients,
diff --git a/mlir/lib/Analysis/Presburger/Matrix.cpp b/mlir/lib/Analysis/Presburger/Matrix.cpp
index 4cb6e6b16bc878..76d4f61d1c0c2a 100644
--- a/mlir/lib/Analysis/Presburger/Matrix.cpp
+++ b/mlir/lib/Analysis/Presburger/Matrix.cpp
@@ -11,6 +11,7 @@
#include "mlir/Analysis/Presburger/MPInt.h"
#include "mlir/Analysis/Presburger/Utils.h"
#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/Sequence.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -38,7 +39,7 @@ bool Matrix<T>::operator==(const Matrix<T> &m) const {
if (nColumns != m.getNumColumns())
return false;
- for (unsigned i = 0; i < nRows; i++)
+ for (int i : llvm::seq<int>(0, nRows))
if (getRow(i) != m.getRow(i))
return false;
@@ -392,8 +393,8 @@ Matrix<T> Matrix<T>::getSubMatrix(unsigned fromRow, unsigned toRow,
"end of column range must be after beginning!");
assert(toColumn < nColumns && "end of column range out of bounds!");
Matrix<T> subMatrix(toRow - fromRow + 1, toColumn - fromColumn + 1);
- for (unsigned i = fromRow; i <= toRow; ++i)
- for (unsigned j = fromColumn; j <= toColumn; ++j)
+ for (int i : llvm::seq<int>(fromRow, toRow + 1))
+ for (int j : llvm::seq<int>(fromColumn, toColumn + 1))
subMatrix(i - fromRow, j - fromColumn) = at(i, j);
return subMatrix;
}
@@ -413,7 +414,7 @@ template <typename T>
std::pair<Matrix<T>, Matrix<T>>
Matrix<T>::splitByBitset(ArrayRef<int> indicator) {
Matrix<T> rowsForOne(0, nColumns), rowsForZero(0, nColumns);
- for (unsigned i = 0; i < nRows; i++) {
+ for (int i : llvm::seq<int>(0, nRows)) {
if (indicator[i] == 1)
rowsForOne.appendExtraRow(getRow(i));
else
@@ -566,8 +567,8 @@ MPInt IntMatrix::determinant(IntMatrix *inverse) const {
return detM;
*inverse = IntMatrix(nRows, nColumns);
- for (unsigned i = 0; i < nRows; i++)
- for (unsigned j = 0; j < nColumns; j++)
+ for (int i : llvm::seq<int>(0, nRows))
+ for (int j : llvm::seq<int>(0, nColumns))
inverse->at(i, j) = (fracInverse.at(i, j) * detM).getAsInteger();
return detM;
@@ -579,8 +580,8 @@ FracMatrix FracMatrix::identity(unsigned dimension) {
FracMatrix::FracMatrix(IntMatrix m)
: FracMatrix(m.getNumRows(), m.getNumColumns()) {
- for (unsigned i = 0, r = m.getNumRows(); i < r; i++)
- for (unsigned j = 0, c = m.getNumColumns(); j < c; j++)
+ for (int i : llvm::seq<int>(0, m.getNumRows()))
+ for (int j : llvm::seq<int>(0, m.getNumColumns()))
this->at(i, j) = m.at(i, j);
}
@@ -602,12 +603,12 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
// which is initially identity.
// Either way, the product of the diagonal elements
// is then the determinant.
- for (unsigned i = 0; i < nRows; i++) {
+ for (int i : llvm::seq<int>(0, nRows)) {
if (m(i, i) == 0)
// First ensure that the diagonal
// element is nonzero, by swapping
// it with a nonzero row.
- for (unsigned j = i + 1; j < nRows; j++) {
+ for (int j : llvm::seq<int>(i + 1, nRows)) {
if (m(j, i) != 0) {
m.swapRows(j, i);
if (inverse)
@@ -623,7 +624,7 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
// Set all elements above the
// diagonal to zero.
if (inverse) {
- for (unsigned j = 0; j < i; j++) {
+ for (int j : llvm::seq<int>(0, i)) {
if (m.at(j, i) == 0)
continue;
a = m.at(j, i);
@@ -637,7 +638,7 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
// Set all elements below the
// diagonal to zero.
- for (unsigned j = i + 1; j < nRows; j++) {
+ for (int j : llvm::seq<int>(i + 1, nRows)) {
if (m.at(j, i) == 0)
continue;
a = m.at(j, i);
@@ -655,15 +656,15 @@ Fraction FracMatrix::determinant(FracMatrix *inverse) const {
// normalize them and apply the same scale to the inverse matrix.
// For efficiency we skip scaling m and just scale tempInv appropriately.
if (inverse) {
- for (unsigned i = 0; i < nRows; i++)
- for (unsigned j = 0; j < nRows; j++)
+ for (int i : llvm::seq<int>(0, nRows))
+ for (int j : llvm::seq<int>(0, nRows))
tempInv.at(i, j) = tempInv.at(i, j) / m(i, i);
*inverse = std::move(tempInv);
}
Fraction determinant = 1;
- for (unsigned i = 0; i < nRows; i++)
+ for (int i : llvm::seq<int>(0, nRows))
determinant *= m.at(i, i);
return determinant;
@@ -678,8 +679,8 @@ FracMatrix FracMatrix::gramSchmidt() const {
// projection along each of the previous vectors.
// This ensures that it has no component in the direction
// of any of the previous vectors.
- for (unsigned i = 1, e = getNumRows(); i < e; i++) {
- for (unsigned j = 0; j < i; j++) {
+ for (int i : llvm::seq<int>(1, getNumRows())) {
+ for (int j : llvm::seq<int>(0, i)) {
Fraction jNormSquared = dotProduct(orth.getRow(j), orth.getRow(j));
assert(jNormSquared != 0 && "some row became zero! Inputs to this "
"function must be linearly independent.");
@@ -730,7 +731,7 @@ void FracMatrix::LLL(Fraction delta) {
// We start from the second row.
unsigned k = 1;
while (k < getNumRows()) {
- for (unsigned j = k - 1; j < k; j--) {
+ for (int j : llvm::reverse(llvm::seq<int>(0, k))) {
// Compute the Gram-Schmidt coefficient μ_jk.
mu = dotProduct(getRow(k), gsOrth.getRow(j)) /
dotProduct(gsOrth.getRow(j), gsOrth.getRow(j));
@@ -763,12 +764,12 @@ IntMatrix FracMatrix::normalizeRows() const {
IntMatrix normalized(numRows, numColumns);
MPInt lcmDenoms = MPInt(1);
- for (unsigned i = 0; i < numRows; i++) {
+ for (int i : llvm::seq<int>(0, numRows)) {
// For a row, first compute the LCM of the denominators.
- for (unsigned j = 0; j < numColumns; j++)
+ for (int j : llvm::seq<int>(0, numColumns))
lcmDenoms = lcm(lcmDenoms, at(i, j).den);
// Then, multiply by it throughout and convert to integers.
- for (unsigned j = 0; j < numColumns; j++)
+ for (int j : llvm::seq<int>(0, numColumns))
normalized(i, j) = (at(i, j) * lcmDenoms).getAsInteger();
}
return normalized;
diff --git a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
index 4fd4886d22536d..673adba4fc8d61 100644
--- a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
+++ b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
@@ -10,6 +10,7 @@
#include "mlir/Analysis/Presburger/Fraction.h"
#include "mlir/Analysis/Presburger/PresburgerSpace.h"
#include "mlir/Analysis/Presburger/Utils.h"
+#include "llvm/ADT/Sequence.h"
using namespace mlir;
using namespace presburger;
@@ -109,7 +110,7 @@ QuasiPolynomial QuasiPolynomial::simplify() {
unsigned numParam = getNumInputs();
- for (unsigned i = 0, e = coefficients.size(); i < e; i++) {
+ for (int i : llvm::seq<int>(0, coefficients.size())) {
// A term is zero if its coefficient is zero, or
if (coefficients[i] == Fraction(0, 1))
continue;
@@ -148,9 +149,9 @@ QuasiPolynomial QuasiPolynomial::collectTerms() {
SmallVector<Fraction> newCoeffs({});
std::vector<std::vector<SmallVector<Fraction>>> newAffine({});
- for (unsigned i = 0, e = affine.size(); i < e; i++) {
+ for (int i : llvm::seq<int>(0, affine.size())) {
bool alreadyPresent = false;
- for (unsigned j = 0, f = newAffine.size(); j < f; j++) {
+ for (int j : llvm::seq<int>(0, newAffine.size())) {
if (affine[i] == newAffine[j]) {
newCoeffs[j] += coefficients[i];
alreadyPresent = true;
@@ -167,7 +168,7 @@ QuasiPolynomial QuasiPolynomial::collectTerms() {
Fraction QuasiPolynomial::getConstantTerm() {
Fraction constTerm = 0;
- for (unsigned i = 0, e = coefficients.size(); i < e; ++i)
+ for (int i : llvm::seq<int>(0, coefficients.size()))
if (affine[i].size() == 0)
constTerm += coefficients[i];
return constTerm;
diff --git a/mlir/lib/Analysis/Presburger/Utils.cpp b/mlir/lib/Analysis/Presburger/Utils.cpp
index f717a4de5d7283..ae4602f2690fb0 100644
--- a/mlir/lib/Analysis/Presburger/Utils.cpp
+++ b/mlir/lib/Analysis/Presburger/Utils.cpp
@@ -17,6 +17,7 @@
#include "mlir/Support/LLVM.h"
#include "mlir/Support/LogicalResult.h"
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -534,7 +535,7 @@ Fraction presburger::dotProduct(ArrayRef<Fraction> a, ArrayRef<Fraction> b) {
assert(a.size() == b.size() &&
"dot product is only valid for vectors of equal sizes!");
Fraction sum = 0;
- for (unsigned i = 0, e = a.size(); i < e; i++)
+ for (int i : llvm::seq<int>(0, a.size()))
sum += a[i] * b[i];
return sum;
}
@@ -557,9 +558,9 @@ std::vector<Fraction> presburger::multiplyPolynomials(ArrayRef<Fraction> a,
std::vector<Fraction> convolution;
convolution.reserve(len);
- for (unsigned k = 0; k < len; ++k) {
+ for (int k : llvm::seq<int>(0, len)) {
Fraction sum(0, 1);
- for (unsigned l = 0; l <= k; ++l)
+ for (int l : llvm::seq<int>(0, k + 1))
sum += getCoeff(a, l) * getCoeff(b, k - l);
convolution.push_back(sum);
}
diff --git a/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp b/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp
index 5e279b542fdf95..e3b081da85a0dd 100644
--- a/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/BarvinokTest.cpp
@@ -93,7 +93,7 @@ TEST(BarvinokTest, getNonOrthogonalVector) {
Point({2, 7, 0, 0}), Point({0, 0, 0, 0})};
Point nonOrth = getNonOrthogonalVector(vectors);
- for (unsigned i = 0; i < 3; i++)
+ for (unsigned i = 0; i < 3; ++i)
EXPECT_NE(dotProduct(nonOrth, vectors[i]), 0);
vectors = {Point({0, 1, 3}), Point({-2, -1, 1}), Point({6, 3, 0}),
@@ -160,7 +160,7 @@ TEST(BarvinokTest, computeNumTermsCone) {
// terms with 1 affine function,
Fraction pSquaredCoeff = 0, pCoeff = 0, constantTerm = 0;
SmallVector<Fraction> coefficients = numPoints.getCoefficients();
- for (unsigned i = 0; i < numPoints.getCoefficients().size(); i++)
+ for (int i : llvm::seq<int>(0, numPoints.getCoefficients().size()))
if (numPoints.getAffine()[i].size() == 2)
pSquaredCoeff = pSquaredCoeff + coefficients[i];
else if (numPoints.getAffine()[i].size() == 1)
@@ -214,7 +214,7 @@ TEST(BarvinokTest, computeNumTermsCone) {
// We store the coefficients of M, N and P in this array.
Fraction count[2][2][2];
coefficients = numPoints.getCoefficients();
- for (unsigned i = 0, e = coefficients.size(); i < e; i++) {
+ for (int i : llvm::seq<int>(0, coefficients.size())) {
unsigned mIndex = 0, nIndex = 0, pIndex = 0;
for (const SmallVector<Fraction> &aff : numPoints.getAffine()[i]) {
if (aff[0] == 1)
@@ -231,9 +231,9 @@ TEST(BarvinokTest, computeNumTermsCone) {
// We expect the answer to be
// (⌊M⌋ + 1)(⌊N⌋ + 1)(⌊P⌋ + 1) =
// ⌊M⌋⌊N⌋⌊P⌋ + ⌊M⌋⌊N⌋ + ⌊N⌋⌊P⌋ + ⌊M⌋⌊P⌋ + ⌊M⌋ + ⌊N⌋ + ⌊P⌋ + 1.
- for (unsigned i = 0; i < 2; i++)
- for (unsigned j = 0; j < 2; j++)
- for (unsigned k = 0; k < 2; k++)
+ for (unsigned i = 0; i < 2; ++i)
+ for (unsigned j = 0; j < 2; ++j)
+ for (unsigned k = 0; k < 2; ++k)
EXPECT_EQ(count[i][j][k], 1);
}
diff --git a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
index fa1f32970b1463..feda98d0b1817a 100644
--- a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
@@ -344,8 +344,8 @@ TEST(MatrixTest, gramSchmidt) {
FracMatrix gs = mat.gramSchmidt();
EXPECT_EQ_FRAC_MATRIX(gs, gramSchmidt);
- for (unsigned i = 0; i < 3u; i++)
- for (unsigned j = i + 1; j < 3u; j++)
+ for (unsigned i = 0; i < 3u; ++i)
+ for (unsigned j = i + 1; j < 3u; ++j)
EXPECT_EQ(dotProduct(gs.getRow(i), gs.getRow(j)), 0);
mat = makeFracMatrix(3, 3,
@@ -362,8 +362,8 @@ TEST(MatrixTest, gramSchmidt) {
gs = mat.gramSchmidt();
EXPECT_EQ_FRAC_MATRIX(gs, gramSchmidt);
- for (unsigned i = 0; i < 3u; i++)
- for (unsigned j = i + 1; j < 3u; j++)
+ for (unsigned i = 0; i < 3u; ++i)
+ for (unsigned j = i + 1; j < 3u; ++j)
EXPECT_EQ(dotProduct(gs.getRow(i), gs.getRow(j)), 0);
mat = makeFracMatrix(
@@ -379,8 +379,8 @@ TEST(MatrixTest, gramSchmidt) {
// but we can check that the result is linearly independent.
ASSERT_FALSE(mat.determinant(nullptr) == 0);
- for (unsigned i = 0; i < 4u; i++)
- for (unsigned j = i + 1; j < 4u; j++)
+ for (unsigned i = 0; i < 4u; ++i)
+ for (unsigned j = i + 1; j < 4u; ++j)
EXPECT_EQ(dotProduct(gs.getRow(i), gs.getRow(j)), 0);
mat = FracMatrix::identity(/*dim=*/10);
@@ -394,8 +394,8 @@ void checkReducedBasis(FracMatrix mat, Fraction delta) {
FracMatrix gsOrth = mat.gramSchmidt();
// Size-reduced check.
- for (unsigned i = 0, e = mat.getNumRows(); i < e; i++) {
- for (unsigned j = 0; j < i; j++) {
+ for (int i : llvm::seq<int>(0, mat.getNumRows())) {
+ for (int j : llvm::seq<int>(0, i)) {
Fraction mu = dotProduct(mat.getRow(i), gsOrth.getRow(j)) /
dotProduct(gsOrth.getRow(j), gsOrth.getRow(j));
EXPECT_TRUE(abs(mu) <= Fraction(1, 2));
@@ -403,7 +403,7 @@ void checkReducedBasis(FracMatrix mat, Fraction delta) {
}
// Lovasz condition check.
- for (unsigned i = 1, e = mat.getNumRows(); i < e; i++) {
+ for (int i : llvm::seq<int>(1, mat.getNumRows())) {
Fraction mu = dotProduct(mat.getRow(i), gsOrth.getRow(i - 1)) /
dotProduct(gsOrth.getRow(i - 1), gsOrth.getRow(i - 1));
EXPECT_TRUE(dotProduct(mat.getRow(i), mat.getRow(i)) >
diff --git a/mlir/unittests/Analysis/Presburger/Utils.h b/mlir/unittests/Analysis/Presburger/Utils.h
index 6b00898a7e2749..26970b798953af 100644
--- a/mlir/unittests/Analysis/Presburger/Utils.h
+++ b/mlir/unittests/Analysis/Presburger/Utils.h
@@ -22,6 +22,7 @@
#include "mlir/Analysis/Presburger/Simplex.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Support/LLVM.h"
+#include "llvm/ADT/Sequence.h"
#include <gtest/gtest.h>
#include <optional>
@@ -33,10 +34,10 @@ inline IntMatrix makeIntMatrix(unsigned numRow, unsigned numColumns,
ArrayRef<SmallVector<int, 8>> matrix) {
IntMatrix results(numRow, numColumns);
assert(matrix.size() == numRow);
- for (unsigned i = 0; i < numRow; ++i) {
+ for (int i : llvm::seq<int>(0, numRow)) {
assert(matrix[i].size() == numColumns &&
"Output expression has incorrect dimensionality!");
- for (unsigned j = 0; j < numColumns; ++j)
+ for (int j : llvm::seq<int>(0, numColumns))
results(i, j) = MPInt(matrix[i][j]);
}
return results;
@@ -46,10 +47,10 @@ inline FracMatrix makeFracMatrix(unsigned numRow, unsigned numColumns,
ArrayRef<SmallVector<Fraction, 8>> matrix) {
FracMatrix results(numRow, numColumns);
assert(matrix.size() == numRow);
- for (unsigned i = 0; i < numRow; ++i) {
+ for (int i : llvm::seq<int>(0, numRow)) {
assert(matrix[i].size() == numColumns &&
"Output expression has incorrect dimensionality!");
- for (unsigned j = 0; j < numColumns; ++j)
+ for (int j : llvm::seq<int>(0, numColumns))
results(i, j) = matrix[i][j];
}
return results;
@@ -59,8 +60,8 @@ inline void EXPECT_EQ_INT_MATRIX(IntMatrix a, IntMatrix b) {
EXPECT_EQ(a.getNumRows(), b.getNumRows());
EXPECT_EQ(a.getNumColumns(), b.getNumColumns());
- for (unsigned row = 0; row < a.getNumRows(); row++)
- for (unsigned col = 0; col < a.getNumColumns(); col++)
+ for (int row : llvm::seq<int>(0, a.getNumRows()))
+ for (int col : llvm::seq<int>(0, a.getNumColumns()))
EXPECT_EQ(a(row, col), b(row, col));
}
@@ -68,8 +69,8 @@ inline void EXPECT_EQ_FRAC_MATRIX(FracMatrix a, FracMatrix b) {
EXPECT_EQ(a.getNumRows(), b.getNumRows());
EXPECT_EQ(a.getNumColumns(), b.getNumColumns());
- for (unsigned row = 0; row < a.getNumRows(); row++)
- for (unsigned col = 0; col < a.getNumColumns(); col++)
+ for (int row : llvm::seq<int>(0, a.getNumRows()))
+ for (int col : llvm::seq<int>(0, a.getNumColumns()))
EXPECT_EQ(a(row, col), b(row, col));
}
@@ -82,25 +83,24 @@ inline void EXPECT_EQ_REPR_GENERATINGFUNCTION(detail::GeneratingFunction a,
SmallVector<int> aSigns = a.getSigns();
SmallVector<int> bSigns = b.getSigns();
EXPECT_EQ(aSigns.size(), bSigns.size());
- for (unsigned i = 0, e = aSigns.size(); i < e; i++)
+ for (int i : llvm::seq<int>(0, aSigns.size()))
EXPECT_EQ(aSigns[i], bSigns[i]);
std::vector<detail::ParamPoint> aNums = a.getNumerators();
std::vector<detail::ParamPoint> bNums = b.getNumerators();
EXPECT_EQ(aNums.size(), bNums.size());
- for (unsigned i = 0, e = aNums.size(); i < e; i++)
+ for (int i : llvm::seq<int>(0, aNums.size()))
EXPECT_EQ_FRAC_MATRIX(aNums[i], bNums[i]);
std::vector<std::vector<detail::Point>> aDens = a.getDenominators();
std::vector<std::vector<detail::Point>> bDens = b.getDenominators();
EXPECT_EQ(aDens.size(), bDens.size());
- for (unsigned i = 0, e = aDens.size(); i < e; i++) {
+ for (int i : llvm::seq<int>(0, aDens.size())) {
EXPECT_EQ(aDens[i].size(), bDens[i].size());
- for (unsigned j = 0, f = aDens[i].size(); j < f; j++) {
+ for (int j : llvm::seq<int>(0, aDens[i].size())) {
EXPECT_EQ(aDens[i][j].size(), bDens[i][j].size());
- for (unsigned k = 0, g = aDens[i][j].size(); k < g; k++) {
+ for (int k : llvm::seq<int>(0, aDens[i][j].size()))
EXPECT_EQ(aDens[i][j][k], bDens[i][j][k]);
- }
}
}
}
@@ -114,16 +114,16 @@ inline void EXPECT_EQ_REPR_QUASIPOLYNOMIAL(QuasiPolynomial a,
SmallVector<Fraction> aCoeffs = a.getCoefficients(),
bCoeffs = b.getCoefficients();
EXPECT_EQ(aCoeffs.size(), bCoeffs.size());
- for (unsigned i = 0, e = aCoeffs.size(); i < e; i++)
+ for (int i : llvm::seq<int>(0, aCoeffs.size()))
EXPECT_EQ(aCoeffs[i], bCoeffs[i]);
std::vector<std::vector<SmallVector<Fraction>>> aAff = a.getAffine(),
bAff = b.getAffine();
EXPECT_EQ(aAff.size(), bAff.size());
- for (unsigned i = 0, e = aAff.size(); i < e; i++) {
+ for (int i : llvm::seq<int>(0, aAff.size())) {
EXPECT_EQ(aAff[i].size(), bAff[i].size());
- for (unsigned j = 0, f = aAff[i].size(); j < f; j++)
- for (unsigned k = 0, g = a.getNumInputs(); k <= g; k++)
+ for (int j : llvm::seq<int>(0, aAff[i].size()))
+ for (int k : llvm::seq<int>(0, a.getNumInputs()))
EXPECT_EQ(aAff[i][j][k], bAff[i][j][k]);
}
}
>From 13a2411303ac6a67a8f24b6bc85f95a4235b320e Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Mon, 19 Feb 2024 23:14:43 +0530
Subject: [PATCH 2/6] Define and use increment operator for quasipolynomials
---
mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h | 1 +
mlir/lib/Analysis/Presburger/Barvinok.cpp | 7 +++----
mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp | 4 ++++
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
index aeac19e827b44f..2518a0a4908120 100644
--- a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
+++ b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
@@ -58,6 +58,7 @@ class QuasiPolynomial : public PresburgerSpace {
QuasiPolynomial operator-(const QuasiPolynomial &x) const;
QuasiPolynomial operator*(const QuasiPolynomial &x) const;
QuasiPolynomial operator/(const Fraction x) const;
+ void operator+=(const QuasiPolynomial &x);
// Removes terms which evaluate to zero from the expression
// and folds affine functions which are constant into the
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index c483b9a4b81f37..d5b6d6024a6a56 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -777,10 +777,9 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
denominatorCoefficients =
multiplyPolynomials(denominatorCoefficients, eachTermDenCoefficient);
- totalTerm =
- totalTerm + getCoefficientInRationalFunction(r, numeratorCoefficients,
- denominatorCoefficients) *
- QuasiPolynomial(numParams, sign);
+ totalTerm += getCoefficientInRationalFunction(r, numeratorCoefficients,
+ denominatorCoefficients) *
+ QuasiPolynomial(numParams, sign);
}
return totalTerm.simplify();
diff --git a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
index 673adba4fc8d61..edb4c091e15547 100644
--- a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
+++ b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
@@ -98,6 +98,10 @@ QuasiPolynomial QuasiPolynomial::operator/(const Fraction x) const {
return qp;
}
+void QuasiPolynomial::operator+=(const QuasiPolynomial &x) {
+ *this = *this + x;
+}
+
// Removes terms which evaluate to zero from the expression and
// integrate affine functions which are constants into the
// coefficients.
>From 73702af15fa291d4951aaa6ad6aa43326fa6727a Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Mon, 19 Feb 2024 23:19:08 +0530
Subject: [PATCH 3/6] Use EXPECT_NE
---
mlir/unittests/Analysis/Presburger/MatrixTest.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
index feda98d0b1817a..a3b898c529c77d 100644
--- a/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
+++ b/mlir/unittests/Analysis/Presburger/MatrixTest.cpp
@@ -377,7 +377,7 @@ TEST(MatrixTest, gramSchmidt) {
// The integers involved are too big to construct the actual matrix.
// but we can check that the result is linearly independent.
- ASSERT_FALSE(mat.determinant(nullptr) == 0);
+ EXPECT_NE(mat.determinant(nullptr), 0);
for (unsigned i = 0; i < 4u; ++i)
for (unsigned j = i + 1; j < 4u; ++j)
>From da73e0ceea9af13f7a88170aa036ceceb1e6ecb7 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Mon, 19 Feb 2024 23:38:16 +0530
Subject: [PATCH 4/6] Change terminology to symbols in GF
---
.../mlir/Analysis/Presburger/GeneratingFunction.h | 15 ++++++++-------
mlir/lib/Analysis/Presburger/Barvinok.cpp | 2 +-
mlir/unittests/Analysis/Presburger/Utils.h | 2 +-
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
index e90a991d5c4809..d19945d2c5266d 100644
--- a/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
+++ b/mlir/include/mlir/Analysis/Presburger/GeneratingFunction.h
@@ -51,19 +51,20 @@ using Point = SmallVector<Fraction>;
// g_{ij} \in Q^n are vectors.
class GeneratingFunction {
public:
- GeneratingFunction(unsigned numParam, SmallVector<int> signs,
+ GeneratingFunction(unsigned numSymbols, SmallVector<int> signs,
std::vector<ParamPoint> nums,
std::vector<std::vector<Point>> dens)
- : numParam(numParam), signs(signs), numerators(nums), denominators(dens) {
+ : numSymbols(numSymbols), signs(signs), numerators(nums),
+ denominators(dens) {
#ifndef NDEBUG
for (const ParamPoint &term : numerators)
- assert(term.getNumRows() == numParam + 1 &&
+ assert(term.getNumRows() == numSymbols + 1 &&
"dimensionality of numerator exponents does not match number of "
"parameters!");
#endif // NDEBUG
}
- unsigned getNumParams() const { return numParam; }
+ unsigned getNumSymbols() const { return numSymbols; }
SmallVector<int> getSigns() const { return signs; }
@@ -74,7 +75,7 @@ class GeneratingFunction {
}
GeneratingFunction operator+(const GeneratingFunction &gf) const {
- assert(numParam == gf.getNumParams() &&
+ assert(numSymbols == gf.getNumSymbols() &&
"two generating functions with different numbers of parameters "
"cannot be added!");
SmallVector<int> sumSigns = signs;
@@ -87,7 +88,7 @@ class GeneratingFunction {
std::vector<std::vector<Point>> sumDenominators = denominators;
sumDenominators.insert(sumDenominators.end(), gf.denominators.begin(),
gf.denominators.end());
- return GeneratingFunction(numParam, sumSigns, sumNumerators,
+ return GeneratingFunction(numSymbols, sumSigns, sumNumerators,
sumDenominators);
}
@@ -127,7 +128,7 @@ class GeneratingFunction {
}
private:
- unsigned numParam;
+ unsigned numSymbols;
SmallVector<int> signs;
std::vector<ParamPoint> numerators;
std::vector<std::vector<Point>> denominators;
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index d5b6d6024a6a56..1803b751a06838 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -696,7 +696,7 @@ mlir::presburger::detail::computeNumTerms(const GeneratingFunction &gf) {
allDenominators.insert(allDenominators.end(), den.begin(), den.end());
Point mu = getNonOrthogonalVector(allDenominators);
- unsigned numParams = gf.getNumParams();
+ unsigned numParams = gf.getNumSymbols();
const std::vector<std::vector<Point>> &ds = gf.getDenominators();
QuasiPolynomial totalTerm(numParams, 0);
for (int i : llvm::seq<int>(0, ds.size())) {
diff --git a/mlir/unittests/Analysis/Presburger/Utils.h b/mlir/unittests/Analysis/Presburger/Utils.h
index 26970b798953af..ed4b04cb7880e6 100644
--- a/mlir/unittests/Analysis/Presburger/Utils.h
+++ b/mlir/unittests/Analysis/Presburger/Utils.h
@@ -78,7 +78,7 @@ inline void EXPECT_EQ_FRAC_MATRIX(FracMatrix a, FracMatrix b) {
// Note that this is not a true equality check.
inline void EXPECT_EQ_REPR_GENERATINGFUNCTION(detail::GeneratingFunction a,
detail::GeneratingFunction b) {
- EXPECT_EQ(a.getNumParams(), b.getNumParams());
+ EXPECT_EQ(a.getNumSymbols(), b.getNumSymbols());
SmallVector<int> aSigns = a.getSigns();
SmallVector<int> bSigns = b.getSigns();
>From 50d826db2d076375d4e377cfc04deefad91422d9 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Fri, 23 Feb 2024 17:26:54 +0530
Subject: [PATCH 5/6] Proof for intersection case
---
mlir/lib/Analysis/Presburger/Barvinok.cpp | 28 +++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/mlir/lib/Analysis/Presburger/Barvinok.cpp b/mlir/lib/Analysis/Presburger/Barvinok.cpp
index 1803b751a06838..e5a81230fede7f 100644
--- a/mlir/lib/Analysis/Presburger/Barvinok.cpp
+++ b/mlir/lib/Analysis/Presburger/Barvinok.cpp
@@ -235,6 +235,34 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
/// generating functions the region that (the sum of) precisely this subset is
/// in, is the intersection of the regions that these are active in,
/// intersected with the complements of the remaining regions.
+///
+/// If the parameter values lie in the intersection of two chambers with
+/// differing vertex sets, the answer is given by considering either one.
+/// Assume that the chambers differ in that one has k+1 vertices and the other
+/// only k – we can then show that the same vertex is counted twice in the
+/// former, and so the sets are in fact the same. This is proved below.
+/// Consider a parametric polyhedron D in n variables and m parameters. We want
+/// to show that if two vertices' chambers intersect, then the vertices collapse
+/// in this region.
+///
+/// Let D' be the polyhedron in combined data-and-parameter space (R^{n+m}).
+/// Then we have from [1] that:
+///
+/// * a vertex is a 0-dimensional face of D, which is equivalent to an m-face
+/// F_i^m of D'.
+/// * a vertex v_i(p) is obtained from F_i^m(D') by projecting down to n-space
+/// (see Fig. 1).
+/// * the region a vertex exists in is given by projecting F_i^m(D') down to
+/// m-space.
+///
+/// Thus, if two chambers intersect, this means that the corresponding faces
+/// (say F_i^m(D') and F_j^m(D')) also have some intersection. Since the
+/// vertices v_i and v_j correspond to the projections of F_i^m(D') and
+/// F_j^m(D'), they must collapse in the intersection.
+///
+/// [1]: Parameterized Polyhedra and Their Vertices (Loechner & Wilde, 1997)
+/// https://link.springer.com/article/10.1023/A:1025117523902
+
std::vector<std::pair<PresburgerSet, GeneratingFunction>>
mlir::presburger::detail::computeChamberDecomposition(
unsigned numSymbols, ArrayRef<std::pair<PresburgerSet, GeneratingFunction>>
>From b5fae3fb76a92165eb17039ce6fb63afe51c5967 Mon Sep 17 00:00:00 2001
From: Abhinav271828 <abhinav.m at research.iiit.ac.in>
Date: Fri, 23 Feb 2024 18:01:30 +0530
Subject: [PATCH 6/6] Implement evaluation of QPs
---
.../Analysis/Presburger/QuasiPolynomial.h | 2 ++
.../Analysis/Presburger/QuasiPolynomial.cpp | 24 +++++++++++++++++++
2 files changed, 26 insertions(+)
diff --git a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
index 2518a0a4908120..a3af219192fbe1 100644
--- a/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
+++ b/mlir/include/mlir/Analysis/Presburger/QuasiPolynomial.h
@@ -70,6 +70,8 @@ class QuasiPolynomial : public PresburgerSpace {
Fraction getConstantTerm();
+ Fraction evaluateAt(const SmallVector<Fraction> ¶meters);
+
private:
SmallVector<Fraction> coefficients;
std::vector<std::vector<SmallVector<Fraction>>> affine;
diff --git a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
index edb4c091e15547..816e5ac72f66c1 100644
--- a/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
+++ b/mlir/lib/Analysis/Presburger/QuasiPolynomial.cpp
@@ -177,3 +177,27 @@ Fraction QuasiPolynomial::getConstantTerm() {
constTerm += coefficients[i];
return constTerm;
}
+
+Fraction QuasiPolynomial::evaluateAt(const SmallVector<Fraction> ¶meters) {
+ assert(parameters.size() == getNumInputs() &&
+ "the size of the input vector does not match the dimensionality of "
+ "the polynomial!");
+
+ unsigned numParams = parameters.size();
+ Fraction sum = 0;
+ // The value of the function is given by a sum of terms,
+ for (int i : llvm::seq<int>(0, coefficients.size())) {
+ // each of which is a coefficient, multiplied by the product of
+ Fraction product = coefficients[i];
+ for (int j : llvm::seq<int>(0, affine[i].size())) {
+ ArrayRef<Fraction> affineFunction(affine[i][j]);
+ // the floors of some affine functions.
+ Fraction value =
+ floor(dotProduct(affineFunction.slice(numParams), parameters) +
+ affineFunction.back());
+ product *= value;
+ }
+ sum += coefficients[i] * product;
+ }
+ return sum;
+}
\ No newline at end of file
More information about the Mlir-commits
mailing list