[Mlir-commits] [mlir] [MLIR][Presburger] Implement vertex enumeration and chamber decomposition for polytope generating function computation. (PR #78987)
Arjun P
llvmlistbot at llvm.org
Thu Jan 25 15:49:17 PST 2024
================
@@ -233,4 +234,86 @@ TEST(BarvinokTest, computeNumTerms) {
for (unsigned j = 0; j < 2; j++)
for (unsigned k = 0; k < 2; k++)
EXPECT_EQ(count[i][j][k], 1);
-}
\ No newline at end of file
+}
+
+/// We define some simple polyhedra with unimodular tangent cones and verify
+/// that the returned generating functions correspond to those calculated by
+/// hand.
+TEST(BarvinokTest, computeNumTermsPolytope) {
+ // A cube of side 1.
+ IntMatrix ineqs = makeIntMatrix(6, 4,
+ {{1, 0, 0, 0},
+ {0, 1, 0, 0},
+ {0, 0, 1, 0},
+ {-1, 0, 0, 1},
+ {0, -1, 0, 1},
+ {0, 0, -1, 1}});
+ PolyhedronH poly = defineHRep(3);
+ for (unsigned i = 0; i < 6; i++)
+ poly.addInequality(ineqs.getRow(i));
+
+ std::vector<std::pair<PresburgerSet, GeneratingFunction>> count =
+ computePolytopeGeneratingFunction(poly);
+ // There is only one chamber, as it is non-parametric.
+ EXPECT_EQ(count.size(), 1u);
+
+ GeneratingFunction gf = count[0].second;
+ EXPECT_EQ_REPR_GENERATINGFUNCTION(
+ gf,
+ GeneratingFunction(
+ 0, {1, 1, 1, 1, 1, 1, 1, 1},
+ {makeFracMatrix(1, 3, {{1, 1, 1}}), makeFracMatrix(1, 3, {{0, 1, 1}}),
+ makeFracMatrix(1, 3, {{0, 1, 1}}), makeFracMatrix(1, 3, {{0, 0, 1}}),
+ makeFracMatrix(1, 3, {{0, 1, 1}}), makeFracMatrix(1, 3, {{0, 0, 1}}),
+ makeFracMatrix(1, 3, {{0, 0, 1}}),
+ makeFracMatrix(1, 3, {{0, 0, 0}})},
+ {{{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}},
+ {{1, 0, 0}, {0, -1, 0}, {0, 0, -1}},
+ {{0, 1, 0}, {-1, 0, 0}, {0, 0, -1}},
+ {{1, 0, 0}, {0, 1, 0}, {0, 0, -1}},
+ {{0, 0, 1}, {-1, 0, 0}, {0, -1, 0}},
+ {{1, 0, 0}, {0, 0, 1}, {0, -1, 0}},
+ {{0, 1, 0}, {0, 0, 1}, {-1, 0, 0}},
+ {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}}));
+
+ // A right-angled triangle with side p.
+ ineqs = makeIntMatrix(3, 4, {{1, 0, 0, 0}, {0, 1, 0, 0}, {-1, -1, 1, 0}});
+ poly = defineHRep(2, 1);
+ for (unsigned i = 0; i < 3; i++)
+ poly.addInequality(ineqs.getRow(i));
+
+ count = computePolytopeGeneratingFunction(poly);
+ // There is only one chamber: p ≥ 0
+ EXPECT_EQ(count.size(), 2u);
+
+ gf = count[0].second;
+ EXPECT_EQ_REPR_GENERATINGFUNCTION(
+ gf, GeneratingFunction(
+ 1, {1, 1, 1},
+ {makeFracMatrix(2, 2, {{0, 1}, {0, 0}}),
+ makeFracMatrix(2, 2, {{0, 1}, {0, 0}}),
+ makeFracMatrix(2, 2, {{0, 0}, {0, 0}})},
+ {{{-1, 1}, {-1, 0}}, {{1, -1}, {0, -1}}, {{1, 0}, {0, 1}}}));
+
+ // Cartesian product of a cube with side M and a right triangle with side N.
+ ineqs = makeIntMatrix(9, 8,
+ {{1, 0, 0, 0, 0, 1, 0, 0},
+ {0, 1, 0, 0, 0, 1, 0, 0},
+ {0, 0, 1, 0, 0, 1, 0, 0},
+ {-1, 0, 0, 0, 0, 1, 0, 0},
+ {0, -1, 0, 0, 0, 1, 0, 0},
+ {0, 0, -1, 0, 0, 1, 0, 0},
+ {0, 0, 0, 1, 0, 0, 0, 0},
+ {0, 0, 0, 0, 1, 0, 0, 0},
+ {0, 0, 0, -1, -1, 0, 1, 0}});
+ poly = defineHRep(5, 2);
+ for (unsigned i = 0; i < 9; i++)
+ poly.addInequality(ineqs.getRow(i));
----------------
Superty wrote:
I just remembered that there is a parsePresburgerSet and parseIntegerPolyhedron that you can use.
You can write the set down in syntax like
`(x,y) : (x + y - 4 >= 0, -x - y + 32 >= 0)`
which is much more understandable
https://github.com/llvm/llvm-project/pull/78987
More information about the Mlir-commits
mailing list