[Mlir-commits] [mlir] [MLIR][Presburger] Add support for Smith normal form (PR #185328)

Arjun Pitchanathan llvmlistbot at llvm.org
Tue Mar 10 09:05:37 PDT 2026


================
@@ -258,6 +258,56 @@ TEST(MatrixTest, computeHermiteNormalForm) {
   }
 }
 
+static IntMatrix matmul(const IntMatrix &a, const IntMatrix &b) {
+  assert(a.getNumColumns() == b.getNumRows());
+  unsigned n = a.getNumRows();
+  unsigned m = b.getNumRows();
+  unsigned p = b.getNumColumns();
+  IntMatrix result(n, p);
+
+  for (unsigned i = 0; i < n; i++) {
+    for (unsigned j = 0; j < m; j++) {
+      for (unsigned k = 0; k < p; k++) {
+        result(i, k) += a(i, j) * b(j, k);
+      }
+    }
+  }
+  return result;
+}
+
+TEST(MatrixTest, computeSmithNormalForm) {
+  IntMatrix mat =
+      makeIntMatrix(4, 3, {{2, 5, 8}, {3, 6, 9}, {4, 7, 1}, {5, 8, 2}});
+
+  auto [u, d, v] = mat.computeSmithNormalForm();
+
+  // Check u and v are unimodular.
+  EXPECT_TRUE(llvm::abs(u.determinant()) == 1);
+  EXPECT_TRUE(llvm::abs(v.determinant()) == 1);
+
+  // Check u @ mat @ v = d (@ is matrix multiplication).
+  EXPECT_TRUE(matmul(u, matmul(mat, v)) == d);
+
+  // Check d is diagonal.
+  for (unsigned i = 0, e = d.getNumRows(); i < e; i++) {
+    for (unsigned j = 0, f = d.getNumColumns(); j < f; j++) {
+      if (i == j)
+        EXPECT_TRUE(d(i, j) != 0);
+      else
+        EXPECT_TRUE(d(i, j) == 0);
+    }
----------------
superty wrote:

you can use EXPECT_EQ, EXPECT_NE

https://github.com/llvm/llvm-project/pull/185328


More information about the Mlir-commits mailing list