xref: /llvm-project/mlir/unittests/IR/AffineMapTest.cpp (revision 6f5e5b630559f2d17bdccfab5dff3a97ac0f8c66)
1fe8a62c4SUday Bondhugula //===- AffineMapTest.cpp - unit tests for affine map API ------------------===//
2fe8a62c4SUday Bondhugula //
3fe8a62c4SUday Bondhugula // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe8a62c4SUday Bondhugula // See https://llvm.org/LICENSE.txt for license information.
5fe8a62c4SUday Bondhugula // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe8a62c4SUday Bondhugula //
7fe8a62c4SUday Bondhugula //===----------------------------------------------------------------------===//
8fe8a62c4SUday Bondhugula 
9fe8a62c4SUday Bondhugula #include "mlir/IR/AffineMap.h"
10fe8a62c4SUday Bondhugula #include "mlir/IR/Builders.h"
11fe8a62c4SUday Bondhugula #include "gtest/gtest.h"
12fe8a62c4SUday Bondhugula 
13fe8a62c4SUday Bondhugula using namespace mlir;
14fe8a62c4SUday Bondhugula 
15fe8a62c4SUday Bondhugula // Test AffineMap replace API for the zero result case.
16fe8a62c4SUday Bondhugula TEST(AffineMapTest, inferMapFromAffineExprs) {
17fe8a62c4SUday Bondhugula   MLIRContext ctx;
18fe8a62c4SUday Bondhugula   OpBuilder b(&ctx);
19fe8a62c4SUday Bondhugula   AffineMap map = b.getEmptyAffineMap();
20fe8a62c4SUday Bondhugula   DenseMap<AffineExpr, AffineExpr> replacements;
21fe8a62c4SUday Bondhugula   map.replace(replacements);
22fe8a62c4SUday Bondhugula   EXPECT_EQ(map, map);
23fe8a62c4SUday Bondhugula }
248b7af60cSAndrzej Warzyński 
258b7af60cSAndrzej Warzyński TEST(AffineMapTest, isProjectedPermutation) {
268b7af60cSAndrzej Warzyński   MLIRContext ctx;
278b7af60cSAndrzej Warzyński   OpBuilder b(&ctx);
288b7af60cSAndrzej Warzyński 
298b7af60cSAndrzej Warzyński   // 1. Empty map
308b7af60cSAndrzej Warzyński   AffineMap map1 = b.getEmptyAffineMap();
318b7af60cSAndrzej Warzyński   EXPECT_TRUE(map1.isProjectedPermutation());
328b7af60cSAndrzej Warzyński 
338b7af60cSAndrzej Warzyński   // 2. Map with a symbol
348b7af60cSAndrzej Warzyński   AffineMap map2 = AffineMap::get(0, 1, &ctx);
358b7af60cSAndrzej Warzyński   EXPECT_FALSE(map2.isProjectedPermutation());
368b7af60cSAndrzej Warzyński 
378b7af60cSAndrzej Warzyński   // 3. The result map is {0} and zero results are _allowed_.
388b7af60cSAndrzej Warzyński   auto zero = b.getAffineConstantExpr(0);
398b7af60cSAndrzej Warzyński   AffineMap map3 = AffineMap::get(1, 0, {zero}, &ctx);
408b7af60cSAndrzej Warzyński   EXPECT_TRUE(map3.isProjectedPermutation(/*allowZeroInResults=*/true));
418b7af60cSAndrzej Warzyński 
428b7af60cSAndrzej Warzyński   // 4. The result map is {0} and zero results are _not allowed_
438b7af60cSAndrzej Warzyński   AffineMap map4 = AffineMap::get(1, 0, {zero}, &ctx);
448b7af60cSAndrzej Warzyński   EXPECT_FALSE(map4.isProjectedPermutation(/*allowZeroInResults=*/false));
458b7af60cSAndrzej Warzyński 
468b7af60cSAndrzej Warzyński   // 5. The number of results > inputs
478b7af60cSAndrzej Warzyński   AffineMap map5 = AffineMap::get(1, 0, {zero, zero}, &ctx);
488b7af60cSAndrzej Warzyński   EXPECT_FALSE(map5.isProjectedPermutation(/*allowZeroInResults=*/true));
498b7af60cSAndrzej Warzyński 
508b7af60cSAndrzej Warzyński   // 6. A constant result that's not a {0}
518b7af60cSAndrzej Warzyński   auto one = b.getAffineConstantExpr(1);
528b7af60cSAndrzej Warzyński   AffineMap map6 = AffineMap::get(1, 0, {one}, &ctx);
538b7af60cSAndrzej Warzyński   EXPECT_FALSE(map6.isProjectedPermutation(/*allowZeroInResults=*/true));
548b7af60cSAndrzej Warzyński 
558b7af60cSAndrzej Warzyński   // 7. Not a dim expression
568b7af60cSAndrzej Warzyński   auto d0 = b.getAffineDimExpr(0);
578b7af60cSAndrzej Warzyński   auto d1 = b.getAffineDimExpr(1);
588b7af60cSAndrzej Warzyński 
598b7af60cSAndrzej Warzyński   auto sum = d0 + d1;
608b7af60cSAndrzej Warzyński   AffineMap map7 = AffineMap::get(2, 0, {sum}, &ctx);
618b7af60cSAndrzej Warzyński   EXPECT_FALSE(map7.isProjectedPermutation());
628b7af60cSAndrzej Warzyński 
638b7af60cSAndrzej Warzyński   // 8. (d0, d1, d2, d3, d4, d5) ->(d5, d3, d0, d1, d2, d4)
648b7af60cSAndrzej Warzyński   auto d2 = b.getAffineDimExpr(2);
658b7af60cSAndrzej Warzyński   auto d3 = b.getAffineDimExpr(3);
668b7af60cSAndrzej Warzyński   auto d4 = b.getAffineDimExpr(4);
678b7af60cSAndrzej Warzyński   auto d5 = b.getAffineDimExpr(5);
688b7af60cSAndrzej Warzyński   AffineMap map8 = AffineMap::get(6, 0, {d5, d3, d0, d1, d2, d4}, &ctx);
698b7af60cSAndrzej Warzyński   EXPECT_TRUE(map8.isProjectedPermutation());
708b7af60cSAndrzej Warzyński 
718b7af60cSAndrzej Warzyński   // 9. (d0, d1, d2, d3, d4, d5) ->(d5, d3, d0 + d1, d2, d4)
728b7af60cSAndrzej Warzyński   AffineMap map9 = AffineMap::get(6, 0, {d5, d3, sum, d2, d4}, &ctx);
738b7af60cSAndrzej Warzyński   EXPECT_FALSE(map9.isProjectedPermutation());
748b7af60cSAndrzej Warzyński 
758b7af60cSAndrzej Warzyński   // 10. (d0, d1, d2, d3, d4, d5) ->(d5, d3, d2, d4)
768b7af60cSAndrzej Warzyński   AffineMap map10 = AffineMap::get(6, 0, {d5, d3, d2, d4}, &ctx);
778b7af60cSAndrzej Warzyński   EXPECT_TRUE(map10.isProjectedPermutation());
788b7af60cSAndrzej Warzyński }
79c87336fcSAndrzej Warzyński 
80c87336fcSAndrzej Warzyński TEST(AffineMapTest, getInversePermutation) {
81c87336fcSAndrzej Warzyński   MLIRContext ctx;
82c87336fcSAndrzej Warzyński   OpBuilder b(&ctx);
83c87336fcSAndrzej Warzyński 
84c87336fcSAndrzej Warzyński   // 0. Empty map
85c87336fcSAndrzej Warzyński   AffineMap map0 = AffineMap::get(0, 0, {}, &ctx);
86c87336fcSAndrzej Warzyński   AffineMap inverseMap0 = inversePermutation(map0);
87c87336fcSAndrzej Warzyński   EXPECT_TRUE(inverseMap0.isEmpty());
88c87336fcSAndrzej Warzyński 
89c87336fcSAndrzej Warzyński   auto d0 = b.getAffineDimExpr(0);
90c87336fcSAndrzej Warzyński   auto d1 = b.getAffineDimExpr(1);
91c87336fcSAndrzej Warzyński   auto d2 = b.getAffineDimExpr(2);
92c87336fcSAndrzej Warzyński 
93c87336fcSAndrzej Warzyński   // 1.   (d0, d1, d2) -> (d1, d1, d0, d2, d1, d2, d1, d0)
94c87336fcSAndrzej Warzyński   AffineMap map1 = AffineMap::get(3, 0, {d1, d1, d0, d2, d1, d2, d1, d0}, &ctx);
95c87336fcSAndrzej Warzyński   //      (d0, d1, d2, d3, d4, d5, d6, d7) -> (d2, d0, d3)
96c87336fcSAndrzej Warzyński   AffineMap inverseMap1 = inversePermutation(map1);
97c87336fcSAndrzej Warzyński   auto resultsInv1 = inverseMap1.getResults();
98c87336fcSAndrzej Warzyński   EXPECT_EQ(resultsInv1.size(), 3UL);
99c87336fcSAndrzej Warzyński 
100*6f5e5b63SAndrzej Warzyński   // Expect (d2, d0, d3)
101*6f5e5b63SAndrzej Warzyński   SmallVector<unsigned> expected = {2, 0, 3};
102*6f5e5b63SAndrzej Warzyński   for (auto [idx, res] : llvm::enumerate(resultsInv1)) {
103*6f5e5b63SAndrzej Warzyński     AffineDimExpr expr = llvm::dyn_cast<AffineDimExpr>(res);
104*6f5e5b63SAndrzej Warzyński     EXPECT_TRUE(expr && expr.getPosition() == expected[idx]);
105*6f5e5b63SAndrzej Warzyński   }
106c87336fcSAndrzej Warzyński 
107c87336fcSAndrzej Warzyński   // 2.   (d0, d1, d2) -> (d1, d0 + d1, d0, d2, d1, d2, d1, d0)
108c87336fcSAndrzej Warzyński   auto sum = d0 + d1;
109c87336fcSAndrzej Warzyński   AffineMap map2 =
110c87336fcSAndrzej Warzyński       AffineMap::get(3, 0, {d1, sum, d0, d2, d1, d2, d1, d0}, &ctx);
111c87336fcSAndrzej Warzyński   //      (d0, d1, d2, d3, d4, d5, d6, d7) -> (d2, d0, d3)
112c87336fcSAndrzej Warzyński   AffineMap inverseMap2 = inversePermutation(map2);
113c87336fcSAndrzej Warzyński   auto resultsInv2 = inverseMap2.getResults();
114c87336fcSAndrzej Warzyński   EXPECT_EQ(resultsInv2.size(), 3UL);
115c87336fcSAndrzej Warzyński 
116*6f5e5b63SAndrzej Warzyński   // Expect (d2, d0, d3)
117*6f5e5b63SAndrzej Warzyński   expected = {2, 0, 3};
118*6f5e5b63SAndrzej Warzyński   for (auto [idx, res] : llvm::enumerate(resultsInv2)) {
119*6f5e5b63SAndrzej Warzyński     AffineDimExpr expr = llvm::dyn_cast<AffineDimExpr>(res);
120*6f5e5b63SAndrzej Warzyński     EXPECT_TRUE(expr && expr.getPosition() == expected[idx]);
121*6f5e5b63SAndrzej Warzyński   }
122c87336fcSAndrzej Warzyński }
123