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