Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 1 | //===-- ClusteringTest.cpp --------------------------------------*- C++ -*-===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 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 | |
Fangrui Song | 32401af | 2018-10-22 17:10:47 +0000 | [diff] [blame] | 16 | namespace llvm { |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 17 | namespace exegesis { |
| 18 | |
| 19 | namespace { |
| 20 | |
| 21 | using testing::Field; |
| 22 | using testing::UnorderedElementsAre; |
| 23 | using testing::UnorderedElementsAreArray; |
| 24 | |
Clement Courbet | c08b26e | 2019-03-22 13:37:39 +0000 | [diff] [blame] | 25 | static const auto HasPoints = [](const std::vector<int> &Indices) { |
Clement Courbet | 2855077 | 2019-03-22 13:13:12 +0000 | [diff] [blame] | 26 | return Field(&InstructionBenchmarkClustering::Cluster::PointIndices, |
| 27 | UnorderedElementsAreArray(Indices)); |
| 28 | }; |
| 29 | |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 30 | TEST(ClusteringTest, Clusters3D) { |
| 31 | std::vector<InstructionBenchmark> Points(6); |
| 32 | |
| 33 | // Cluster around (x=0, y=1, z=2): points {0, 3}. |
Clement Courbet | 684a5f6 | 2018-09-26 08:37:21 +0000 | [diff] [blame] | 34 | Points[0].Measurements = { |
Clement Courbet | 28d4f85 | 2018-09-26 13:35:10 +0000 | [diff] [blame] | 35 | {"x", 0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}}; |
Clement Courbet | 684a5f6 | 2018-09-26 08:37:21 +0000 | [diff] [blame] | 36 | Points[3].Measurements = { |
Clement Courbet | 28d4f85 | 2018-09-26 13:35:10 +0000 | [diff] [blame] | 37 | {"x", -0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}}; |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 38 | // Cluster around (x=1, y=1, z=2): points {1, 4}. |
Clement Courbet | 684a5f6 | 2018-09-26 08:37:21 +0000 | [diff] [blame] | 39 | Points[1].Measurements = { |
Clement Courbet | 28d4f85 | 2018-09-26 13:35:10 +0000 | [diff] [blame] | 40 | {"x", 1.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}}; |
Clement Courbet | 684a5f6 | 2018-09-26 08:37:21 +0000 | [diff] [blame] | 41 | Points[4].Measurements = { |
Clement Courbet | 28d4f85 | 2018-09-26 13:35:10 +0000 | [diff] [blame] | 42 | {"x", 0.99, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}}; |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 43 | // Cluster around (x=0, y=0, z=0): points {5}, marked as noise. |
Clement Courbet | 684a5f6 | 2018-09-26 08:37:21 +0000 | [diff] [blame] | 44 | Points[5].Measurements = { |
Clement Courbet | 28d4f85 | 2018-09-26 13:35:10 +0000 | [diff] [blame] | 45 | {"x", 0.0, 0.0}, {"y", 0.01, 0.0}, {"z", -0.02, 0.0}}; |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 46 | // Error cluster: points {2} |
| 47 | Points[2].Error = "oops"; |
| 48 | |
Roman Lebedev | c2423fe | 2019-03-28 08:55:01 +0000 | [diff] [blame] | 49 | auto Clustering = InstructionBenchmarkClustering::create( |
| 50 | Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25); |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 51 | ASSERT_TRUE((bool)Clustering); |
| 52 | EXPECT_THAT(Clustering.get().getValidClusters(), |
| 53 | UnorderedElementsAre(HasPoints({0, 3}), HasPoints({1, 4}))); |
| 54 | EXPECT_THAT(Clustering.get().getCluster( |
| 55 | InstructionBenchmarkClustering::ClusterId::noise()), |
| 56 | HasPoints({5})); |
| 57 | EXPECT_THAT(Clustering.get().getCluster( |
| 58 | InstructionBenchmarkClustering::ClusterId::error()), |
| 59 | HasPoints({2})); |
| 60 | |
| 61 | EXPECT_EQ(Clustering.get().getClusterIdForPoint(2), |
| 62 | InstructionBenchmarkClustering::ClusterId::error()); |
| 63 | EXPECT_EQ(Clustering.get().getClusterIdForPoint(5), |
| 64 | InstructionBenchmarkClustering::ClusterId::noise()); |
| 65 | EXPECT_EQ(Clustering.get().getClusterIdForPoint(0), |
| 66 | Clustering.get().getClusterIdForPoint(3)); |
| 67 | EXPECT_EQ(Clustering.get().getClusterIdForPoint(1), |
| 68 | Clustering.get().getClusterIdForPoint(4)); |
| 69 | } |
| 70 | |
| 71 | TEST(ClusteringTest, Clusters3D_InvalidSize) { |
| 72 | std::vector<InstructionBenchmark> Points(6); |
Clement Courbet | 684a5f6 | 2018-09-26 08:37:21 +0000 | [diff] [blame] | 73 | Points[0].Measurements = { |
Clement Courbet | 28d4f85 | 2018-09-26 13:35:10 +0000 | [diff] [blame] | 74 | {"x", 0.01, 0.0}, {"y", 1.02, 0.0}, {"z", 1.98, 0.0}}; |
| 75 | Points[1].Measurements = {{"y", 1.02, 0.0}, {"z", 1.98, 0.0}}; |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 76 | auto Error = |
Roman Lebedev | c2423fe | 2019-03-28 08:55:01 +0000 | [diff] [blame] | 77 | InstructionBenchmarkClustering::create( |
| 78 | Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25) |
| 79 | .takeError(); |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 80 | ASSERT_TRUE((bool)Error); |
| 81 | consumeError(std::move(Error)); |
| 82 | } |
| 83 | |
| 84 | TEST(ClusteringTest, Clusters3D_InvalidOrder) { |
| 85 | std::vector<InstructionBenchmark> Points(6); |
Clement Courbet | 28d4f85 | 2018-09-26 13:35:10 +0000 | [diff] [blame] | 86 | Points[0].Measurements = {{"x", 0.01, 0.0}, {"y", 1.02, 0.0}}; |
| 87 | Points[1].Measurements = {{"y", 1.02, 0.0}, {"x", 1.98, 0.0}}; |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 88 | auto Error = |
Roman Lebedev | c2423fe | 2019-03-28 08:55:01 +0000 | [diff] [blame] | 89 | InstructionBenchmarkClustering::create( |
| 90 | Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 0.25) |
| 91 | .takeError(); |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 92 | ASSERT_TRUE((bool)Error); |
| 93 | consumeError(std::move(Error)); |
| 94 | } |
| 95 | |
Clement Courbet | 17d3c25 | 2018-05-22 13:31:29 +0000 | [diff] [blame] | 96 | TEST(ClusteringTest, Ordering) { |
| 97 | ASSERT_LT(InstructionBenchmarkClustering::ClusterId::makeValid(1), |
| 98 | InstructionBenchmarkClustering::ClusterId::makeValid(2)); |
| 99 | |
| 100 | ASSERT_LT(InstructionBenchmarkClustering::ClusterId::makeValid(2), |
| 101 | InstructionBenchmarkClustering::ClusterId::noise()); |
| 102 | |
| 103 | ASSERT_LT(InstructionBenchmarkClustering::ClusterId::makeValid(2), |
| 104 | InstructionBenchmarkClustering::ClusterId::error()); |
| 105 | |
| 106 | ASSERT_LT(InstructionBenchmarkClustering::ClusterId::noise(), |
| 107 | InstructionBenchmarkClustering::ClusterId::error()); |
| 108 | } |
| 109 | |
Clement Courbet | 2855077 | 2019-03-22 13:13:12 +0000 | [diff] [blame] | 110 | TEST(ClusteringTest, Ordering1) { |
| 111 | std::vector<InstructionBenchmark> Points(3); |
| 112 | |
| 113 | Points[0].Measurements = { |
| 114 | {"x", 0.0, 0.0}}; |
| 115 | Points[1].Measurements = { |
| 116 | {"x", 1.0, 0.0}}; |
| 117 | Points[2].Measurements = { |
| 118 | {"x", 2.0, 0.0}}; |
| 119 | |
Roman Lebedev | c2423fe | 2019-03-28 08:55:01 +0000 | [diff] [blame] | 120 | auto Clustering = InstructionBenchmarkClustering::create( |
| 121 | Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 1.1); |
Clement Courbet | 2855077 | 2019-03-22 13:13:12 +0000 | [diff] [blame] | 122 | ASSERT_TRUE((bool)Clustering); |
| 123 | EXPECT_THAT(Clustering.get().getValidClusters(), |
| 124 | UnorderedElementsAre(HasPoints({0, 1, 2}))); |
| 125 | } |
| 126 | |
| 127 | TEST(ClusteringTest, Ordering2) { |
| 128 | std::vector<InstructionBenchmark> Points(3); |
| 129 | |
| 130 | Points[0].Measurements = { |
| 131 | {"x", 0.0, 0.0}}; |
| 132 | Points[1].Measurements = { |
| 133 | {"x", 2.0, 0.0}}; |
| 134 | Points[2].Measurements = { |
| 135 | {"x", 1.0, 0.0}}; |
| 136 | |
Roman Lebedev | c2423fe | 2019-03-28 08:55:01 +0000 | [diff] [blame] | 137 | auto Clustering = InstructionBenchmarkClustering::create( |
| 138 | Points, InstructionBenchmarkClustering::ModeE::Dbscan, 2, 1.1); |
Clement Courbet | 2855077 | 2019-03-22 13:13:12 +0000 | [diff] [blame] | 139 | ASSERT_TRUE((bool)Clustering); |
| 140 | EXPECT_THAT(Clustering.get().getValidClusters(), |
| 141 | UnorderedElementsAre(HasPoints({0, 1, 2}))); |
| 142 | } |
| 143 | |
Clement Courbet | 9671541 | 2018-05-07 09:09:48 +0000 | [diff] [blame] | 144 | } // namespace |
| 145 | } // namespace exegesis |
Fangrui Song | 32401af | 2018-10-22 17:10:47 +0000 | [diff] [blame] | 146 | } // namespace llvm |