Revert "[MLIR][Presburger] Template Matrix to allow MPInt and Fraction (#65272)"

This reverts commit efca035c6d28542ad6374cd8bf17ae7c72407ead.

Reverting due to windows build bot failure:
https://lab.llvm.org/buildbot/#/builders/13/builds/40242/steps/6/logs/stdio
This commit is contained in:
Arjun P 2023-09-18 19:06:32 +01:00
parent 054f9c55c6
commit 98c994c8e2
15 changed files with 127 additions and 163 deletions

View File

@ -366,7 +366,7 @@ public:
/// bounded. The span of the returned vectors is guaranteed to contain all /// bounded. The span of the returned vectors is guaranteed to contain all
/// such vectors. The returned vectors are NOT guaranteed to be linearly /// such vectors. The returned vectors are NOT guaranteed to be linearly
/// independent. This function should not be called on empty sets. /// independent. This function should not be called on empty sets.
Matrix<MPInt> getBoundedDirections() const; Matrix getBoundedDirections() const;
/// Find an integer sample point satisfying the constraints using a /// Find an integer sample point satisfying the constraints using a
/// branch and bound algorithm with generalized basis reduction, with some /// branch and bound algorithm with generalized basis reduction, with some
@ -792,10 +792,10 @@ protected:
PresburgerSpace space; PresburgerSpace space;
/// Coefficients of affine equalities (in == 0 form). /// Coefficients of affine equalities (in == 0 form).
Matrix<MPInt> equalities; Matrix equalities;
/// Coefficients of affine inequalities (in >= 0 form). /// Coefficients of affine inequalities (in >= 0 form).
Matrix<MPInt> inequalities; Matrix inequalities;
}; };
/// An IntegerPolyhedron represents the set of points from a PresburgerSpace /// An IntegerPolyhedron represents the set of points from a PresburgerSpace

View File

@ -22,8 +22,8 @@ namespace presburger {
class LinearTransform { class LinearTransform {
public: public:
explicit LinearTransform(Matrix<MPInt> &&oMatrix); explicit LinearTransform(Matrix &&oMatrix);
explicit LinearTransform(const Matrix<MPInt> &oMatrix); explicit LinearTransform(const Matrix &oMatrix);
// Returns a linear transform T such that MT is M in column echelon form. // Returns a linear transform T such that MT is M in column echelon form.
// Also returns the number of non-zero columns in MT. // Also returns the number of non-zero columns in MT.
@ -32,7 +32,7 @@ public:
// strictly below that of the previous column, and all columns which have only // strictly below that of the previous column, and all columns which have only
// zeros are at the end. // zeros are at the end.
static std::pair<unsigned, LinearTransform> static std::pair<unsigned, LinearTransform>
makeTransformToColumnEchelon(const Matrix<MPInt> &m); makeTransformToColumnEchelon(const Matrix &m);
// Returns an IntegerRelation having a constraint vector vT for every // Returns an IntegerRelation having a constraint vector vT for every
// constraint vector v in rel, where T is this transform. // constraint vector v in rel, where T is this transform.
@ -50,12 +50,8 @@ public:
return matrix.postMultiplyWithColumn(colVec); return matrix.postMultiplyWithColumn(colVec);
} }
// Compute the determinant of the transform by converting it to row echelon
// form and then taking the product of the diagonal.
MPInt determinant();
private: private:
Matrix<MPInt> matrix; Matrix matrix;
}; };
} // namespace presburger } // namespace presburger

View File

@ -7,17 +7,15 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// //
// This is a simple 2D matrix class that supports reading, writing, resizing, // This is a simple 2D matrix class that supports reading, writing, resizing,
// swapping rows, and swapping columns. It can hold integers (MPInt) or rational // swapping rows, and swapping columns.
// numbers (Fraction).
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef MLIR_ANALYSIS_PRESBURGER_MATRIX_H #ifndef MLIR_ANALYSIS_PRESBURGER_MATRIX_H
#define MLIR_ANALYSIS_PRESBURGER_MATRIX_H #define MLIR_ANALYSIS_PRESBURGER_MATRIX_H
#include "mlir/Analysis/Presburger/MPInt.h"
#include "mlir/Support/LLVM.h" #include "mlir/Support/LLVM.h"
#include "mlir/Analysis/Presburger/Fraction.h"
#include "mlir/Analysis/Presburger/Matrix.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@ -34,12 +32,7 @@ namespace presburger {
/// (i, j) is stored at data[i*nReservedColumns + j]. The reserved but unused /// (i, j) is stored at data[i*nReservedColumns + j]. The reserved but unused
/// columns always have all zero values. The reserved rows are just reserved /// columns always have all zero values. The reserved rows are just reserved
/// space in the underlying SmallVector's capacity. /// space in the underlying SmallVector's capacity.
/// This class only works for the types MPInt and Fraction, since the method
/// implementations are in the Matrix.cpp file. Only these two types have
/// been explicitly instantiated there.
template<typename T>
class Matrix { class Matrix {
static_assert(std::is_same_v<T,MPInt> || std::is_same_v<T,Fraction>, "T must be MPInt or Fraction.");
public: public:
Matrix() = delete; Matrix() = delete;
@ -56,21 +49,21 @@ public:
static Matrix identity(unsigned dimension); static Matrix identity(unsigned dimension);
/// Access the element at the specified row and column. /// Access the element at the specified row and column.
T &at(unsigned row, unsigned column) { MPInt &at(unsigned row, unsigned column) {
assert(row < nRows && "Row outside of range"); assert(row < nRows && "Row outside of range");
assert(column < nColumns && "Column outside of range"); assert(column < nColumns && "Column outside of range");
return data[row * nReservedColumns + column]; return data[row * nReservedColumns + column];
} }
T at(unsigned row, unsigned column) const { MPInt at(unsigned row, unsigned column) const {
assert(row < nRows && "Row outside of range"); assert(row < nRows && "Row outside of range");
assert(column < nColumns && "Column outside of range"); assert(column < nColumns && "Column outside of range");
return data[row * nReservedColumns + column]; return data[row * nReservedColumns + column];
} }
T &operator()(unsigned row, unsigned column) { return at(row, column); } MPInt &operator()(unsigned row, unsigned column) { return at(row, column); }
T operator()(unsigned row, unsigned column) const { MPInt operator()(unsigned row, unsigned column) const {
return at(row, column); return at(row, column);
} }
@ -94,11 +87,11 @@ public:
void reserveRows(unsigned rows); void reserveRows(unsigned rows);
/// Get a [Mutable]ArrayRef corresponding to the specified row. /// Get a [Mutable]ArrayRef corresponding to the specified row.
MutableArrayRef<T> getRow(unsigned row); MutableArrayRef<MPInt> getRow(unsigned row);
ArrayRef<T> getRow(unsigned row) const; ArrayRef<MPInt> getRow(unsigned row) const;
/// Set the specified row to `elems`. /// Set the specified row to `elems`.
void setRow(unsigned row, ArrayRef<T> elems); void setRow(unsigned row, ArrayRef<MPInt> elems);
/// Insert columns having positions pos, pos + 1, ... pos + count - 1. /// Insert columns having positions pos, pos + 1, ... pos + count - 1.
/// Columns that were at positions 0 to pos - 1 will stay where they are; /// Columns that were at positions 0 to pos - 1 will stay where they are;
@ -132,23 +125,23 @@ public:
void copyRow(unsigned sourceRow, unsigned targetRow); void copyRow(unsigned sourceRow, unsigned targetRow);
void fillRow(unsigned row, const T &value); void fillRow(unsigned row, const MPInt &value);
void fillRow(unsigned row, int64_t value) { fillRow(row, T(value)); } void fillRow(unsigned row, int64_t value) { fillRow(row, MPInt(value)); }
/// Add `scale` multiples of the source row to the target row. /// Add `scale` multiples of the source row to the target row.
void addToRow(unsigned sourceRow, unsigned targetRow, const T &scale); void addToRow(unsigned sourceRow, unsigned targetRow, const MPInt &scale);
void addToRow(unsigned sourceRow, unsigned targetRow, int64_t scale) { void addToRow(unsigned sourceRow, unsigned targetRow, int64_t scale) {
addToRow(sourceRow, targetRow, T(scale)); addToRow(sourceRow, targetRow, MPInt(scale));
} }
/// Add `scale` multiples of the rowVec row to the specified row. /// Add `scale` multiples of the rowVec row to the specified row.
void addToRow(unsigned row, ArrayRef<T> rowVec, const T &scale); void addToRow(unsigned row, ArrayRef<MPInt> rowVec, const MPInt &scale);
/// Add `scale` multiples of the source column to the target column. /// Add `scale` multiples of the source column to the target column.
void addToColumn(unsigned sourceColumn, unsigned targetColumn, void addToColumn(unsigned sourceColumn, unsigned targetColumn,
const T &scale); const MPInt &scale);
void addToColumn(unsigned sourceColumn, unsigned targetColumn, void addToColumn(unsigned sourceColumn, unsigned targetColumn,
int64_t scale) { int64_t scale) {
addToColumn(sourceColumn, targetColumn, T(scale)); addToColumn(sourceColumn, targetColumn, MPInt(scale));
} }
/// Negate the specified column. /// Negate the specified column.
@ -159,18 +152,18 @@ public:
/// Divide the first `nCols` of the specified row by their GCD. /// Divide the first `nCols` of the specified row by their GCD.
/// Returns the GCD of the first `nCols` of the specified row. /// Returns the GCD of the first `nCols` of the specified row.
T normalizeRow(unsigned row, unsigned nCols); MPInt normalizeRow(unsigned row, unsigned nCols);
/// Divide the columns of the specified row by their GCD. /// Divide the columns of the specified row by their GCD.
/// Returns the GCD of the columns of the specified row. /// Returns the GCD of the columns of the specified row.
T normalizeRow(unsigned row); MPInt normalizeRow(unsigned row);
/// The given vector is interpreted as a row vector v. Post-multiply v with /// The given vector is interpreted as a row vector v. Post-multiply v with
/// this matrix, say M, and return vM. /// this matrix, say M, and return vM.
SmallVector<T, 8> preMultiplyWithRow(ArrayRef<T> rowVec) const; SmallVector<MPInt, 8> preMultiplyWithRow(ArrayRef<MPInt> rowVec) const;
/// The given vector is interpreted as a column vector v. Pre-multiply v with /// The given vector is interpreted as a column vector v. Pre-multiply v with
/// this matrix, say M, and return Mv. /// this matrix, say M, and return Mv.
SmallVector<T, 8> postMultiplyWithColumn(ArrayRef<T> colVec) const; SmallVector<MPInt, 8> postMultiplyWithColumn(ArrayRef<MPInt> colVec) const;
/// Given the current matrix M, returns the matrices H, U such that H is the /// Given the current matrix M, returns the matrices H, U such that H is the
/// column hermite normal form of M, i.e. H = M * U, where U is unimodular and /// column hermite normal form of M, i.e. H = M * U, where U is unimodular and
@ -199,7 +192,7 @@ public:
unsigned appendExtraRow(); unsigned appendExtraRow();
/// Same as above, but copy the given elements into the row. The length of /// Same as above, but copy the given elements into the row. The length of
/// `elems` must be equal to the number of columns. /// `elems` must be equal to the number of columns.
unsigned appendExtraRow(ArrayRef<T> elems); unsigned appendExtraRow(ArrayRef<MPInt> elems);
/// Print the matrix. /// Print the matrix.
void print(raw_ostream &os) const; void print(raw_ostream &os) const;
@ -218,7 +211,7 @@ private:
/// Stores the data. data.size() is equal to nRows * nReservedColumns. /// Stores the data. data.size() is equal to nRows * nReservedColumns.
/// data.capacity() / nReservedColumns is the number of reserved rows. /// data.capacity() / nReservedColumns is the number of reserved rows.
SmallVector<T, 16> data; SmallVector<MPInt, 16> data;
}; };
} // namespace presburger } // namespace presburger

View File

@ -40,13 +40,13 @@ enum class OrderingKind { EQ, NE, LT, LE, GT, GE };
/// value of the function at a specified point. /// value of the function at a specified point.
class MultiAffineFunction { class MultiAffineFunction {
public: public:
MultiAffineFunction(const PresburgerSpace &space, const Matrix<MPInt> &output) MultiAffineFunction(const PresburgerSpace &space, const Matrix &output)
: space(space), output(output), : space(space), output(output),
divs(space.getNumVars() - space.getNumRangeVars()) { divs(space.getNumVars() - space.getNumRangeVars()) {
assertIsConsistent(); assertIsConsistent();
} }
MultiAffineFunction(const PresburgerSpace &space, const Matrix<MPInt> &output, MultiAffineFunction(const PresburgerSpace &space, const Matrix &output,
const DivisionRepr &divs) const DivisionRepr &divs)
: space(space), output(output), divs(divs) { : space(space), output(output), divs(divs) {
assertIsConsistent(); assertIsConsistent();
@ -65,7 +65,7 @@ public:
PresburgerSpace getOutputSpace() const { return space.getRangeSpace(); } PresburgerSpace getOutputSpace() const { return space.getRangeSpace(); }
/// Get a matrix with each row representing row^th output expression. /// Get a matrix with each row representing row^th output expression.
const Matrix<MPInt> &getOutputMatrix() const { return output; } const Matrix &getOutputMatrix() const { return output; }
/// Get the `i^th` output expression. /// Get the `i^th` output expression.
ArrayRef<MPInt> getOutputExpr(unsigned i) const { return output.getRow(i); } ArrayRef<MPInt> getOutputExpr(unsigned i) const { return output.getRow(i); }
@ -124,7 +124,7 @@ private:
/// The function's output is a tuple of integers, with the ith element of the /// The function's output is a tuple of integers, with the ith element of the
/// tuple defined by the affine expression given by the ith row of this output /// tuple defined by the affine expression given by the ith row of this output
/// matrix. /// matrix.
Matrix<MPInt> output; Matrix output;
/// Storage for division representation for each local variable in space. /// Storage for division representation for each local variable in space.
DivisionRepr divs; DivisionRepr divs;

View File

@ -338,7 +338,7 @@ protected:
unsigned nSymbol; unsigned nSymbol;
/// The matrix representing the tableau. /// The matrix representing the tableau.
Matrix<MPInt> tableau; Matrix tableau;
/// This is true if the tableau has been detected to be empty, false /// This is true if the tableau has been detected to be empty, false
/// otherwise. /// otherwise.
@ -861,7 +861,7 @@ private:
/// Reduce the given basis, starting at the specified level, using general /// Reduce the given basis, starting at the specified level, using general
/// basis reduction. /// basis reduction.
void reduceBasis(Matrix<MPInt> &basis, unsigned level); void reduceBasis(Matrix &basis, unsigned level);
}; };
/// Takes a snapshot of the simplex state on construction and rolls back to the /// Takes a snapshot of the simplex state on construction and rolls back to the

View File

@ -182,7 +182,7 @@ private:
/// Each row of the Matrix represents a single division dividend. The /// Each row of the Matrix represents a single division dividend. The
/// `i^th` row represents the dividend of the variable at `divOffset + i` /// `i^th` row represents the dividend of the variable at `divOffset + i`
/// in the constraint system (and the `i^th` local variable). /// in the constraint system (and the `i^th` local variable).
Matrix<MPInt> dividends; Matrix dividends;
/// Denominators of each division. If a denominator of a division is `0`, the /// Denominators of each division. If a denominator of a division is `0`, the
/// division variable is considered to not have a division representation. /// division variable is considered to not have a division representation.

View File

@ -1292,7 +1292,7 @@ mlir::getMultiAffineFunctionFromMap(AffineMap map,
"AffineMap cannot produce divs without local representation"); "AffineMap cannot produce divs without local representation");
// TODO: We shouldn't have to do this conversion. // TODO: We shouldn't have to do this conversion.
Matrix<MPInt> mat(map.getNumResults(), map.getNumInputs() + divs.getNumDivs() + 1); Matrix mat(map.getNumResults(), map.getNumInputs() + divs.getNumDivs() + 1);
for (unsigned i = 0, e = flattenedExprs.size(); i < e; ++i) for (unsigned i = 0, e = flattenedExprs.size(); i < e; ++i)
for (unsigned j = 0, f = flattenedExprs[i].size(); j < f; ++j) for (unsigned j = 0, f = flattenedExprs[i].size(); j < f; ++j)
mat(i, j) = flattenedExprs[i][j]; mat(i, j) = flattenedExprs[i][j];

View File

@ -304,7 +304,7 @@ SymbolicLexOpt IntegerRelation::findSymbolicIntegerLexMax() const {
// Get lexmax by flipping range sign in the PWMA constraints. // Get lexmax by flipping range sign in the PWMA constraints.
for (auto &flippedPiece : for (auto &flippedPiece :
flippedSymbolicIntegerLexMax.lexopt.getAllPieces()) { flippedSymbolicIntegerLexMax.lexopt.getAllPieces()) {
Matrix<MPInt> mat = flippedPiece.output.getOutputMatrix(); Matrix mat = flippedPiece.output.getOutputMatrix();
for (unsigned i = 0, e = mat.getNumRows(); i < e; i++) for (unsigned i = 0, e = mat.getNumRows(); i < e; i++)
mat.negateRow(i); mat.negateRow(i);
MultiAffineFunction maf(flippedPiece.output.getSpace(), mat); MultiAffineFunction maf(flippedPiece.output.getSpace(), mat);
@ -738,7 +738,7 @@ bool IntegerRelation::isEmptyByGCDTest() const {
// //
// It is sufficient to check the perpendiculars of the constraints, as the set // It is sufficient to check the perpendiculars of the constraints, as the set
// of perpendiculars which are bounded must span all bounded directions. // of perpendiculars which are bounded must span all bounded directions.
Matrix<MPInt> IntegerRelation::getBoundedDirections() const { Matrix IntegerRelation::getBoundedDirections() const {
// Note that it is necessary to add the equalities too (which the constructor // Note that it is necessary to add the equalities too (which the constructor
// does) even though we don't need to check if they are bounded; whether an // does) even though we don't need to check if they are bounded; whether an
// inequality is bounded or not depends on what other constraints, including // inequality is bounded or not depends on what other constraints, including
@ -759,7 +759,7 @@ Matrix<MPInt> IntegerRelation::getBoundedDirections() const {
// The direction vector is given by the coefficients and does not include the // The direction vector is given by the coefficients and does not include the
// constant term, so the matrix has one fewer column. // constant term, so the matrix has one fewer column.
unsigned dirsNumCols = getNumCols() - 1; unsigned dirsNumCols = getNumCols() - 1;
Matrix<MPInt> dirs(boundedIneqs.size() + getNumEqualities(), dirsNumCols); Matrix dirs(boundedIneqs.size() + getNumEqualities(), dirsNumCols);
// Copy the bounded inequalities. // Copy the bounded inequalities.
unsigned row = 0; unsigned row = 0;
@ -845,7 +845,7 @@ IntegerRelation::findIntegerSample() const {
// m is a matrix containing, in each row, a vector in which S is // m is a matrix containing, in each row, a vector in which S is
// bounded, such that the linear span of all these dimensions contains all // bounded, such that the linear span of all these dimensions contains all
// bounded dimensions in S. // bounded dimensions in S.
Matrix<MPInt> m = getBoundedDirections(); Matrix m = getBoundedDirections();
// In column echelon form, each row of m occupies only the first rank(m) // In column echelon form, each row of m occupies only the first rank(m)
// columns and has zeros on the other columns. The transform T that brings S // columns and has zeros on the other columns. The transform T that brings S
// to column echelon form is unimodular as well, so this is a suitable // to column echelon form is unimodular as well, so this is a suitable

View File

@ -12,11 +12,11 @@
using namespace mlir; using namespace mlir;
using namespace presburger; using namespace presburger;
LinearTransform::LinearTransform(Matrix<MPInt> &&oMatrix) : matrix(oMatrix) {} LinearTransform::LinearTransform(Matrix &&oMatrix) : matrix(oMatrix) {}
LinearTransform::LinearTransform(const Matrix<MPInt> &oMatrix) : matrix(oMatrix) {} LinearTransform::LinearTransform(const Matrix &oMatrix) : matrix(oMatrix) {}
std::pair<unsigned, LinearTransform> std::pair<unsigned, LinearTransform>
LinearTransform::makeTransformToColumnEchelon(const Matrix<MPInt> &m) { LinearTransform::makeTransformToColumnEchelon(const Matrix &m) {
// Compute the hermite normal form of m. This, is by definition, is in column // Compute the hermite normal form of m. This, is by definition, is in column
// echelon form. // echelon form.
auto [h, u] = m.computeHermiteNormalForm(); auto [h, u] = m.computeHermiteNormalForm();

View File

@ -7,14 +7,13 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "mlir/Analysis/Presburger/Matrix.h" #include "mlir/Analysis/Presburger/Matrix.h"
#include "mlir/Analysis/Presburger/Fraction.h"
#include "mlir/Analysis/Presburger/Utils.h" #include "mlir/Analysis/Presburger/Utils.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
using namespace mlir; using namespace mlir;
using namespace presburger; using namespace presburger;
template <typename T> Matrix<T>::Matrix(unsigned rows, unsigned columns, unsigned reservedRows, Matrix::Matrix(unsigned rows, unsigned columns, unsigned reservedRows,
unsigned reservedColumns) unsigned reservedColumns)
: nRows(rows), nColumns(columns), : nRows(rows), nColumns(columns),
nReservedColumns(std::max(nColumns, reservedColumns)), nReservedColumns(std::max(nColumns, reservedColumns)),
@ -22,27 +21,27 @@ template <typename T> Matrix<T>::Matrix(unsigned rows, unsigned columns, unsigne
data.reserve(std::max(nRows, reservedRows) * nReservedColumns); data.reserve(std::max(nRows, reservedRows) * nReservedColumns);
} }
template <typename T> Matrix<T> Matrix<T>::identity(unsigned dimension) { Matrix Matrix::identity(unsigned dimension) {
Matrix matrix(dimension, dimension); Matrix matrix(dimension, dimension);
for (unsigned i = 0; i < dimension; ++i) for (unsigned i = 0; i < dimension; ++i)
matrix(i, i) = 1; matrix(i, i) = 1;
return matrix; return matrix;
} }
template <typename T> unsigned Matrix<T>::getNumReservedRows() const { unsigned Matrix::getNumReservedRows() const {
return data.capacity() / nReservedColumns; return data.capacity() / nReservedColumns;
} }
template <typename T> void Matrix<T>::reserveRows(unsigned rows) { void Matrix::reserveRows(unsigned rows) {
data.reserve(rows * nReservedColumns); data.reserve(rows * nReservedColumns);
} }
template <typename T> unsigned Matrix<T>::appendExtraRow() { unsigned Matrix::appendExtraRow() {
resizeVertically(nRows + 1); resizeVertically(nRows + 1);
return nRows - 1; return nRows - 1;
} }
template <typename T> unsigned Matrix<T>::appendExtraRow(ArrayRef<T> elems) { unsigned Matrix::appendExtraRow(ArrayRef<MPInt> elems) {
assert(elems.size() == nColumns && "elems must match row length!"); assert(elems.size() == nColumns && "elems must match row length!");
unsigned row = appendExtraRow(); unsigned row = appendExtraRow();
for (unsigned col = 0; col < nColumns; ++col) for (unsigned col = 0; col < nColumns; ++col)
@ -50,24 +49,24 @@ template <typename T> unsigned Matrix<T>::appendExtraRow(ArrayRef<T> elems) {
return row; return row;
} }
template <typename T> void Matrix<T>::resizeHorizontally(unsigned newNColumns) { void Matrix::resizeHorizontally(unsigned newNColumns) {
if (newNColumns < nColumns) if (newNColumns < nColumns)
removeColumns(newNColumns, nColumns - newNColumns); removeColumns(newNColumns, nColumns - newNColumns);
if (newNColumns > nColumns) if (newNColumns > nColumns)
insertColumns(nColumns, newNColumns - nColumns); insertColumns(nColumns, newNColumns - nColumns);
} }
template <typename T> void Matrix<T>::resize(unsigned newNRows, unsigned newNColumns) { void Matrix::resize(unsigned newNRows, unsigned newNColumns) {
resizeHorizontally(newNColumns); resizeHorizontally(newNColumns);
resizeVertically(newNRows); resizeVertically(newNRows);
} }
template <typename T> void Matrix<T>::resizeVertically(unsigned newNRows) { void Matrix::resizeVertically(unsigned newNRows) {
nRows = newNRows; nRows = newNRows;
data.resize(nRows * nReservedColumns); data.resize(nRows * nReservedColumns);
} }
template <typename T> void Matrix<T>::swapRows(unsigned row, unsigned otherRow) { void Matrix::swapRows(unsigned row, unsigned otherRow) {
assert((row < getNumRows() && otherRow < getNumRows()) && assert((row < getNumRows() && otherRow < getNumRows()) &&
"Given row out of bounds"); "Given row out of bounds");
if (row == otherRow) if (row == otherRow)
@ -76,7 +75,7 @@ template <typename T> void Matrix<T>::swapRows(unsigned row, unsigned otherRow)
std::swap(at(row, col), at(otherRow, col)); std::swap(at(row, col), at(otherRow, col));
} }
template <typename T> void Matrix<T>::swapColumns(unsigned column, unsigned otherColumn) { void Matrix::swapColumns(unsigned column, unsigned otherColumn) {
assert((column < getNumColumns() && otherColumn < getNumColumns()) && assert((column < getNumColumns() && otherColumn < getNumColumns()) &&
"Given column out of bounds"); "Given column out of bounds");
if (column == otherColumn) if (column == otherColumn)
@ -85,23 +84,23 @@ template <typename T> void Matrix<T>::swapColumns(unsigned column, unsigned othe
std::swap(at(row, column), at(row, otherColumn)); std::swap(at(row, column), at(row, otherColumn));
} }
template <typename T> MutableArrayRef<T> Matrix<T>::getRow(unsigned row) { MutableArrayRef<MPInt> Matrix::getRow(unsigned row) {
return {&data[row * nReservedColumns], nColumns}; return {&data[row * nReservedColumns], nColumns};
} }
template <typename T> ArrayRef<T> Matrix<T>::getRow(unsigned row) const { ArrayRef<MPInt> Matrix::getRow(unsigned row) const {
return {&data[row * nReservedColumns], nColumns}; return {&data[row * nReservedColumns], nColumns};
} }
template <typename T> void Matrix<T>::setRow(unsigned row, ArrayRef<T> elems) { void Matrix::setRow(unsigned row, ArrayRef<MPInt> elems) {
assert(elems.size() == getNumColumns() && assert(elems.size() == getNumColumns() &&
"elems size must match row length!"); "elems size must match row length!");
for (unsigned i = 0, e = getNumColumns(); i < e; ++i) for (unsigned i = 0, e = getNumColumns(); i < e; ++i)
at(row, i) = elems[i]; at(row, i) = elems[i];
} }
template <typename T> void Matrix<T>::insertColumn(unsigned pos) { insertColumns(pos, 1); } void Matrix::insertColumn(unsigned pos) { insertColumns(pos, 1); }
template <typename T> void Matrix<T>::insertColumns(unsigned pos, unsigned count) { void Matrix::insertColumns(unsigned pos, unsigned count) {
if (count == 0) if (count == 0)
return; return;
assert(pos <= nColumns); assert(pos <= nColumns);
@ -116,7 +115,7 @@ template <typename T> void Matrix<T>::insertColumns(unsigned pos, unsigned count
for (int ci = nReservedColumns - 1; ci >= 0; --ci) { for (int ci = nReservedColumns - 1; ci >= 0; --ci) {
unsigned r = ri; unsigned r = ri;
unsigned c = ci; unsigned c = ci;
T &dest = data[r * nReservedColumns + c]; MPInt &dest = data[r * nReservedColumns + c];
if (c >= nColumns) { // NOLINT if (c >= nColumns) { // NOLINT
// Out of bounds columns are zero-initialized. NOLINT because clang-tidy // Out of bounds columns are zero-initialized. NOLINT because clang-tidy
// complains about this branch being the same as the c >= pos one. // complains about this branch being the same as the c >= pos one.
@ -142,8 +141,8 @@ template <typename T> void Matrix<T>::insertColumns(unsigned pos, unsigned count
} }
} }
template <typename T> void Matrix<T>::removeColumn(unsigned pos) { removeColumns(pos, 1); } void Matrix::removeColumn(unsigned pos) { removeColumns(pos, 1); }
template <typename T> void Matrix<T>::removeColumns(unsigned pos, unsigned count) { void Matrix::removeColumns(unsigned pos, unsigned count) {
if (count == 0) if (count == 0)
return; return;
assert(pos + count - 1 < nColumns); assert(pos + count - 1 < nColumns);
@ -156,8 +155,8 @@ template <typename T> void Matrix<T>::removeColumns(unsigned pos, unsigned count
nColumns -= count; nColumns -= count;
} }
template <typename T> void Matrix<T>::insertRow(unsigned pos) { insertRows(pos, 1); } void Matrix::insertRow(unsigned pos) { insertRows(pos, 1); }
template <typename T> void Matrix<T>::insertRows(unsigned pos, unsigned count) { void Matrix::insertRows(unsigned pos, unsigned count) {
if (count == 0) if (count == 0)
return; return;
@ -170,8 +169,8 @@ template <typename T> void Matrix<T>::insertRows(unsigned pos, unsigned count) {
at(r, c) = 0; at(r, c) = 0;
} }
template <typename T> void Matrix<T>::removeRow(unsigned pos) { removeRows(pos, 1); } void Matrix::removeRow(unsigned pos) { removeRows(pos, 1); }
template <typename T> void Matrix<T>::removeRows(unsigned pos, unsigned count) { void Matrix::removeRows(unsigned pos, unsigned count) {
if (count == 0) if (count == 0)
return; return;
assert(pos + count - 1 <= nRows); assert(pos + count - 1 <= nRows);
@ -180,73 +179,73 @@ template <typename T> void Matrix<T>::removeRows(unsigned pos, unsigned count) {
resizeVertically(nRows - count); resizeVertically(nRows - count);
} }
template <typename T> void Matrix<T>::copyRow(unsigned sourceRow, unsigned targetRow) { void Matrix::copyRow(unsigned sourceRow, unsigned targetRow) {
if (sourceRow == targetRow) if (sourceRow == targetRow)
return; return;
for (unsigned c = 0; c < nColumns; ++c) for (unsigned c = 0; c < nColumns; ++c)
at(targetRow, c) = at(sourceRow, c); at(targetRow, c) = at(sourceRow, c);
} }
template <typename T> void Matrix<T>::fillRow(unsigned row, const T &value) { void Matrix::fillRow(unsigned row, const MPInt &value) {
for (unsigned col = 0; col < nColumns; ++col) for (unsigned col = 0; col < nColumns; ++col)
at(row, col) = value; at(row, col) = value;
} }
template <typename T> void Matrix<T>::addToRow(unsigned sourceRow, unsigned targetRow, void Matrix::addToRow(unsigned sourceRow, unsigned targetRow,
const T &scale) { const MPInt &scale) {
addToRow(targetRow, getRow(sourceRow), scale); addToRow(targetRow, getRow(sourceRow), scale);
} }
template <typename T> void Matrix<T>::addToRow(unsigned row, ArrayRef<T> rowVec, void Matrix::addToRow(unsigned row, ArrayRef<MPInt> rowVec,
const T &scale) { const MPInt &scale) {
if (scale == 0) if (scale == 0)
return; return;
for (unsigned col = 0; col < nColumns; ++col) for (unsigned col = 0; col < nColumns; ++col)
at(row, col) += scale * rowVec[col]; at(row, col) += scale * rowVec[col];
} }
template <typename T> void Matrix<T>::addToColumn(unsigned sourceColumn, unsigned targetColumn, void Matrix::addToColumn(unsigned sourceColumn, unsigned targetColumn,
const T &scale) { const MPInt &scale) {
if (scale == 0) if (scale == 0)
return; return;
for (unsigned row = 0, e = getNumRows(); row < e; ++row) for (unsigned row = 0, e = getNumRows(); row < e; ++row)
at(row, targetColumn) += scale * at(row, sourceColumn); at(row, targetColumn) += scale * at(row, sourceColumn);
} }
template <typename T> void Matrix<T>::negateColumn(unsigned column) { void Matrix::negateColumn(unsigned column) {
for (unsigned row = 0, e = getNumRows(); row < e; ++row) for (unsigned row = 0, e = getNumRows(); row < e; ++row)
at(row, column) = -at(row, column); at(row, column) = -at(row, column);
} }
template <typename T> void Matrix<T>::negateRow(unsigned row) { void Matrix::negateRow(unsigned row) {
for (unsigned column = 0, e = getNumColumns(); column < e; ++column) for (unsigned column = 0, e = getNumColumns(); column < e; ++column)
at(row, column) = -at(row, column); at(row, column) = -at(row, column);
} }
template <> MPInt Matrix<MPInt>::normalizeRow(unsigned row, unsigned cols) { MPInt Matrix::normalizeRow(unsigned row, unsigned cols) {
return normalizeRange(getRow(row).slice(0, cols)); return normalizeRange(getRow(row).slice(0, cols));
} }
template <> MPInt Matrix<MPInt>::normalizeRow(unsigned row) { MPInt Matrix::normalizeRow(unsigned row) {
return normalizeRow(row, getNumColumns()); return normalizeRow(row, getNumColumns());
} }
template <typename T> SmallVector<T, 8> Matrix<T>::preMultiplyWithRow(ArrayRef<T> rowVec) const { SmallVector<MPInt, 8> Matrix::preMultiplyWithRow(ArrayRef<MPInt> rowVec) const {
assert(rowVec.size() == getNumRows() && "Invalid row vector dimension!"); assert(rowVec.size() == getNumRows() && "Invalid row vector dimension!");
SmallVector<T, 8> result(getNumColumns(), T(0)); SmallVector<MPInt, 8> result(getNumColumns(), MPInt(0));
for (unsigned col = 0, e = getNumColumns(); col < e; ++col) for (unsigned col = 0, e = getNumColumns(); col < e; ++col)
for (unsigned i = 0, e = getNumRows(); i < e; ++i) for (unsigned i = 0, e = getNumRows(); i < e; ++i)
result[col] += rowVec[i] * at(i, col); result[col] += rowVec[i] * at(i, col);
return result; return result;
} }
template <typename T> SmallVector<T, 8> SmallVector<MPInt, 8>
Matrix<T>::postMultiplyWithColumn(ArrayRef<T> colVec) const { Matrix::postMultiplyWithColumn(ArrayRef<MPInt> colVec) const {
assert(getNumColumns() == colVec.size() && assert(getNumColumns() == colVec.size() &&
"Invalid column vector dimension!"); "Invalid column vector dimension!");
SmallVector<T, 8> result(getNumRows(), T(0)); SmallVector<MPInt, 8> result(getNumRows(), MPInt(0));
for (unsigned row = 0, e = getNumRows(); row < e; row++) for (unsigned row = 0, e = getNumRows(); row < e; row++)
for (unsigned i = 0, e = getNumColumns(); i < e; i++) for (unsigned i = 0, e = getNumColumns(); i < e; i++)
result[row] += at(row, i) * colVec[i]; result[row] += at(row, i) * colVec[i];
@ -258,8 +257,8 @@ Matrix<T>::postMultiplyWithColumn(ArrayRef<T> colVec) const {
/// sourceCol. This brings M(row, targetCol) to the range [0, M(row, /// sourceCol. This brings M(row, targetCol) to the range [0, M(row,
/// sourceCol)). Apply the same column operation to otherMatrix, with the same /// sourceCol)). Apply the same column operation to otherMatrix, with the same
/// integer multiple. /// integer multiple.
static void modEntryColumnOperation(Matrix<MPInt> &m, unsigned row, unsigned sourceCol, static void modEntryColumnOperation(Matrix &m, unsigned row, unsigned sourceCol,
unsigned targetCol, Matrix<MPInt> &otherMatrix) { unsigned targetCol, Matrix &otherMatrix) {
assert(m(row, sourceCol) != 0 && "Cannot divide by zero!"); assert(m(row, sourceCol) != 0 && "Cannot divide by zero!");
assert(m(row, sourceCol) > 0 && "Source must be positive!"); assert(m(row, sourceCol) > 0 && "Source must be positive!");
MPInt ratio = -floorDiv(m(row, targetCol), m(row, sourceCol)); MPInt ratio = -floorDiv(m(row, targetCol), m(row, sourceCol));
@ -267,12 +266,12 @@ static void modEntryColumnOperation(Matrix<MPInt> &m, unsigned row, unsigned sou
otherMatrix.addToColumn(sourceCol, targetCol, ratio); otherMatrix.addToColumn(sourceCol, targetCol, ratio);
} }
template <> std::pair<Matrix<MPInt>, Matrix<MPInt>> Matrix<MPInt>::computeHermiteNormalForm() const { std::pair<Matrix, Matrix> Matrix::computeHermiteNormalForm() const {
// We start with u as an identity matrix and perform operations on h until h // We start with u as an identity matrix and perform operations on h until h
// is in hermite normal form. We apply the same sequence of operations on u to // is in hermite normal form. We apply the same sequence of operations on u to
// obtain a transform that takes h to hermite normal form. // obtain a transform that takes h to hermite normal form.
Matrix<MPInt> h = *this; Matrix h = *this;
Matrix<MPInt> u = Matrix<MPInt>::identity(h.getNumColumns()); Matrix u = Matrix::identity(h.getNumColumns());
unsigned echelonCol = 0; unsigned echelonCol = 0;
// Invariant: in all rows above row, all columns from echelonCol onwards // Invariant: in all rows above row, all columns from echelonCol onwards
@ -353,7 +352,7 @@ template <> std::pair<Matrix<MPInt>, Matrix<MPInt>> Matrix<MPInt>::computeHermit
return {h, u}; return {h, u};
} }
template <typename T> void Matrix<T>::print(raw_ostream &os) const { void Matrix::print(raw_ostream &os) const {
for (unsigned row = 0; row < nRows; ++row) { for (unsigned row = 0; row < nRows; ++row) {
for (unsigned column = 0; column < nColumns; ++column) for (unsigned column = 0; column < nColumns; ++column)
os << at(row, column) << ' '; os << at(row, column) << ' ';
@ -361,9 +360,9 @@ template <typename T> void Matrix<T>::print(raw_ostream &os) const {
} }
} }
template <typename T> void Matrix<T>::dump() const { print(llvm::errs()); } void Matrix::dump() const { print(llvm::errs()); }
template <typename T> bool Matrix<T>::hasConsistentState() const { bool Matrix::hasConsistentState() const {
if (data.size() != nRows * nReservedColumns) if (data.size() != nRows * nReservedColumns)
return false; return false;
if (nColumns > nReservedColumns) if (nColumns > nReservedColumns)
@ -376,12 +375,3 @@ template <typename T> bool Matrix<T>::hasConsistentState() const {
#endif #endif
return true; return true;
} }
namespace mlir
{
namespace presburger
{
template class Matrix<MPInt>;
template class Matrix<Fraction>;
}
}

View File

@ -436,7 +436,7 @@ LogicalResult SymbolicLexSimplex::addSymbolicCut(unsigned row) {
} }
void SymbolicLexSimplex::recordOutput(SymbolicLexOpt &result) const { void SymbolicLexSimplex::recordOutput(SymbolicLexOpt &result) const {
Matrix<MPInt> output(0, domainPoly.getNumVars() + 1); Matrix output(0, domainPoly.getNumVars() + 1);
output.reserveRows(result.lexopt.getNumOutputs()); output.reserveRows(result.lexopt.getNumOutputs());
for (const Unknown &u : var) { for (const Unknown &u : var) {
if (u.isSymbol) if (u.isSymbol)
@ -1801,7 +1801,7 @@ private:
/// ///
/// When incrementing i, no cached f values get invalidated. However, the cached /// When incrementing i, no cached f values get invalidated. However, the cached
/// duals do get invalidated as the duals for the higher levels are different. /// duals do get invalidated as the duals for the higher levels are different.
void Simplex::reduceBasis(Matrix<MPInt> &basis, unsigned level) { void Simplex::reduceBasis(Matrix &basis, unsigned level) {
const Fraction epsilon(3, 4); const Fraction epsilon(3, 4);
if (level == basis.getNumRows() - 1) if (level == basis.getNumRows() - 1)
@ -1975,7 +1975,7 @@ std::optional<SmallVector<MPInt, 8>> Simplex::findIntegerSample() {
return {}; return {};
unsigned nDims = var.size(); unsigned nDims = var.size();
Matrix<MPInt> basis = Matrix<MPInt>::identity(nDims); Matrix basis = Matrix::identity(nDims);
unsigned level = 0; unsigned level = 0;
// The snapshot just before constraining a direction to a value at each level. // The snapshot just before constraining a direction to a value at each level.

View File

@ -13,7 +13,7 @@
using namespace mlir; using namespace mlir;
using namespace presburger; using namespace presburger;
void testColumnEchelonForm(const Matrix<MPInt> &m, unsigned expectedRank) { void testColumnEchelonForm(const Matrix &m, unsigned expectedRank) {
unsigned lastAllowedNonZeroCol = 0; unsigned lastAllowedNonZeroCol = 0;
std::pair<unsigned, LinearTransform> result = std::pair<unsigned, LinearTransform> result =
LinearTransform::makeTransformToColumnEchelon(m); LinearTransform::makeTransformToColumnEchelon(m);
@ -42,21 +42,21 @@ void testColumnEchelonForm(const Matrix<MPInt> &m, unsigned expectedRank) {
TEST(LinearTransformTest, transformToColumnEchelonTest) { TEST(LinearTransformTest, transformToColumnEchelonTest) {
// m1, m2, m3 are rank 1 matrices -- the first and second rows are identical. // m1, m2, m3 are rank 1 matrices -- the first and second rows are identical.
Matrix<MPInt> m1(2, 2); Matrix m1(2, 2);
m1(0, 0) = 4; m1(0, 0) = 4;
m1(0, 1) = -7; m1(0, 1) = -7;
m1(1, 0) = 4; m1(1, 0) = 4;
m1(1, 1) = -7; m1(1, 1) = -7;
testColumnEchelonForm(m1, 1u); testColumnEchelonForm(m1, 1u);
Matrix<MPInt> m2(2, 2); Matrix m2(2, 2);
m2(0, 0) = -4; m2(0, 0) = -4;
m2(0, 1) = 7; m2(0, 1) = 7;
m2(1, 0) = 4; m2(1, 0) = 4;
m2(1, 1) = -7; m2(1, 1) = -7;
testColumnEchelonForm(m2, 1u); testColumnEchelonForm(m2, 1u);
Matrix<MPInt> m3(2, 2); Matrix m3(2, 2);
m3(0, 0) = -4; m3(0, 0) = -4;
m3(0, 1) = -7; m3(0, 1) = -7;
m3(1, 0) = -4; m3(1, 0) = -4;
@ -64,21 +64,21 @@ TEST(LinearTransformTest, transformToColumnEchelonTest) {
testColumnEchelonForm(m3, 1u); testColumnEchelonForm(m3, 1u);
// m4, m5, m6 are rank 2 matrices -- the first and second rows are different. // m4, m5, m6 are rank 2 matrices -- the first and second rows are different.
Matrix<MPInt> m4(2, 2); Matrix m4(2, 2);
m4(0, 0) = 4; m4(0, 0) = 4;
m4(0, 1) = -7; m4(0, 1) = -7;
m4(1, 0) = -4; m4(1, 0) = -4;
m4(1, 1) = -7; m4(1, 1) = -7;
testColumnEchelonForm(m4, 2u); testColumnEchelonForm(m4, 2u);
Matrix<MPInt> m5(2, 2); Matrix m5(2, 2);
m5(0, 0) = -4; m5(0, 0) = -4;
m5(0, 1) = 7; m5(0, 1) = 7;
m5(1, 0) = 4; m5(1, 0) = 4;
m5(1, 1) = 7; m5(1, 1) = 7;
testColumnEchelonForm(m5, 2u); testColumnEchelonForm(m5, 2u);
Matrix<MPInt> m6(2, 2); Matrix m6(2, 2);
m6(0, 0) = -4; m6(0, 0) = -4;
m6(0, 1) = -7; m6(0, 1) = -7;
m6(1, 0) = 4; m6(1, 0) = 4;

View File

@ -7,7 +7,6 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "mlir/Analysis/Presburger/Matrix.h" #include "mlir/Analysis/Presburger/Matrix.h"
#include "mlir/Analysis/Presburger/Fraction.h"
#include "./Utils.h" #include "./Utils.h"
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -16,7 +15,7 @@ using namespace mlir;
using namespace presburger; using namespace presburger;
TEST(MatrixTest, ReadWrite) { TEST(MatrixTest, ReadWrite) {
Matrix<MPInt> mat(5, 5); Matrix mat(5, 5);
for (unsigned row = 0; row < 5; ++row) for (unsigned row = 0; row < 5; ++row)
for (unsigned col = 0; col < 5; ++col) for (unsigned col = 0; col < 5; ++col)
mat(row, col) = 10 * row + col; mat(row, col) = 10 * row + col;
@ -26,7 +25,7 @@ TEST(MatrixTest, ReadWrite) {
} }
TEST(MatrixTest, SwapColumns) { TEST(MatrixTest, SwapColumns) {
Matrix<MPInt> mat(5, 5); Matrix mat(5, 5);
for (unsigned row = 0; row < 5; ++row) for (unsigned row = 0; row < 5; ++row)
for (unsigned col = 0; col < 5; ++col) for (unsigned col = 0; col < 5; ++col)
mat(row, col) = col == 3 ? 1 : 0; mat(row, col) = col == 3 ? 1 : 0;
@ -48,7 +47,7 @@ TEST(MatrixTest, SwapColumns) {
} }
TEST(MatrixTest, SwapRows) { TEST(MatrixTest, SwapRows) {
Matrix<MPInt> mat(5, 5); Matrix mat(5, 5);
for (unsigned row = 0; row < 5; ++row) for (unsigned row = 0; row < 5; ++row)
for (unsigned col = 0; col < 5; ++col) for (unsigned col = 0; col < 5; ++col)
mat(row, col) = row == 2 ? 1 : 0; mat(row, col) = row == 2 ? 1 : 0;
@ -70,7 +69,7 @@ TEST(MatrixTest, SwapRows) {
} }
TEST(MatrixTest, resizeVertically) { TEST(MatrixTest, resizeVertically) {
Matrix<MPInt> mat(5, 5); Matrix mat(5, 5);
EXPECT_EQ(mat.getNumRows(), 5u); EXPECT_EQ(mat.getNumRows(), 5u);
EXPECT_EQ(mat.getNumColumns(), 5u); EXPECT_EQ(mat.getNumColumns(), 5u);
for (unsigned row = 0; row < 5; ++row) for (unsigned row = 0; row < 5; ++row)
@ -95,7 +94,7 @@ TEST(MatrixTest, resizeVertically) {
} }
TEST(MatrixTest, insertColumns) { TEST(MatrixTest, insertColumns) {
Matrix<MPInt> mat(5, 5, 5, 10); Matrix mat(5, 5, 5, 10);
EXPECT_EQ(mat.getNumRows(), 5u); EXPECT_EQ(mat.getNumRows(), 5u);
EXPECT_EQ(mat.getNumColumns(), 5u); EXPECT_EQ(mat.getNumColumns(), 5u);
for (unsigned row = 0; row < 5; ++row) for (unsigned row = 0; row < 5; ++row)
@ -132,7 +131,7 @@ TEST(MatrixTest, insertColumns) {
} }
TEST(MatrixTest, insertRows) { TEST(MatrixTest, insertRows) {
Matrix<MPInt> mat(5, 5, 5, 10); Matrix mat(5, 5, 5, 10);
ASSERT_TRUE(mat.hasConsistentState()); ASSERT_TRUE(mat.hasConsistentState());
EXPECT_EQ(mat.getNumRows(), 5u); EXPECT_EQ(mat.getNumRows(), 5u);
EXPECT_EQ(mat.getNumColumns(), 5u); EXPECT_EQ(mat.getNumColumns(), 5u);
@ -170,7 +169,7 @@ TEST(MatrixTest, insertRows) {
} }
TEST(MatrixTest, resize) { TEST(MatrixTest, resize) {
Matrix<MPInt> mat(5, 5); Matrix mat(5, 5);
EXPECT_EQ(mat.getNumRows(), 5u); EXPECT_EQ(mat.getNumRows(), 5u);
EXPECT_EQ(mat.getNumColumns(), 5u); EXPECT_EQ(mat.getNumColumns(), 5u);
for (unsigned row = 0; row < 5; ++row) for (unsigned row = 0; row < 5; ++row)
@ -194,8 +193,8 @@ TEST(MatrixTest, resize) {
EXPECT_EQ(mat(row, col), row >= 3 || col >= 3 ? 0 : int(10 * row + col)); EXPECT_EQ(mat(row, col), row >= 3 || col >= 3 ? 0 : int(10 * row + col));
} }
static void checkHermiteNormalForm(const Matrix<MPInt> &mat, static void checkHermiteNormalForm(const Matrix &mat,
const Matrix<MPInt> &hermiteForm) { const Matrix &hermiteForm) {
auto [h, u] = mat.computeHermiteNormalForm(); auto [h, u] = mat.computeHermiteNormalForm();
for (unsigned row = 0; row < mat.getNumRows(); row++) for (unsigned row = 0; row < mat.getNumRows(); row++)
@ -209,42 +208,42 @@ TEST(MatrixTest, computeHermiteNormalForm) {
{ {
// Hermite form of a unimodular matrix is the identity matrix. // Hermite form of a unimodular matrix is the identity matrix.
Matrix<MPInt> mat = makeIntMatrix(3, 3, {{2, 3, 6}, {3, 2, 3}, {17, 11, 16}}); Matrix mat = makeMatrix(3, 3, {{2, 3, 6}, {3, 2, 3}, {17, 11, 16}});
Matrix<MPInt> hermiteForm = makeIntMatrix(3, 3, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}); Matrix hermiteForm = makeMatrix(3, 3, {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}});
checkHermiteNormalForm(mat, hermiteForm); checkHermiteNormalForm(mat, hermiteForm);
} }
{ {
// Hermite form of a unimodular is the identity matrix. // Hermite form of a unimodular is the identity matrix.
Matrix<MPInt> mat = makeIntMatrix( Matrix mat = makeMatrix(
4, 4, 4, 4,
{{-6, -1, -19, -20}, {0, 1, 0, 0}, {-5, 0, -15, -16}, {6, 0, 18, 19}}); {{-6, -1, -19, -20}, {0, 1, 0, 0}, {-5, 0, -15, -16}, {6, 0, 18, 19}});
Matrix<MPInt> hermiteForm = makeIntMatrix( Matrix hermiteForm = makeMatrix(
4, 4, {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}); 4, 4, {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}});
checkHermiteNormalForm(mat, hermiteForm); checkHermiteNormalForm(mat, hermiteForm);
} }
{ {
Matrix<MPInt> mat = makeIntMatrix( Matrix mat = makeMatrix(
4, 4, {{3, 3, 1, 4}, {0, 1, 0, 0}, {0, 0, 19, 16}, {0, 0, 0, 3}}); 4, 4, {{3, 3, 1, 4}, {0, 1, 0, 0}, {0, 0, 19, 16}, {0, 0, 0, 3}});
Matrix<MPInt> hermiteForm = makeIntMatrix( Matrix hermiteForm = makeMatrix(
4, 4, {{1, 0, 0, 0}, {0, 1, 0, 0}, {1, 0, 3, 0}, {18, 0, 54, 57}}); 4, 4, {{1, 0, 0, 0}, {0, 1, 0, 0}, {1, 0, 3, 0}, {18, 0, 54, 57}});
checkHermiteNormalForm(mat, hermiteForm); checkHermiteNormalForm(mat, hermiteForm);
} }
{ {
Matrix<MPInt> mat = makeIntMatrix( Matrix mat = makeMatrix(
4, 4, {{3, 3, 1, 4}, {0, 1, 0, 0}, {0, 0, 19, 16}, {0, 0, 0, 3}}); 4, 4, {{3, 3, 1, 4}, {0, 1, 0, 0}, {0, 0, 19, 16}, {0, 0, 0, 3}});
Matrix<MPInt> hermiteForm = makeIntMatrix( Matrix hermiteForm = makeMatrix(
4, 4, {{1, 0, 0, 0}, {0, 1, 0, 0}, {1, 0, 3, 0}, {18, 0, 54, 57}}); 4, 4, {{1, 0, 0, 0}, {0, 1, 0, 0}, {1, 0, 3, 0}, {18, 0, 54, 57}});
checkHermiteNormalForm(mat, hermiteForm); checkHermiteNormalForm(mat, hermiteForm);
} }
{ {
Matrix<MPInt> mat = Matrix mat =
makeIntMatrix(3, 5, {{0, 2, 0, 7, 1}, {-1, 0, 0, -3, 0}, {0, 4, 1, 0, 8}}); makeMatrix(3, 5, {{0, 2, 0, 7, 1}, {-1, 0, 0, -3, 0}, {0, 4, 1, 0, 8}});
Matrix<MPInt> hermiteForm = Matrix hermiteForm =
makeIntMatrix(3, 5, {{1, 0, 0, 0, 0}, {0, 1, 0, 0, 0}, {0, 0, 1, 0, 0}}); makeMatrix(3, 5, {{1, 0, 0, 0, 0}, {0, 1, 0, 0, 0}, {0, 0, 1, 0, 0}});
checkHermiteNormalForm(mat, hermiteForm); checkHermiteNormalForm(mat, hermiteForm);
} }
} }

View File

@ -52,7 +52,7 @@ inline MultiAffineFunction parseMultiAffineFunction(StringRef str) {
// TODO: Add default constructor for MultiAffineFunction. // TODO: Add default constructor for MultiAffineFunction.
MultiAffineFunction multiAff(PresburgerSpace::getRelationSpace(), MultiAffineFunction multiAff(PresburgerSpace::getRelationSpace(),
Matrix<MPInt>(0, 1)); Matrix(0, 1));
if (getMultiAffineFunctionFromMap(parseAffineMap(str, &context), multiAff) if (getMultiAffineFunctionFromMap(parseAffineMap(str, &context), multiAff)
.failed()) .failed())
llvm_unreachable( llvm_unreachable(

View File

@ -17,7 +17,6 @@
#include "mlir/Analysis/Presburger/PWMAFunction.h" #include "mlir/Analysis/Presburger/PWMAFunction.h"
#include "mlir/Analysis/Presburger/PresburgerRelation.h" #include "mlir/Analysis/Presburger/PresburgerRelation.h"
#include "mlir/Analysis/Presburger/Simplex.h" #include "mlir/Analysis/Presburger/Simplex.h"
#include "mlir/Analysis/Presburger/Matrix.h"
#include "mlir/IR/MLIRContext.h" #include "mlir/IR/MLIRContext.h"
#include "mlir/Support/LLVM.h" #include "mlir/Support/LLVM.h"
@ -27,22 +26,9 @@
namespace mlir { namespace mlir {
namespace presburger { namespace presburger {
inline Matrix<MPInt> makeIntMatrix(unsigned numRow, unsigned numColumns, inline Matrix makeMatrix(unsigned numRow, unsigned numColumns,
ArrayRef<SmallVector<int, 8>> matrix) { ArrayRef<SmallVector<int64_t, 8>> matrix) {
Matrix<MPInt> results(numRow, numColumns); Matrix results(numRow, numColumns);
assert(matrix.size() == numRow);
for (unsigned i = 0; i < numRow; ++i) {
assert(matrix[i].size() == numColumns &&
"Output expression has incorrect dimensionality!");
for (unsigned j = 0; j < numColumns; ++j)
results(i, j) = MPInt(matrix[i][j]);
}
return results;
}
inline Matrix<Fraction> makeFracMatrix(unsigned numRow, unsigned numColumns,
ArrayRef<SmallVector<Fraction, 8>> matrix) {
Matrix<Fraction> results(numRow, numColumns);
assert(matrix.size() == numRow); assert(matrix.size() == numRow);
for (unsigned i = 0; i < numRow; ++i) { for (unsigned i = 0; i < numRow; ++i) {
assert(matrix[i].size() == numColumns && assert(matrix[i].size() == numColumns &&