forked from OSchip/llvm-project
[libc][automemcpy] Introduce geomean of scores as a tie breaker
Differential Revision: https://reviews.llvm.org/D120040
This commit is contained in:
parent
6457f42bde
commit
da5a4f16e8
|
@ -60,7 +60,8 @@ struct PerDistributionData {
|
||||||
struct FunctionData {
|
struct FunctionData {
|
||||||
FunctionId Id;
|
FunctionId Id;
|
||||||
StringMap<PerDistributionData> PerDistributionData;
|
StringMap<PerDistributionData> PerDistributionData;
|
||||||
GradeHistogram GradeHisto = {}; // GradeEnum indexed array
|
double ScoresGeoMean; // Geomean of scores for each distribution.
|
||||||
|
GradeHistogram GradeHisto = {}; // GradeEnum indexed array
|
||||||
Grade::GradeEnum FinalGrade = Grade::BAD; // Overall grade for this function
|
Grade::GradeEnum FinalGrade = Grade::BAD; // Overall grade for this function
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -168,14 +168,17 @@ void fillScores(MutableArrayRef<FunctionData> Functions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void castVotes(MutableArrayRef<FunctionData> Functions) {
|
void castVotes(MutableArrayRef<FunctionData> Functions) {
|
||||||
for (FunctionData &Function : Functions)
|
for (FunctionData &Function : Functions) {
|
||||||
|
Function.ScoresGeoMean = 1.0;
|
||||||
for (const auto &Pair : Function.PerDistributionData) {
|
for (const auto &Pair : Function.PerDistributionData) {
|
||||||
const StringRef Distribution = Pair.getKey();
|
const StringRef Distribution = Pair.getKey();
|
||||||
const double Score = Pair.getValue().Score;
|
const double Score = Pair.getValue().Score;
|
||||||
|
Function.ScoresGeoMean *= Score;
|
||||||
const auto G = Grade::judge(Score);
|
const auto G = Grade::judge(Score);
|
||||||
++(Function.GradeHisto[G]);
|
++(Function.GradeHisto[G]);
|
||||||
Function.PerDistributionData[Distribution].Grade = G;
|
Function.PerDistributionData[Distribution].Grade = G;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (FunctionData &Function : Functions) {
|
for (FunctionData &Function : Functions) {
|
||||||
const auto &GradeHisto = Function.GradeHisto;
|
const auto &GradeHisto = Function.GradeHisto;
|
||||||
|
|
|
@ -141,18 +141,16 @@ int Main(int argc, char **argv) {
|
||||||
fillScores(Functions);
|
fillScores(Functions);
|
||||||
castVotes(Functions);
|
castVotes(Functions);
|
||||||
|
|
||||||
// TODO: Implement tie breaking algorithm.
|
// Present data by function type, Grade and Geomean of scores.
|
||||||
std::sort(Functions.begin(), Functions.end(),
|
std::sort(Functions.begin(), Functions.end(),
|
||||||
[](const FunctionData &A, const FunctionData &B) {
|
[](const FunctionData &A, const FunctionData &B) {
|
||||||
return A.FinalGrade < B.FinalGrade;
|
const auto Less = [](const FunctionData &FD) {
|
||||||
|
return std::make_tuple(FD.Id.Type, FD.FinalGrade,
|
||||||
|
-FD.ScoresGeoMean);
|
||||||
|
};
|
||||||
|
return Less(A) < Less(B);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Present data by function type.
|
|
||||||
std::stable_sort(Functions.begin(), Functions.end(),
|
|
||||||
[](const FunctionData &A, const FunctionData &B) {
|
|
||||||
return A.Id.Type < B.Id.Type;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Print result.
|
// Print result.
|
||||||
for (const FunctionData &Function : Functions) {
|
for (const FunctionData &Function : Functions) {
|
||||||
outs() << formatv("{0,-10}", Grade::getString(Function.FinalGrade));
|
outs() << formatv("{0,-10}", Grade::getString(Function.FinalGrade));
|
||||||
|
|
|
@ -139,27 +139,35 @@ TEST(AutomemcpyJsonResultsAnalyzer, castVotes) {
|
||||||
EXPECT_THAT(Data[1].Id, Foo2);
|
EXPECT_THAT(Data[1].Id, Foo2);
|
||||||
EXPECT_THAT(Data[2].Id, Foo3);
|
EXPECT_THAT(Data[2].Id, Foo3);
|
||||||
|
|
||||||
|
const auto GetDistData = [&Data](size_t Index, StringRef Name) {
|
||||||
|
return Data[Index].PerDistributionData.lookup(Name);
|
||||||
|
};
|
||||||
|
|
||||||
// Distribution A
|
// Distribution A
|
||||||
// Throughput is 0, 1 and 7, so normalized scores are 0, 1/7 and 1.
|
// Throughput is 0, 1 and 7, so normalized scores are 0, 1/7 and 1.
|
||||||
EXPECT_NEAR(Data[0].PerDistributionData.lookup("A").Score, 0, kAbsErr);
|
EXPECT_THAT(GetDistData(0, "A").Score, DoubleNear(0, kAbsErr));
|
||||||
EXPECT_NEAR(Data[1].PerDistributionData.lookup("A").Score, 1. / 7, kAbsErr);
|
EXPECT_THAT(GetDistData(1, "A").Score, DoubleNear(1. / 7, kAbsErr));
|
||||||
EXPECT_NEAR(Data[2].PerDistributionData.lookup("A").Score, 1, kAbsErr);
|
EXPECT_THAT(GetDistData(2, "A").Score, DoubleNear(1, kAbsErr));
|
||||||
// which are turned into grades BAD, MEDIOCRE and EXCELLENT.
|
// which are turned into grades BAD, MEDIOCRE and EXCELLENT.
|
||||||
EXPECT_THAT(Data[0].PerDistributionData.lookup("A").Grade, Grade::BAD);
|
EXPECT_THAT(GetDistData(0, "A").Grade, Grade::BAD);
|
||||||
EXPECT_THAT(Data[1].PerDistributionData.lookup("A").Grade, Grade::MEDIOCRE);
|
EXPECT_THAT(GetDistData(1, "A").Grade, Grade::MEDIOCRE);
|
||||||
EXPECT_THAT(Data[2].PerDistributionData.lookup("A").Grade, Grade::EXCELLENT);
|
EXPECT_THAT(GetDistData(2, "A").Grade, Grade::EXCELLENT);
|
||||||
|
|
||||||
// Distribution B
|
// Distribution B
|
||||||
// Throughput is 30, 100 and 100, so normalized scores are 0, 1 and 1.
|
// Throughput is 30, 100 and 100, so normalized scores are 0, 1 and 1.
|
||||||
EXPECT_NEAR(Data[0].PerDistributionData.lookup("B").Score, 0, kAbsErr);
|
EXPECT_THAT(GetDistData(0, "B").Score, DoubleNear(0, kAbsErr));
|
||||||
EXPECT_NEAR(Data[1].PerDistributionData.lookup("B").Score, 1, kAbsErr);
|
EXPECT_THAT(GetDistData(1, "B").Score, DoubleNear(1, kAbsErr));
|
||||||
EXPECT_NEAR(Data[2].PerDistributionData.lookup("B").Score, 1, kAbsErr);
|
EXPECT_THAT(GetDistData(2, "B").Score, DoubleNear(1, kAbsErr));
|
||||||
// which are turned into grades BAD, EXCELLENT and EXCELLENT.
|
// which are turned into grades BAD, EXCELLENT and EXCELLENT.
|
||||||
EXPECT_THAT(Data[0].PerDistributionData.lookup("B").Grade, Grade::BAD);
|
EXPECT_THAT(GetDistData(0, "B").Grade, Grade::BAD);
|
||||||
EXPECT_THAT(Data[1].PerDistributionData.lookup("B").Grade, Grade::EXCELLENT);
|
EXPECT_THAT(GetDistData(1, "B").Grade, Grade::EXCELLENT);
|
||||||
EXPECT_THAT(Data[2].PerDistributionData.lookup("B").Grade, Grade::EXCELLENT);
|
EXPECT_THAT(GetDistData(2, "B").Grade, Grade::EXCELLENT);
|
||||||
|
|
||||||
// Now looking from the functions point of view.
|
// Now looking from the functions point of view.
|
||||||
|
EXPECT_THAT(Data[0].ScoresGeoMean, DoubleNear(0, kAbsErr));
|
||||||
|
EXPECT_THAT(Data[1].ScoresGeoMean, DoubleNear(1. * (1. / 7), kAbsErr));
|
||||||
|
EXPECT_THAT(Data[2].ScoresGeoMean, DoubleNear(1, kAbsErr));
|
||||||
|
|
||||||
// Note the array is indexed by GradeEnum values (EXCELLENT=0 / BAD = 6)
|
// Note the array is indexed by GradeEnum values (EXCELLENT=0 / BAD = 6)
|
||||||
EXPECT_THAT(Data[0].GradeHisto, ElementsAre(0, 0, 0, 0, 0, 0, 2));
|
EXPECT_THAT(Data[0].GradeHisto, ElementsAre(0, 0, 0, 0, 0, 0, 2));
|
||||||
EXPECT_THAT(Data[1].GradeHisto, ElementsAre(1, 0, 0, 0, 0, 1, 0));
|
EXPECT_THAT(Data[1].GradeHisto, ElementsAre(1, 0, 0, 0, 0, 1, 0));
|
||||||
|
|
Loading…
Reference in New Issue