///|
pub(all) enum PlotKind {
Scaling
RawDistribution
BlockOrder
Interval
Outlier
ChangePoint
Heatmap
Pareto
}
///|
pub struct PlotPoint {
x : String
y : Double
series : String
}
///|
/// How the x values of a plot are placed along the horizontal axis.
pub(all) enum AxisScale {
/// Evenly spaced, in order of first appearance; ticks show the x text.
Categorical
/// Positioned by numeric value. Every x value must parse as a finite number.
Linear
/// Positioned by the logarithm of positive finite numeric values.
Log
}
///|
pub struct Plot {
kind : PlotKind
title : String
unit : String
interval_kind : String
points : Array[PlotPoint]
x_axis : AxisScale
y_axis : AxisScale
x_label : String
note : String
}
///|
pub struct MismatchRow {
implementation : String
operation : String
operands : Array[String]
expected : String
actual : String
flags_diff : String
trap : String
fingerprint : String
replay_command : String
}
///|
pub fn MismatchRow::new(
implementation : String,
operation : String,
operands : Array[String],
expected : String,
actual : String,
flags_diff : String,
trap : String,
fingerprint : String,
replay_command : String,
) -> MismatchRow {
{
implementation,
operation,
operands,
expected,
actual,
flags_diff,
trap,
fingerprint,
replay_command,
}
}
///|
pub struct CapabilityCell {
implementation : String
outcome_kind : String
count : Int32
}
///|
pub fn CapabilityCell::new(
implementation : String,
outcome_kind : String,
count : Int32,
) -> CapabilityCell {
{ implementation, outcome_kind, count, }
}
///|
pub struct Counterexample {
implementation : String
minimal_input : String
fingerprint : String
shrink_path : Array[String]
replay_command : String
}
///|
pub fn Counterexample::new(
implementation : String,
minimal_input : String,
fingerprint : String,
shrink_path : Array[String],
replay_command : String,
) -> Counterexample {
{ implementation, minimal_input, fingerprint, shrink_path, replay_command, }
}
///|
pub struct CorpusSummary {
total : Int32
passed : Int32
failed : Int32
unsupported : Int32
expected_difference : Int32
}
///|
pub fn CorpusSummary::new(
total : Int32,
passed : Int32,
failed : Int32,
unsupported : Int32,
expected_difference : Int32,
) -> CorpusSummary {
{ total, passed, failed, unsupported, expected_difference, }
}
///|
pub struct DifferentialReport {
mismatches : Array[MismatchRow]
capabilities : Array[CapabilityCell]
counterexamples : Array[Counterexample]
corpus : CorpusSummary
}
///|
pub fn DifferentialReport::new(
mismatches : Array[MismatchRow],
capabilities : Array[CapabilityCell],
counterexamples : Array[Counterexample],
corpus : CorpusSummary,
) -> DifferentialReport {
{ mismatches, capabilities, counterexamples, corpus, }
}
///|
pub fn DifferentialReport::empty() -> DifferentialReport {
DifferentialReport::new([], [], [], CorpusSummary::new(0, 0, 0, 0, 0))
}
///|
pub fn PlotPoint::new(x : String, y : Double, series : String) -> PlotPoint {
{ x, y, series, }
}
///|
pub fn Plot::new(
kind : PlotKind,
title : String,
unit : String,
interval_kind : String,
points : Array[PlotPoint],
x_axis~ : AxisScale = Categorical,
y_axis~ : AxisScale = Linear,
x_label~ : String = "",
note~ : String = "",
) -> Plot {
{ kind, title, unit, interval_kind, points, x_axis, y_axis, x_label, note, }
}
///|
pub struct PlotDocument {
schema_version : @model.SchemaVersion
run_id : String
target : String
plots : Array[Plot]
differential : DifferentialReport
comparisons : ComparisonReport
}
///|
pub fn PlotDocument::new(
run_id : String,
target : String,
plots : Array[Plot],
differential~ : DifferentialReport = DifferentialReport::empty(),
comparisons~ : ComparisonReport = ComparisonReport::empty(),
) -> PlotDocument {
{
schema_version: @model.SchemaVersion::V2,
run_id,
target,
plots,
differential,
comparisons,
}
}
///|
/// The decision of one paired comparison; the same five outcomes as
/// `@stats.Decision`.
pub(all) enum ComparisonDecision {
Faster
Slower
Equivalent
Unknown
Invalid
}
///|
/// Lower-case name of the decision, as written to the plot JSON.
pub fn ComparisonDecision::text(self : ComparisonDecision) -> String {
match self {
Faster => "faster"
Slower => "slower"
Equivalent => "equivalent"
Unknown => "unknown"
Invalid => "invalid"
}
}
///|
/// Point estimates of one paired comparison over the blocks it used. Times
/// are per-iteration times in µs/op.
pub struct PairedEstimate {
/// Median of the baseline times of the used blocks.
baseline_median_us : Double
/// Median of the candidate times of the used blocks.
candidate_median_us : Double
/// Median of the paired deltas `candidate - baseline`.
median_delta_us : Double
/// `100 * median_delta_us / baseline_median_us`.
relative_delta_pct : Double
/// `baseline_median_us / (baseline_median_us + median_delta_us)`.
speedup : Double
}
///|
pub fn PairedEstimate::new(
baseline_median_us : Double,
candidate_median_us : Double,
median_delta_us : Double,
relative_delta_pct : Double,
speedup : Double,
) -> PairedEstimate {
{
baseline_median_us,
candidate_median_us,
median_delta_us,
relative_delta_pct,
speedup,
}
}
///|
/// Percentile bootstrap interval of the median paired delta, in µs/op and as a
/// percentage of the baseline median.
pub struct DeltaInterval {
low_us : Double
high_us : Double
low_pct : Double
high_pct : Double
}
///|
pub fn DeltaInterval::new(
low_us : Double,
high_us : Double,
low_pct : Double,
high_pct : Double,
) -> DeltaInterval {
{ low_us, high_us, low_pct, high_pct, }
}
///|
/// The paired comparison of one candidate against the baseline at one scale
/// of one case.
pub struct ComparisonRow {
case_id : String
scale : String
baseline : String
candidate : String
decision : ComparisonDecision
/// Why the decision is `Unknown` or `Invalid`; empty otherwise.
reason : String
/// `None` when no block was used.
estimate : PairedEstimate?
/// `None` when the bootstrap did not run.
interval : DeltaInterval?
/// Complete blocks that entered the comparison.
blocks_used : Int32
/// Blocks without exactly one observation of both implementations.
blocks_incomplete : Int32
/// Complete blocks removed by the outlier policy.
blocks_outliers : Int32
/// Bootstrap seed of this row.
seed : UInt64
}
///|
pub fn ComparisonRow::new(
case_id : String,
scale : String,
baseline : String,
candidate : String,
decision : ComparisonDecision,
reason : String,
estimate : PairedEstimate?,
interval : DeltaInterval?,
blocks_used : Int32,
blocks_incomplete : Int32,
blocks_outliers : Int32,
seed : UInt64,
) -> ComparisonRow {
{
case_id,
scale,
baseline,
candidate,
decision,
reason,
estimate,
interval,
blocks_used,
blocks_incomplete,
blocks_outliers,
seed,
}
}
///|
/// The paired comparisons of a report and the settings they were made with.
pub struct ComparisonReport {
rows : Array[ComparisonRow]
practical_delta_pct : Double
/// `OutlierPolicy::text()` of the policy applied to the paired deltas.
outlier_policy : String
confidence_pct : Double
resamples : Int32
/// Fewest used blocks for which a decision is made.
min_blocks : Int32
run_seed : UInt64
/// Whether `practical_delta_pct` and `outlier_policy` come from the record.
protocol_recorded : Bool
/// Whether `run_seed` comes from the record.
seed_recorded : Bool
/// One-line, human-readable statement of the settings and their sources.
note : String
}
///|
pub fn ComparisonReport::new(
rows : Array[ComparisonRow],
practical_delta_pct : Double,
outlier_policy : String,
confidence_pct : Double,
resamples : Int32,
min_blocks : Int32,
run_seed : UInt64,
protocol_recorded : Bool,
seed_recorded : Bool,
note : String,
) -> ComparisonReport {
{
rows,
practical_delta_pct,
outlier_policy,
confidence_pct,
resamples,
min_blocks,
run_seed,
protocol_recorded,
seed_recorded,
note,
}
}
///|
/// No comparisons and an empty note.
pub fn ComparisonReport::empty() -> ComparisonReport {
ComparisonReport::new([], 0.0, "", 0.0, 0, 0, 0UL, false, false, "")
}