[perf] Don't display LSE where it doesn't apply.
Also fix bug so LSE gets reported when it does apply.
Bug: skia:10392
Change-Id: I221a1dd6f29fd3db7225c16c9c56e32ad8dc363f
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/301636
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
Commit-Queue: Joe Gregorio <jcgregorio@google.com>
diff --git a/perf/go/stepfit/stepfit.go b/perf/go/stepfit/stepfit.go
index 66752c7..3575b43 100644
--- a/perf/go/stepfit/stepfit.go
+++ b/perf/go/stepfit/stepfit.go
@@ -33,7 +33,9 @@
//
// Used in ClusterSummary.
type StepFit struct {
- // LeastSquares is the Least Squares error for a step function curve fit to the trace.
+ // LeastSquares is the Least Squares error for a step function curve fit to
+ // the trace. Will be set to InvalidLeastSquaresError if LSE isn't
+ // calculated for a given algorithm.
LeastSquares float32 `json:"least_squares"`
// TurningPoint is the index where the Step Function changes value.
@@ -58,6 +60,10 @@
Status StepFitStatus `json:"status"`
}
+// InvalidLeastSquaresError signals that the value of StepFit.LeastSquares is
+// invalid, i.e. it is not calculated for the given algorithm.
+const InvalidLeastSquaresError = -1
+
// NewStepFit creates an properly initialized StepFit struct.
func NewStepFit() *StepFit {
return &StepFit{
@@ -92,7 +98,8 @@
trace = trace[0 : len(trace)-1]
}
- var lse float32
+ var lse float32 = InvalidLeastSquaresError
+
var regression float32
stepSize := float32(-1.0)
i := len(trace) / 2
@@ -104,7 +111,7 @@
if stepDetection == types.OriginalStep {
// This is the original recipe step detection as described at
// https://bitworking.org/news/2014/11/detecting-benchmark-regressions
- lse := float32(math.MaxFloat32)
+ lse = float32(math.MaxFloat32)
if y0 != y1 {
d := vec32.SSE(trace[:i], y0) + vec32.SSE(trace[i:], y1)
if d < lse {
diff --git a/perf/go/stepfit/stepfit_test.go b/perf/go/stepfit/stepfit_test.go
index 8c901ff..f7d0e65 100644
--- a/perf/go/stepfit/stepfit_test.go
+++ b/perf/go/stepfit/stepfit_test.go
@@ -41,75 +41,76 @@
func TestStepFit_NoStep(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 2, StepSize: -1, Status: UNINTERESTING, Regression: -2.7105057e-19},
+ &StepFit{TurningPoint: 2, StepSize: -1, Status: UNINTERESTING, Regression: -2.7105057e-19,
+ LeastSquares: 3.6893486e+18},
GetStepFitAtMid([]float32{1, 1, 1, 1, 1}, minStdDev, 50, types.OriginalStep))
}
func TestStepFit_Absolute_NoStep(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 2, StepSize: 0, Status: UNINTERESTING, Regression: 0},
+ &StepFit{TurningPoint: 2, StepSize: 0, Status: UNINTERESTING, Regression: 0, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 2, 1, 2, x}, minStdDev, 1.0, types.AbsoluteStep))
}
func TestStepFit_Absolute_StepExactMatch(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 2, StepSize: -1, Status: HIGH, Regression: -1},
+ &StepFit{TurningPoint: 2, StepSize: -1, Status: HIGH, Regression: -1, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 1, 2, 2, x}, minStdDev, 1.0, types.AbsoluteStep))
}
func TestStepFit_Absolute_StepTooSmall(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 2, StepSize: -0.5, Status: UNINTERESTING, Regression: -0.5},
+ &StepFit{TurningPoint: 2, StepSize: -0.5, Status: UNINTERESTING, Regression: -0.5, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 1, 1.5, 1.5, x}, minStdDev, 1.0, types.AbsoluteStep))
}
func TestStepFit_Percent_NoStep(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 2, StepSize: 0, Status: UNINTERESTING, Regression: 0},
+ &StepFit{TurningPoint: 2, StepSize: 0, Status: UNINTERESTING, Regression: 0, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 2, 1, 2, x}, minStdDev, 1.0, types.PercentStep))
}
func TestStepFit_Percent_StepExactMatch(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 1, StepSize: -1, Status: HIGH, Regression: -1},
+ &StepFit{TurningPoint: 1, StepSize: -1, Status: HIGH, Regression: -1, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 2, x}, minStdDev, 1.0, types.PercentStep))
}
func TestStepFit_Percent_StepTooSmall(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 1, StepSize: -0.5, Status: UNINTERESTING, Regression: -0.5},
+ &StepFit{TurningPoint: 1, StepSize: -0.5, Status: UNINTERESTING, Regression: -0.5, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 1.5, x}, minStdDev, 1.0, types.PercentStep))
}
func TestStepFit_Cohen_NoStep(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 3, StepSize: -0.1999998, Status: UNINTERESTING, Regression: -0.1999998},
+ &StepFit{TurningPoint: 3, StepSize: -0.1999998, Status: UNINTERESTING, Regression: -0.1999998, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 1.1, 0.9, 1.02, 1.12, 0.92, x}, minStdDev, 1.0, types.CohenStep))
}
func TestStepFit_Cohen_Step(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 3, StepSize: -0.1999998, Status: HIGH, Regression: -0.1999998},
+ &StepFit{TurningPoint: 3, StepSize: -0.1999998, Status: HIGH, Regression: -0.1999998, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 1.1, 0.9, 1.02, 1.12, 0.92, x}, minStdDev, 0.1, types.CohenStep))
}
func TestStepFit_Cohen_StepWithZeroStandardDeviation(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{TurningPoint: 2, StepSize: -10, Status: HIGH, Regression: -10},
+ &StepFit{TurningPoint: 2, StepSize: -10, Status: HIGH, Regression: -10, LeastSquares: InvalidLeastSquaresError},
GetStepFitAtMid([]float32{1, 1, 2, 2, x}, minStdDev, 0.2, types.CohenStep))
}
func TestStepFit_Cohen_StepWithLargeStandardDeviation(t *testing.T) {
unittest.SmallTest(t)
assert.Equal(t,
- &StepFit{LeastSquares: 0, TurningPoint: 2, StepSize: -2.828427, Regression: -2.828427, Status: "High"},
+ &StepFit{LeastSquares: InvalidLeastSquaresError, TurningPoint: 2, StepSize: -2.828427, Regression: -2.828427, Status: "High"},
GetStepFitAtMid([]float32{1, 2, 3, 4, x}, minStdDev, 0.2, types.CohenStep))
}
diff --git a/perf/modules/cluster-summary2-sk/cluster-summary2-sk-demo.ts b/perf/modules/cluster-summary2-sk/cluster-summary2-sk-demo.ts
index 8d81f7d..9a951f2 100644
--- a/perf/modules/cluster-summary2-sk/cluster-summary2-sk-demo.ts
+++ b/perf/modules/cluster-summary2-sk/cluster-summary2-sk-demo.ts
@@ -109,9 +109,10 @@
);
cluster!.full_summary = fullSummary;
-const summary2 = JSON.parse(JSON.stringify(fullSummary));
-summary2.summary.step_fit.status = 'High';
-summary2.summary.step_fit.regression = 201;
+const summary2: FullSummary = JSON.parse(JSON.stringify(fullSummary));
+summary2.summary.step_fit!.status = 'High';
+summary2.summary.step_fit!.regression = 201;
+summary2.summary.step_fit!.least_squares = -1; // Should be hidden.
const nostatus = document.querySelector<ClusterSummary2Sk>(
'cluster-summary2-sk.nostatus'
);
diff --git a/perf/modules/cluster-summary2-sk/cluster-summary2-sk.ts b/perf/modules/cluster-summary2-sk/cluster-summary2-sk.ts
index 212ea01..5842dad 100644
--- a/perf/modules/cluster-summary2-sk/cluster-summary2-sk.ts
+++ b/perf/modules/cluster-summary2-sk/cluster-summary2-sk.ts
@@ -88,16 +88,18 @@
export class ClusterSummary2Sk extends ElementSk {
private static template = (ele: ClusterSummary2Sk) => html`
<div class="regression ${ele.statusClass()}">
- Regression: <span>${trunc(ele.summary!.step_fit!.regression)}</span>
+ Regression:
+ <span>${trunc(ele.summary!.step_fit!.regression)}</span>
</div>
<div class="stats">
- <div class="labelled">Cluster Size: <span>${ele.summary.num}</span></div>
<div class="labelled">
- Least Squares Error:
- <span> ${trunc(ele.summary!.step_fit!.least_squares)} </span>
+ Cluster Size:
+ <span>${ele.summary.num}</span>
</div>
+ ${ClusterSummary2Sk.leastSquares(ele)}
<div class="labelled">
- Step Size: <span>${trunc(ele.summary!.step_fit!.step_size)} </span>
+ Step Size:
+ <span>${trunc(ele.summary!.step_fit!.step_size)}</span>
</div>
</div>
<plot-simple-sk
@@ -106,8 +108,7 @@
height="250"
specialevents
@trace_selected=${ele.traceSelected}
- >
- </plot-simple-sk>
+ ></plot-simple-sk>
<div id="status" class=${ele.hiddenClass()}>
<p class="disabledMessage">You must be logged in to change the status.</p>
<triage2-sk
@@ -115,8 +116,7 @@
@change=${(e: CustomEvent<Status>) => {
ele.triageStatus.status = e.detail;
}}
- >
- </triage2-sk>
+ ></triage2-sk>
<input
type="text"
.value=${ele.triageStatus.message}
@@ -125,14 +125,14 @@
}}
label="Message"
/>
- <button class="action" @click=${ele.update}> Update </button>
+ <button class="action" @click=${ele.update}>Update</button>
</div>
<commit-detail-panel-sk id="commits" selectable></commit-detail-panel-sk>
<div class="actions">
<button id="shortcut" @click=${ele.openShortcut}>
View on dashboard
</button>
- <button @click=${ele.toggleWordCloud}> Word Cloud </button>
+ <button @click=${ele.toggleWordCloud}>Word Cloud</button>
<a id="permalink" class=${ele.hiddenClass()} href=${ele.permaLink()}>
Permlink
</a>
@@ -143,6 +143,18 @@
</collapse-sk>
`;
+ private static leastSquares = (ele: ClusterSummary2Sk) => {
+ if (ele.summary!.step_fit!.least_squares >= 0) {
+ return html`
+ <div class="labelled">
+ Least Squares Error:
+ <span>${trunc(ele.summary!.step_fit!.least_squares)}</span>
+ </div>
+ `;
+ }
+ return html``;
+ };
+
private summary: ClusterSummary;
private triageStatus: TriageStatus;
private wordCloud: CollapseSk | null = null;