[Mlir-commits] [mlir] 2740273 - [MLIR][Presburger] Make printing aligned to assist in debugging (#107648)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Sep 11 20:22:58 PDT 2024


Author: Amy Wang
Date: 2024-09-11T23:22:54-04:00
New Revision: 2740273505ab27c0d8531d35948f0647309842cd

URL: https://github.com/llvm/llvm-project/commit/2740273505ab27c0d8531d35948f0647309842cd
DIFF: https://github.com/llvm/llvm-project/commit/2740273505ab27c0d8531d35948f0647309842cd.diff

LOG: [MLIR][Presburger] Make printing aligned to assist in debugging (#107648)

Hello Arjun! Please allow me to contribute this patch as it helps me
debugging significantly! When the 1's and 0's don't line up when
debugging farkas lemma of numerous polyhedrons using simplex lexmin
solver, it is truly straining on the eyes. Hopefully this patch can help
others!

The unfortunate part is the lack of testcase as I'm not sure how to add
testcase for debug dumps. :) However, you can add this testcase to the
SimplexTest.cpp to witness the nice printing!

```c++
TEST(SimplexTest, DumpTest) {
  int COLUMNS = 2;
  int ROWS = 2;
  LexSimplex simplex(COLUMNS * 2);
  IntMatrix m1(ROWS, COLUMNS * 2 + 1);
  // Adding LHS columns.
  for (int i = 0; i < ROWS; i++) {
    // an arbitrary formula to test all kinds of integers
    for (int j = 0; j < COLUMNS; j++) 
      m1(i, j) = i + (2 << (i % 3)) * (-1 * ((i + j) % 2));
  }
  // Adding RHS columns.
  for (int i = 0; i < ROWS; i++) {
    for (int j = 0; j < COLUMNS; j++)
      m1(i, j + COLUMNS) = j - (3 << (j % 4)) * (-1 * ((i + j * 2) % 2));
  }
  for (int i = 0; i < m1.getNumRows(); i++) {
    ArrayRef<DynamicAPInt> curRow = m1.getRow(i);
    simplex.addInequality(curRow);
  }
  IntegerRelation rel =
      parseRelationFromSet("(x, y, z)[] : (z - x - 17 * y == 0, x - 11 * z >= 1)",2);
  simplex.dump();
  m1.dump();
  rel.dump();
}
```

```
rows = 2, columns = 7
var: c3, c4, c5, c6
con: r0 [>=0], r1 [>=0]
r0: -1, r1: -2
c0: denom, c1: const, c2: 2147483647, c3: 0, c4: 1, c5: 2, c6: 3
  1  0  1  0 -2  0  1
  1  0 -8 -3  1  3  7

  0 -2  0  1  0
 -3  1  3  7  0
Domain: 2, Range: 1, Symbols: 0, Locals: 0
2 constraints
 -1  -17  1   0   = 0
  1   0  -11 -1  >= 0

```

Added: 
    

Modified: 
    mlir/include/mlir/Analysis/Presburger/Utils.h
    mlir/lib/Analysis/Presburger/IntegerRelation.cpp
    mlir/lib/Analysis/Presburger/Matrix.cpp
    mlir/lib/Analysis/Presburger/Simplex.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Analysis/Presburger/Utils.h b/mlir/include/mlir/Analysis/Presburger/Utils.h
index d3c0802c240bc1..69a5ce4e70178f 100644
--- a/mlir/include/mlir/Analysis/Presburger/Utils.h
+++ b/mlir/include/mlir/Analysis/Presburger/Utils.h
@@ -17,7 +17,9 @@
 #include "llvm/ADT/DynamicAPInt.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallBitVector.h"
+#include "llvm/Support/raw_ostream.h"
 #include <optional>
+#include <string>
 
 namespace mlir {
 namespace presburger {
@@ -292,6 +294,54 @@ std::vector<Fraction> multiplyPolynomials(ArrayRef<Fraction> a,
 
 bool isRangeZero(ArrayRef<Fraction> arr);
 
+/// Example usage:
+/// Print .12, 3.4, 56.7
+/// preAlign = ".", minSpacing = 1,
+///    .12   .12
+///   3.4   3.4
+///  56.7  56.7
+struct PrintTableMetrics {
+  // If unknown, set to 0 and pass the struct into updatePrintMetrics.
+  unsigned maxPreIndent;
+  unsigned maxPostIndent;
+  std::string preAlign;
+};
+
+/// Iterate over each val in the table and update 'm' where
+/// .maxPreIndent and .maxPostIndent are initialized to 0.
+/// class T is any type that can be handled by llvm::raw_string_ostream.
+template <class T>
+void updatePrintMetrics(T val, PrintTableMetrics &m) {
+  std::string str;
+  llvm::raw_string_ostream(str) << val;
+  if (str.empty())
+    return;
+  unsigned preIndent = str.find(m.preAlign);
+  preIndent = (preIndent != std::string::npos) ? preIndent + 1 : 0;
+  m.maxPreIndent = std::max(m.maxPreIndent, preIndent);
+  m.maxPostIndent =
+      std::max(m.maxPostIndent, (unsigned int)(str.length() - preIndent));
+}
+
+/// Print val in the table with metrics specified in 'm'.
+template <class T>
+void printWithPrintMetrics(raw_ostream &os, T val, unsigned minSpacing,
+                           const PrintTableMetrics &m) {
+  std::string str;
+  llvm::raw_string_ostream(str) << val;
+  unsigned preIndent;
+  if (!str.empty()) {
+    preIndent = str.find(m.preAlign);
+    preIndent = (preIndent != std::string::npos) ? preIndent + 1 : 0;
+  } else {
+    preIndent = 0;
+  }
+  for (unsigned i = 0; i < (minSpacing + m.maxPreIndent - preIndent); ++i)
+    os << " ";
+  os << str;
+  for (unsigned i = 0; i < m.maxPostIndent - (str.length() - preIndent); ++i)
+    os << " ";
+}
 } // namespace presburger
 } // namespace mlir
 

diff  --git a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
index 94af81f955e5a5..74cdf567c0e569 100644
--- a/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
+++ b/mlir/lib/Analysis/Presburger/IntegerRelation.cpp
@@ -32,7 +32,10 @@
 #include <cassert>
 #include <functional>
 #include <memory>
+#include <numeric>
 #include <optional>
+#include <sstream>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -2589,19 +2592,26 @@ void IntegerRelation::mergeAndCompose(const IntegerRelation &other) {
 void IntegerRelation::print(raw_ostream &os) const {
   assert(hasConsistentState());
   printSpace(os);
+  PrintTableMetrics ptm = {0, 0, "-"};
+  for (unsigned i = 0, e = getNumEqualities(); i < e; ++i)
+    for (unsigned j = 0, f = getNumCols(); j < f; ++j)
+      updatePrintMetrics<DynamicAPInt>(atEq(i, j), ptm);
+  for (unsigned i = 0, e = getNumInequalities(); i < e; ++i)
+    for (unsigned j = 0, f = getNumCols(); j < f; ++j)
+      updatePrintMetrics<DynamicAPInt>(atIneq(i, j), ptm);
+  // Print using PrintMetrics.
+  unsigned MIN_SPACING = 1;
   for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
-    os << " ";
     for (unsigned j = 0, f = getNumCols(); j < f; ++j) {
-      os << atEq(i, j) << "\t";
+      printWithPrintMetrics<DynamicAPInt>(os, atEq(i, j), MIN_SPACING, ptm);
     }
-    os << "= 0\n";
+    os << "  = 0\n";
   }
   for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
-    os << " ";
     for (unsigned j = 0, f = getNumCols(); j < f; ++j) {
-      os << atIneq(i, j) << "\t";
+      printWithPrintMetrics<DynamicAPInt>(os, atIneq(i, j), MIN_SPACING, ptm);
     }
-    os << ">= 0\n";
+    os << " >= 0\n";
   }
   os << '\n';
 }

diff  --git a/mlir/lib/Analysis/Presburger/Matrix.cpp b/mlir/lib/Analysis/Presburger/Matrix.cpp
index 110c5df1af37c0..9fc6205eb5ed52 100644
--- a/mlir/lib/Analysis/Presburger/Matrix.cpp
+++ b/mlir/lib/Analysis/Presburger/Matrix.cpp
@@ -398,10 +398,16 @@ Matrix<T> Matrix<T>::getSubMatrix(unsigned fromRow, unsigned toRow,
 
 template <typename T>
 void Matrix<T>::print(raw_ostream &os) const {
-  for (unsigned row = 0; row < nRows; ++row) {
+  PrintTableMetrics ptm = {0, 0, "-"};
+  for (unsigned row = 0; row < nRows; ++row)
     for (unsigned column = 0; column < nColumns; ++column)
-      os << at(row, column) << ' ';
-    os << '\n';
+      updatePrintMetrics<T>(at(row, column), ptm);
+  unsigned MIN_SPACING = 1;
+  for (unsigned row = 0; row < nRows; ++row) {
+    for (unsigned column = 0; column < nColumns; ++column) {
+      printWithPrintMetrics<T>(os, at(row, column), MIN_SPACING, ptm);
+    }
+    os << "\n";
   }
 }
 

diff  --git a/mlir/lib/Analysis/Presburger/Simplex.cpp b/mlir/lib/Analysis/Presburger/Simplex.cpp
index c78a0723a6c0fa..4ffa2d546af4dd 100644
--- a/mlir/lib/Analysis/Presburger/Simplex.cpp
+++ b/mlir/lib/Analysis/Presburger/Simplex.cpp
@@ -2153,9 +2153,16 @@ void SimplexBase::print(raw_ostream &os) const {
   for (unsigned col = 2, e = getNumColumns(); col < e; ++col)
     os << ", c" << col << ": " << colUnknown[col];
   os << '\n';
-  for (unsigned row = 0, numRows = getNumRows(); row < numRows; ++row) {
+  PrintTableMetrics ptm = {0, 0, "-"};
+  for (unsigned row = 0, numRows = getNumRows(); row < numRows; ++row)
     for (unsigned col = 0, numCols = getNumColumns(); col < numCols; ++col)
-      os << tableau(row, col) << '\t';
+      updatePrintMetrics<DynamicAPInt>(tableau(row, col), ptm);
+  unsigned MIN_SPACING = 1;
+  for (unsigned row = 0, numRows = getNumRows(); row < numRows; ++row) {
+    for (unsigned col = 0, numCols = getNumColumns(); col < numCols; ++col) {
+      printWithPrintMetrics<DynamicAPInt>(os, tableau(row, col), MIN_SPACING,
+                                          ptm);
+    }
     os << '\n';
   }
   os << '\n';


        


More information about the Mlir-commits mailing list