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
__anon7ae965d30202(const std::vector<int> &Indices) 25 static const auto HasPoints = [](const std::vector<int> &Indices) {
26 return Field(&BenchmarkClustering::Cluster::PointIndices,
27 UnorderedElementsAreArray(Indices));
28 };
29
TEST(ClusteringTest,Clusters3D)30 TEST(ClusteringTest, Clusters3D) {
31 std::vector<Benchmark> Points(6);
32
33 // Cluster around (x=0, y=1, z=2): points {0, 3}.
34 Points[0].Measurements = {BenchmarkMeasure::Create("x", 0.01, {}),
35 BenchmarkMeasure::Create("y", 1.02, {}),
36 BenchmarkMeasure::Create("z", 1.98, {})};
37 Points[3].Measurements = {BenchmarkMeasure::Create("x", -0.01, {}),
38 BenchmarkMeasure::Create("y", 1.02, {}),
39 BenchmarkMeasure::Create("z", 1.98, {})};
40 // Cluster around (x=1, y=1, z=2): points {1, 4}.
41 Points[1].Measurements = {BenchmarkMeasure::Create("x", 1.01, {}),
42 BenchmarkMeasure::Create("y", 1.02, {}),
43 BenchmarkMeasure::Create("z", 1.98, {})};
44 Points[4].Measurements = {BenchmarkMeasure::Create("x", 0.99, {}),
45 BenchmarkMeasure::Create("y", 1.02, {}),
46 BenchmarkMeasure::Create("z", 1.98, {})};
47 // Cluster around (x=0, y=0, z=0): points {5}, marked as noise.
48 Points[5].Measurements = {BenchmarkMeasure::Create("x", 0.0, {}),
49 BenchmarkMeasure::Create("y", 0.01, {}),
50 BenchmarkMeasure::Create("z", -0.02, {})};
51 // Error cluster: points {2}
52 Points[2].Error = "oops";
53
54 auto Clustering = BenchmarkClustering::create(
55 Points, BenchmarkClustering::ModeE::Dbscan, 2, 0.25);
56 ASSERT_TRUE((bool)Clustering);
57 EXPECT_THAT(Clustering.get().getValidClusters(),
58 UnorderedElementsAre(HasPoints({0, 3}), HasPoints({1, 4})));
59 EXPECT_THAT(Clustering.get().getCluster(
60 BenchmarkClustering::ClusterId::noise()),
61 HasPoints({5}));
62 EXPECT_THAT(Clustering.get().getCluster(
63 BenchmarkClustering::ClusterId::error()),
64 HasPoints({2}));
65
66 EXPECT_EQ(Clustering.get().getClusterIdForPoint(2),
67 BenchmarkClustering::ClusterId::error());
68 EXPECT_EQ(Clustering.get().getClusterIdForPoint(5),
69 BenchmarkClustering::ClusterId::noise());
70 EXPECT_EQ(Clustering.get().getClusterIdForPoint(0),
71 Clustering.get().getClusterIdForPoint(3));
72 EXPECT_EQ(Clustering.get().getClusterIdForPoint(1),
73 Clustering.get().getClusterIdForPoint(4));
74 }
75
TEST(ClusteringTest,Clusters3D_InvalidSize)76 TEST(ClusteringTest, Clusters3D_InvalidSize) {
77 std::vector<Benchmark> Points(6);
78 Points[0].Measurements = {BenchmarkMeasure::Create("x", 0.01, {}),
79 BenchmarkMeasure::Create("y", 1.02, {}),
80 BenchmarkMeasure::Create("z", 1.98, {})};
81 Points[1].Measurements = {BenchmarkMeasure::Create("y", 1.02, {}),
82 BenchmarkMeasure::Create("z", 1.98, {})};
83 auto Error =
84 BenchmarkClustering::create(
85 Points, BenchmarkClustering::ModeE::Dbscan, 2, 0.25)
86 .takeError();
87 ASSERT_TRUE((bool)Error);
88 consumeError(std::move(Error));
89 }
90
TEST(ClusteringTest,Clusters3D_InvalidOrder)91 TEST(ClusteringTest, Clusters3D_InvalidOrder) {
92 std::vector<Benchmark> Points(6);
93 Points[0].Measurements = {BenchmarkMeasure::Create("x", 0.01, {}),
94 BenchmarkMeasure::Create("y", 1.02, {})};
95 Points[1].Measurements = {BenchmarkMeasure::Create("y", 1.02, {}),
96 BenchmarkMeasure::Create("x", 1.98, {})};
97 auto Error =
98 BenchmarkClustering::create(
99 Points, BenchmarkClustering::ModeE::Dbscan, 2, 0.25)
100 .takeError();
101 ASSERT_TRUE((bool)Error);
102 consumeError(std::move(Error));
103 }
104
TEST(ClusteringTest,Ordering)105 TEST(ClusteringTest, Ordering) {
106 ASSERT_LT(BenchmarkClustering::ClusterId::makeValid(1),
107 BenchmarkClustering::ClusterId::makeValid(2));
108
109 ASSERT_LT(BenchmarkClustering::ClusterId::makeValid(2),
110 BenchmarkClustering::ClusterId::noise());
111
112 ASSERT_LT(BenchmarkClustering::ClusterId::makeValid(2),
113 BenchmarkClustering::ClusterId::error());
114
115 ASSERT_LT(BenchmarkClustering::ClusterId::noise(),
116 BenchmarkClustering::ClusterId::error());
117 }
118
TEST(ClusteringTest,Ordering1)119 TEST(ClusteringTest, Ordering1) {
120 std::vector<Benchmark> Points(3);
121
122 Points[0].Measurements = {BenchmarkMeasure::Create("x", 0.0, {})};
123 Points[1].Measurements = {BenchmarkMeasure::Create("x", 1.0, {})};
124 Points[2].Measurements = {BenchmarkMeasure::Create("x", 2.0, {})};
125
126 auto Clustering = BenchmarkClustering::create(
127 Points, BenchmarkClustering::ModeE::Dbscan, 2, 1.1);
128 ASSERT_TRUE((bool)Clustering);
129 EXPECT_THAT(Clustering.get().getValidClusters(),
130 UnorderedElementsAre(HasPoints({0, 1, 2})));
131 }
132
TEST(ClusteringTest,Ordering2)133 TEST(ClusteringTest, Ordering2) {
134 std::vector<Benchmark> Points(3);
135
136 Points[0].Measurements = {BenchmarkMeasure::Create("x", 0.0, {})};
137 Points[1].Measurements = {BenchmarkMeasure::Create("x", 2.0, {})};
138 Points[2].Measurements = {BenchmarkMeasure::Create("x", 1.0, {})};
139
140 auto Clustering = BenchmarkClustering::create(
141 Points, BenchmarkClustering::ModeE::Dbscan, 2, 1.1);
142 ASSERT_TRUE((bool)Clustering);
143 EXPECT_THAT(Clustering.get().getValidClusters(),
144 UnorderedElementsAre(HasPoints({0, 1, 2})));
145 }
146
147 } // namespace
148 } // namespace exegesis
149 } // namespace llvm
150