Skip to content

Commit 4162760

Browse files
committed
[MLIR][Presburger] Fix Gaussian elimination
1 parent 48a99ad commit 4162760

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

mlir/lib/Analysis/Presburger/Barvinok.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,13 @@ mlir::presburger::detail::solveParametricEquations(FracMatrix equations) {
178178
for (unsigned i = 0; i < d; ++i) {
179179
// First ensure that the diagonal element is nonzero, by swapping
180180
// it with a row that is non-zero at column i.
181-
if (equations(i, i) != 0)
182-
continue;
183-
for (unsigned j = i + 1; j < d; ++j) {
184-
if (equations(j, i) == 0)
185-
continue;
186-
equations.swapRows(j, i);
187-
break;
181+
if (equations(i, i) == 0) {
182+
for (unsigned j = i + 1; j < d; ++j) {
183+
if (equations(j, i) == 0)
184+
continue;
185+
equations.swapRows(j, i);
186+
break;
187+
}
188188
}
189189

190190
Fraction diagElement = equations(i, i);

mlir/lib/Analysis/Presburger/IntegerRelation.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,15 +1111,28 @@ unsigned IntegerRelation::gaussianEliminateVars(unsigned posStart,
11111111
return posLimit - posStart;
11121112
}
11131113

1114+
static std::optional<unsigned>
1115+
findEqualityWithNonZeroAfterRow(IntegerRelation &rel, unsigned fromRow,
1116+
unsigned colIdx) {
1117+
assert(fromRow < rel.getNumVars() && colIdx < rel.getNumCols() &&
1118+
"position out of bounds");
1119+
for (unsigned rowIdx = fromRow; rowIdx < rel.getNumEqualities(); ++rowIdx) {
1120+
if (rel.atEq(rowIdx, colIdx) != 0)
1121+
return rowIdx;
1122+
}
1123+
return std::nullopt;
1124+
}
1125+
11141126
bool IntegerRelation::gaussianEliminate() {
11151127
gcdTightenInequalities();
11161128
unsigned firstVar = 0, vars = getNumVars();
11171129
unsigned nowDone, eqs;
11181130
std::optional<unsigned> pivotRow;
11191131
for (nowDone = 0, eqs = getNumEqualities(); nowDone < eqs; ++nowDone) {
1120-
// Finds the first non-empty column.
1132+
// Finds the first non-empty column that we haven't dealt with.
11211133
for (; firstVar < vars; ++firstVar) {
1122-
if ((pivotRow = findConstraintWithNonZeroAt(firstVar, /*isEq=*/true)))
1134+
if ((pivotRow =
1135+
findEqualityWithNonZeroAfterRow(*this, nowDone, firstVar)))
11231136
break;
11241137
}
11251138
// The matrix has been normalized to row echelon form.
@@ -1142,6 +1155,10 @@ bool IntegerRelation::gaussianEliminate() {
11421155
inequalities.normalizeRow(i);
11431156
}
11441157
gcdTightenInequalities();
1158+
1159+
// The column is finished. Tell the next iteration to start at the next
1160+
// column.
1161+
firstVar++;
11451162
}
11461163

11471164
// No redundant rows.

mlir/unittests/Analysis/Presburger/IntegerRelationTest.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -725,3 +725,18 @@ TEST(IntegerRelationTest, addLocalModulo) {
725725
EXPECT_TRUE(rel.containsPointNoLocal({x, x % 32}));
726726
}
727727
}
728+
729+
TEST(IntegerRelationTest, simplify) {
730+
IntegerRelation rel =
731+
parseRelationFromSet("(x, y)[N]: (2*x + y - 4*N - 3 == 0, 3*x - y - 3*N"
732+
"+ 2 == 0, x + 3*y - 5*N - 8 == 0, x - y + N >= 0)",
733+
2);
734+
IntegerRelation simplified = parseRelationFromSet(
735+
"(x, y)[N]: (2*x + y - 4*N - 3 == 0, -5*y + 6*N + 13 == 0, N - 2 >= 0)",
736+
2);
737+
rel.simplify();
738+
739+
EXPECT_TRUE(rel.isEqual(simplified));
740+
// The third equality is redundant and should be removed.
741+
EXPECT_TRUE(rel.getNumEqualities() == 2);
742+
}

0 commit comments

Comments
 (0)