xref: /llvm-project/llvm/unittests/tools/llvm-exegesis/ClusteringTest.cpp (revision 2946cd701067404b99c39fb29dc9c74bd7193eb3)
1 //===-- ClusteringTest.cpp --------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Clustering.h"
10 #include "BenchmarkResult.h"
11 #include "llvm/Support/Error.h"
12 #include "llvm/Support/raw_ostream.h"
13 #include "gmock/gmock.h"
14 #include "gtest/gtest.h"
15 
16 namespace llvm {
17 namespace exegesis {
18 
19 namespace {
20 
21 using testing::Field;
22 using testing::UnorderedElementsAre;
23 using testing::UnorderedElementsAreArray;
24 
25 TEST(ClusteringTest, Clusters3D) {
26   std::vector<InstructionBenchmark> Points(6);
27 
28   // Cluster around (x=0, y=1, z=2): points {0, 3}.
29   Points[0].Measurements = {
30       {"x", 0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
31   Points[3].Measurements = {
32       {"x", -0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
33   // Cluster around (x=1, y=1, z=2): points {1, 4}.
34   Points[1].Measurements = {
35       {"x", 1.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
36   Points[4].Measurements = {
37       {"x", 0.99, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
38   // Cluster around (x=0, y=0, z=0): points {5}, marked as noise.
39   Points[5].Measurements = {
40       {"x", 0.0, 0.0}, {"y", 0.01, 0.0}, {"z", -0.02, 0.0}};
41   // Error cluster: points {2}
42   Points[2].Error = "oops";
43 
44   auto HasPoints = [](const std::vector<int> &Indices) {
45     return Field(&InstructionBenchmarkClustering::Cluster::PointIndices,
46                  UnorderedElementsAreArray(Indices));
47   };
48 
49   auto Clustering = InstructionBenchmarkClustering::create(Points, 2, 0.25);
50   ASSERT_TRUE((bool)Clustering);
51   EXPECT_THAT(Clustering.get().getValidClusters(),
52               UnorderedElementsAre(HasPoints({0, 3}), HasPoints({1, 4})));
53   EXPECT_THAT(Clustering.get().getCluster(
54                   InstructionBenchmarkClustering::ClusterId::noise()),
55               HasPoints({5}));
56   EXPECT_THAT(Clustering.get().getCluster(
57                   InstructionBenchmarkClustering::ClusterId::error()),
58               HasPoints({2}));
59 
60   EXPECT_EQ(Clustering.get().getClusterIdForPoint(2),
61             InstructionBenchmarkClustering::ClusterId::error());
62   EXPECT_EQ(Clustering.get().getClusterIdForPoint(5),
63             InstructionBenchmarkClustering::ClusterId::noise());
64   EXPECT_EQ(Clustering.get().getClusterIdForPoint(0),
65             Clustering.get().getClusterIdForPoint(3));
66   EXPECT_EQ(Clustering.get().getClusterIdForPoint(1),
67             Clustering.get().getClusterIdForPoint(4));
68 }
69 
70 TEST(ClusteringTest, Clusters3D_InvalidSize) {
71   std::vector<InstructionBenchmark> Points(6);
72   Points[0].Measurements = {
73       {"x", 0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
74   Points[1].Measurements = {{"y", 1.02, 0.0}, {"z", 1.98, 0.0}};
75   auto Error =
76       InstructionBenchmarkClustering::create(Points, 2, 0.25).takeError();
77   ASSERT_TRUE((bool)Error);
78   consumeError(std::move(Error));
79 }
80 
81 TEST(ClusteringTest, Clusters3D_InvalidOrder) {
82   std::vector<InstructionBenchmark> Points(6);
83   Points[0].Measurements = {{"x", 0.01, 0.0}, {"y", 1.02, 0.0}};
84   Points[1].Measurements = {{"y", 1.02, 0.0}, {"x", 1.98, 0.0}};
85   auto Error =
86       InstructionBenchmarkClustering::create(Points, 2, 0.25).takeError();
87   ASSERT_TRUE((bool)Error);
88   consumeError(std::move(Error));
89 }
90 
91 TEST(ClusteringTest, Ordering) {
92   ASSERT_LT(InstructionBenchmarkClustering::ClusterId::makeValid(1),
93             InstructionBenchmarkClustering::ClusterId::makeValid(2));
94 
95   ASSERT_LT(InstructionBenchmarkClustering::ClusterId::makeValid(2),
96             InstructionBenchmarkClustering::ClusterId::noise());
97 
98   ASSERT_LT(InstructionBenchmarkClustering::ClusterId::makeValid(2),
99             InstructionBenchmarkClustering::ClusterId::error());
100 
101   ASSERT_LT(InstructionBenchmarkClustering::ClusterId::noise(),
102             InstructionBenchmarkClustering::ClusterId::error());
103 }
104 
105 } // namespace
106 } // namespace exegesis
107 } // namespace llvm
108