annotate llvm/tools/llvm-exegesis/lib/Clustering.h @ 266:00f31e85ec16 default tip

Added tag current for changeset 31d058e83c98
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 14 Oct 2023 10:13:55 +0900
parents 1f2b6ac9f198
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===-- Clustering.h --------------------------------------------*- C++ -*-===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8 ///
anatofuz
parents:
diff changeset
9 /// \file
anatofuz
parents:
diff changeset
10 /// Utilities to compute benchmark result clusters.
anatofuz
parents:
diff changeset
11 ///
anatofuz
parents:
diff changeset
12 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
13
anatofuz
parents:
diff changeset
14 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H
anatofuz
parents:
diff changeset
15 #define LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H
anatofuz
parents:
diff changeset
16
anatofuz
parents:
diff changeset
17 #include "BenchmarkResult.h"
anatofuz
parents:
diff changeset
18 #include "llvm/Support/Error.h"
anatofuz
parents:
diff changeset
19 #include <limits>
anatofuz
parents:
diff changeset
20 #include <vector>
anatofuz
parents:
diff changeset
21
anatofuz
parents:
diff changeset
22 namespace llvm {
anatofuz
parents:
diff changeset
23 namespace exegesis {
anatofuz
parents:
diff changeset
24
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
25 class BenchmarkClustering {
150
anatofuz
parents:
diff changeset
26 public:
anatofuz
parents:
diff changeset
27 enum ModeE { Dbscan, Naive };
anatofuz
parents:
diff changeset
28
anatofuz
parents:
diff changeset
29 // Clusters `Points` using DBSCAN with the given parameters. See the cc file
anatofuz
parents:
diff changeset
30 // for more explanations on the algorithm.
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
31 static Expected<BenchmarkClustering>
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
32 create(const std::vector<Benchmark> &Points, ModeE Mode,
150
anatofuz
parents:
diff changeset
33 size_t DbscanMinPts, double AnalysisClusteringEpsilon,
236
c4bab56944e8 LLVM 16
kono
parents: 150
diff changeset
34 const MCSubtargetInfo *SubtargetInfo = nullptr,
c4bab56944e8 LLVM 16
kono
parents: 150
diff changeset
35 const MCInstrInfo *InstrInfo = nullptr);
150
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 class ClusterId {
anatofuz
parents:
diff changeset
38 public:
anatofuz
parents:
diff changeset
39 static ClusterId noise() { return ClusterId(kNoise); }
anatofuz
parents:
diff changeset
40 static ClusterId error() { return ClusterId(kError); }
anatofuz
parents:
diff changeset
41 static ClusterId makeValid(size_t Id, bool IsUnstable = false) {
anatofuz
parents:
diff changeset
42 return ClusterId(Id, IsUnstable);
anatofuz
parents:
diff changeset
43 }
anatofuz
parents:
diff changeset
44 static ClusterId makeValidUnstable(size_t Id) {
anatofuz
parents:
diff changeset
45 return makeValid(Id, /*IsUnstable=*/true);
anatofuz
parents:
diff changeset
46 }
anatofuz
parents:
diff changeset
47
anatofuz
parents:
diff changeset
48 ClusterId() : Id_(kUndef), IsUnstable_(false) {}
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 // Compare id's, ignoring the 'unstability' bit.
anatofuz
parents:
diff changeset
51 bool operator==(const ClusterId &O) const { return Id_ == O.Id_; }
anatofuz
parents:
diff changeset
52 bool operator<(const ClusterId &O) const { return Id_ < O.Id_; }
anatofuz
parents:
diff changeset
53
anatofuz
parents:
diff changeset
54 bool isValid() const { return Id_ <= kMaxValid; }
anatofuz
parents:
diff changeset
55 bool isUnstable() const { return IsUnstable_; }
anatofuz
parents:
diff changeset
56 bool isNoise() const { return Id_ == kNoise; }
anatofuz
parents:
diff changeset
57 bool isError() const { return Id_ == kError; }
anatofuz
parents:
diff changeset
58 bool isUndef() const { return Id_ == kUndef; }
anatofuz
parents:
diff changeset
59
anatofuz
parents:
diff changeset
60 // Precondition: isValid().
anatofuz
parents:
diff changeset
61 size_t getId() const {
anatofuz
parents:
diff changeset
62 assert(isValid());
anatofuz
parents:
diff changeset
63 return Id_;
anatofuz
parents:
diff changeset
64 }
anatofuz
parents:
diff changeset
65
anatofuz
parents:
diff changeset
66 private:
anatofuz
parents:
diff changeset
67 ClusterId(size_t Id, bool IsUnstable = false)
anatofuz
parents:
diff changeset
68 : Id_(Id), IsUnstable_(IsUnstable) {}
anatofuz
parents:
diff changeset
69
anatofuz
parents:
diff changeset
70 static constexpr const size_t kMaxValid =
anatofuz
parents:
diff changeset
71 (std::numeric_limits<size_t>::max() >> 1) - 4;
anatofuz
parents:
diff changeset
72 static constexpr const size_t kNoise = kMaxValid + 1;
anatofuz
parents:
diff changeset
73 static constexpr const size_t kError = kMaxValid + 2;
anatofuz
parents:
diff changeset
74 static constexpr const size_t kUndef = kMaxValid + 3;
anatofuz
parents:
diff changeset
75
anatofuz
parents:
diff changeset
76 size_t Id_ : (std::numeric_limits<size_t>::digits - 1);
anatofuz
parents:
diff changeset
77 size_t IsUnstable_ : 1;
anatofuz
parents:
diff changeset
78 };
anatofuz
parents:
diff changeset
79 static_assert(sizeof(ClusterId) == sizeof(size_t), "should be a bit field.");
anatofuz
parents:
diff changeset
80
anatofuz
parents:
diff changeset
81 struct Cluster {
anatofuz
parents:
diff changeset
82 Cluster() = delete;
anatofuz
parents:
diff changeset
83 explicit Cluster(const ClusterId &Id) : Id(Id) {}
anatofuz
parents:
diff changeset
84
anatofuz
parents:
diff changeset
85 const ClusterId Id;
anatofuz
parents:
diff changeset
86 // Indices of benchmarks within the cluster.
anatofuz
parents:
diff changeset
87 std::vector<int> PointIndices;
anatofuz
parents:
diff changeset
88 };
anatofuz
parents:
diff changeset
89
anatofuz
parents:
diff changeset
90 ClusterId getClusterIdForPoint(size_t P) const {
anatofuz
parents:
diff changeset
91 return ClusterIdForPoint_[P];
anatofuz
parents:
diff changeset
92 }
anatofuz
parents:
diff changeset
93
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
94 const std::vector<Benchmark> &getPoints() const { return Points_; }
150
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 const Cluster &getCluster(ClusterId Id) const {
anatofuz
parents:
diff changeset
97 assert(!Id.isUndef() && "unlabeled cluster");
anatofuz
parents:
diff changeset
98 if (Id.isNoise()) {
anatofuz
parents:
diff changeset
99 return NoiseCluster_;
anatofuz
parents:
diff changeset
100 }
anatofuz
parents:
diff changeset
101 if (Id.isError()) {
anatofuz
parents:
diff changeset
102 return ErrorCluster_;
anatofuz
parents:
diff changeset
103 }
anatofuz
parents:
diff changeset
104 return Clusters_[Id.getId()];
anatofuz
parents:
diff changeset
105 }
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 const std::vector<Cluster> &getValidClusters() const { return Clusters_; }
anatofuz
parents:
diff changeset
108
anatofuz
parents:
diff changeset
109 // Returns true if the given point is within a distance Epsilon of each other.
anatofuz
parents:
diff changeset
110 bool isNeighbour(const std::vector<BenchmarkMeasure> &P,
anatofuz
parents:
diff changeset
111 const std::vector<BenchmarkMeasure> &Q,
anatofuz
parents:
diff changeset
112 const double EpsilonSquared_) const {
anatofuz
parents:
diff changeset
113 double DistanceSquared = 0.0;
anatofuz
parents:
diff changeset
114 for (size_t I = 0, E = P.size(); I < E; ++I) {
anatofuz
parents:
diff changeset
115 const auto Diff = P[I].PerInstructionValue - Q[I].PerInstructionValue;
anatofuz
parents:
diff changeset
116 DistanceSquared += Diff * Diff;
anatofuz
parents:
diff changeset
117 }
anatofuz
parents:
diff changeset
118 return DistanceSquared <= EpsilonSquared_;
anatofuz
parents:
diff changeset
119 }
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 private:
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
122 BenchmarkClustering(
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
123 const std::vector<Benchmark> &Points,
150
anatofuz
parents:
diff changeset
124 double AnalysisClusteringEpsilonSquared);
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126 Error validateAndSetup();
anatofuz
parents:
diff changeset
127
anatofuz
parents:
diff changeset
128 void clusterizeDbScan(size_t MinPts);
236
c4bab56944e8 LLVM 16
kono
parents: 150
diff changeset
129 void clusterizeNaive(const MCSubtargetInfo &SubtargetInfo,
c4bab56944e8 LLVM 16
kono
parents: 150
diff changeset
130 const MCInstrInfo &InstrInfo);
150
anatofuz
parents:
diff changeset
131
anatofuz
parents:
diff changeset
132 // Stabilization is only needed if dbscan was used to clusterize.
anatofuz
parents:
diff changeset
133 void stabilize(unsigned NumOpcodes);
anatofuz
parents:
diff changeset
134
anatofuz
parents:
diff changeset
135 void rangeQuery(size_t Q, std::vector<size_t> &Scratchpad) const;
anatofuz
parents:
diff changeset
136
anatofuz
parents:
diff changeset
137 bool areAllNeighbours(ArrayRef<size_t> Pts) const;
anatofuz
parents:
diff changeset
138
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
139 const std::vector<Benchmark> &Points_;
150
anatofuz
parents:
diff changeset
140 const double AnalysisClusteringEpsilonSquared_;
anatofuz
parents:
diff changeset
141
anatofuz
parents:
diff changeset
142 int NumDimensions_ = 0;
anatofuz
parents:
diff changeset
143 // ClusterForPoint_[P] is the cluster id for Points[P].
anatofuz
parents:
diff changeset
144 std::vector<ClusterId> ClusterIdForPoint_;
anatofuz
parents:
diff changeset
145 std::vector<Cluster> Clusters_;
anatofuz
parents:
diff changeset
146 Cluster NoiseCluster_;
anatofuz
parents:
diff changeset
147 Cluster ErrorCluster_;
anatofuz
parents:
diff changeset
148 };
anatofuz
parents:
diff changeset
149
anatofuz
parents:
diff changeset
150 class SchedClassClusterCentroid {
anatofuz
parents:
diff changeset
151 public:
anatofuz
parents:
diff changeset
152 const std::vector<PerInstructionStats> &getStats() const {
anatofuz
parents:
diff changeset
153 return Representative;
anatofuz
parents:
diff changeset
154 }
anatofuz
parents:
diff changeset
155
anatofuz
parents:
diff changeset
156 std::vector<BenchmarkMeasure> getAsPoint() const;
anatofuz
parents:
diff changeset
157
anatofuz
parents:
diff changeset
158 void addPoint(ArrayRef<BenchmarkMeasure> Point);
anatofuz
parents:
diff changeset
159
252
1f2b6ac9f198 LLVM16-1
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 236
diff changeset
160 bool validate(Benchmark::ModeE Mode) const;
150
anatofuz
parents:
diff changeset
161
anatofuz
parents:
diff changeset
162 private:
anatofuz
parents:
diff changeset
163 // Measurement stats for the points in the SchedClassCluster.
anatofuz
parents:
diff changeset
164 std::vector<PerInstructionStats> Representative;
anatofuz
parents:
diff changeset
165 };
anatofuz
parents:
diff changeset
166
anatofuz
parents:
diff changeset
167 } // namespace exegesis
anatofuz
parents:
diff changeset
168 } // namespace llvm
anatofuz
parents:
diff changeset
169
anatofuz
parents:
diff changeset
170 #endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H