tiny.profiling.analyze.render
Defined in analyze.
API (6)
Actions
Public operations.
expectRepeatedMeasurementJsonwriteCapturePerturbationsJsonwriteCapturesJsonwriteCausalJsonwriteJsonwriteText
Source
Source: src/profiling/analyze/render.zig
zig
const std = @import("std");const capture = @import("capture");const pretty = @import("pretty");const pretty_usage = @import("pretty_usage");const baseline = @import("../root.zig").baseline;const budget = @import("../root.zig").budget;const coz = @import("../capture/root.zig").coz;const environment = @import("../root.zig").environment;const json = @import("../root.zig").json;const measurement = @import("../root.zig").measurement;const memory = @import("../root.zig").memory;const metric = @import("../root.zig").metric;const order = @import("../root.zig").order;const perturbation = @import("../root.zig").perturbation;const priority = @import("../root.zig").priority;const reducer = @import("../root.zig").reduction;const pretty_json = pretty.json;const Comparison = @import("root.zig").model.Comparison;const ComparisonSupport = @import("root.zig").model.ComparisonSupport;const CounterShift = @import("root.zig").model.CounterShift;const EnergyShift = @import("root.zig").model.EnergyShift;const NamedCapture = @import("root.zig").model.NamedCapture;const Options = @import("root.zig").model.Options;const OrderEffectRow = @import("root.zig").model.OrderEffectRow;const OrderEffectSupport = @import("root.zig").model.OrderEffectSupport;const OrderEffects = @import("root.zig").model.OrderEffects;const Run = @import("root.zig").model.Run;const Workload = @import("root.zig").model.Workload;const WorkloadComparisonSkip = @import("root.zig").model.WorkloadComparisonSkip;const WorkloadComparisonSupport = @import("root.zig").model.WorkloadComparisonSupport;const comparisonEvidence = @import("root.zig").evidence.comparisonEvidence;const comparisonSupport = @import("root.zig").compare.comparisonSupport;const flattenCaptures = @import("root.zig").evidence.flattenCaptures;const flattenCausal = @import("root.zig").evidence.flattenCausal;const missingWorkloads = @import("root.zig").compare.missingWorkloads;const orderEffectTestFixture = @import("fixture/root.zig").orderEffectTestFixture;const outliersByRss = @import("root.zig").evidence.outliersByRss;const outliersByWall = @import("root.zig").evidence.outliersByWall;const sortedByRss = @import("root.zig").evidence.sortedByRss;const sortedByWall = @import("root.zig").evidence.sortedByWall;const workloadWallDistribution = @import("root.zig").model.workloadWallDistribution;const workload_wall_statistic = @import("root.zig").model.workload_wall_statistic;fn writeUnsupportedComparisonText( terminal: pretty_usage.Terminal, base: Run, candidate: Run,) !void { const support = comparisonSupport(base, candidate); switch (support) { .supported => unreachable, .missing_optimize => try terminal.writeText( "comparison: unsupported; build optimization mode is missing from one or both runs\n", ), .optimize_mismatch => try terminal.writeTextFmt( "comparison: unsupported; build optimization differs ({s} baseline, {s} candidate)\n", .{ base.optimize.?, candidate.optimize.? }, ), .missing_host => try terminal.writeText( "comparison: unsupported; host OS, architecture, or logical CPU count " ++ "is missing from one or both runs\n", ), else => try writeUnsupportedHostComparisonText(terminal, base, candidate, support), }}fn writeUnsupportedHostComparisonText( terminal: pretty_usage.Terminal, base: Run, candidate: Run, support: ComparisonSupport,) !void { switch (support) { .supported, .missing_optimize, .optimize_mismatch, .missing_host => unreachable, .os_mismatch => try writeHostFieldMismatchText( terminal, "host OS", base.host.os, candidate.host.os, ), .arch_mismatch => try writeHostFieldMismatchText( terminal, "host architecture", base.host.arch, candidate.host.arch, ), .cpu_count_mismatch => try terminal.writeTextFmt( "comparison: unsupported; logical CPU count differs ({d} baseline, {d} candidate)\n", .{ base.host.cpu_count.?, candidate.host.cpu_count.? }, ), .hostname_mismatch => try writeHostFieldMismatchText( terminal, "hostname", base.host.hostname, candidate.host.hostname, ), .kernel_mismatch => try writeHostFieldMismatchText( terminal, "kernel release", base.host.kernel, candidate.host.kernel, ), .cpu_model_mismatch => try writeHostFieldMismatchText( terminal, "CPU model", base.host.cpu_model, candidate.host.cpu_model, ), .cpu_frequency_policy_missing => try terminal.writeText( "comparison: unsupported; CPU frequency policy is missing from one or both runs\n", ), .cpu_frequency_policy_mismatch => try writeHostFieldMismatchText( terminal, "CPU frequency policy", base.host.cpu_frequency_policy, candidate.host.cpu_frequency_policy, ), .process_cpu_affinity_missing, .process_cpu_affinity_mismatch, .process_memory_affinity_missing, .process_memory_affinity_mismatch, => try writeUnsupportedAffinityComparisonText(terminal, base, candidate, support), }}fn writeUnsupportedAffinityComparisonText( terminal: pretty_usage.Terminal, base: Run, candidate: Run, support: ComparisonSupport,) !void { switch (support) { .process_cpu_affinity_missing => try terminal.writeText( "comparison: unsupported; process CPU affinity is missing from one or both runs\n", ), .process_cpu_affinity_mismatch => try writeHostFieldMismatchText( terminal, "process CPU affinity", base.host.process_cpu_affinity, candidate.host.process_cpu_affinity, ), .process_memory_affinity_missing => try terminal.writeText( "comparison: unsupported; process memory-node affinity is missing " ++ "from one or both runs\n", ), .process_memory_affinity_mismatch => try writeHostFieldMismatchText( terminal, "process memory-node affinity", base.host.process_memory_affinity, candidate.host.process_memory_affinity, ), else => unreachable, }}fn writeHostFieldMismatchText( terminal: pretty_usage.Terminal, field: []const u8, baseline_value: ?[]const u8, candidate_value: ?[]const u8,) !void { try terminal.writeTextFmt( "comparison: unsupported; {s} differs ({s} baseline, {s} candidate)\n", .{ field, baseline_value orelse "missing", candidate_value orelse "missing" }, );}fn writeComparisonSupportJson( out: *pretty_json.Writer, base: Run, candidate: Run,) !void { const support = comparisonSupport(base, candidate); try out.beginObject(); try out.objectField("state"); try out.write(@tagName(support)); try out.objectField("supported"); try out.write(support == .supported); try out.objectField("baseline_optimize"); try out.write(base.optimize); try out.objectField("candidate_optimize"); try out.write(candidate.optimize); try out.objectField("baseline_host"); try environment.writeJson(out, base.host); try out.objectField("candidate_host"); try environment.writeJson(out, candidate.host); try out.endObject();}pub fn writeText(allocator: std.mem.Allocator, terminal: pretty_usage.Terminal, candidate: Run, baseline_run: ?Run, options: Options) !void { const missing = try missingWorkloads(allocator, candidate); const slowest = try sortedByWall(allocator, candidate.workloads); const largest = try sortedByRss(allocator, candidate.workloads); const wall_outliers = try outliersByWall(allocator, candidate.workloads); const rss_outliers = try outliersByRss(allocator, candidate.workloads); const causal = try flattenCausal(allocator, candidate); const captured = try flattenCaptures(allocator, candidate); const evidence = try comparisonEvidence( allocator, candidate, baseline_run, options.regression_threshold_percent, causal, ); const order_effects = evidence.order_effects; const comparisons = evidence.workload; const workload_comparison_skips = evidence.skips; const metric_comparisons = evidence.metrics; const memory_comparisons = evidence.memory_metrics; const allocation_budget_checks = evidence.allocation_budgets; const energy_shifts = evidence.energy; const counter_shifts = evidence.counters; const priority_report = evidence.priority_report; try terminal.writeTextFmt("profile analysis: {s}\n", .{candidate.ref.run_id}); try terminal.writeTextFmt("artifacts: {s}\n", .{candidate.ref.root}); try terminal.writeTextFmt("optimize: {s}\n", .{candidate.optimize orelse "unknown"}); try writeHostText(terminal, candidate.host); try terminal.writeTextFmt("workloads: ran {d}, passed {d}, failed {d}, missing {d}, structured metrics {d}, memory metrics {d}\n", .{ candidate.ran(), candidate.passed(), candidate.failed(), missing.len, candidate.metricCount(), candidate.memoryMetricCount() }); try writeStructuredAnalysisCaveats(terminal, candidate.workloads); try writeCapturePerturbationsText(terminal, candidate.workloads); try writeCausalText(terminal, causal, options.top); try writeCapturesText(terminal, captured); try writeAllocationBudgetChecksText(terminal, allocation_budget_checks); if (candidate.failed() != 0) { try terminal.writeText("failures:\n"); for (candidate.workloads) |workload| { if (workload.exit_code != 0) try terminal.writeTextFmt(" {s}: exit {d}\n", .{ workload.name, workload.exit_code }); } } if (missing.len != 0) { try terminal.writeText("missing:\n"); for (missing) |name| try terminal.writeTextFmt(" {s}\n", .{name}); } try terminal.writeText("slowest mean execution wall:\n"); try writeRankedWallText(terminal, candidate.workloads, slowest, @min(options.top, slowest.len)); try terminal.writeText("highest memory:\n"); try writeRankedRssText(terminal, candidate.workloads, largest, @min(options.top, largest.len)); if (wall_outliers.len != 0 or rss_outliers.len != 0) { try terminal.writeText("outliers:\n"); for (wall_outliers) |index| try terminal.writeTextFmt(" mean wall {s}: {d} ns\n", .{ candidate.workloads[index].name, candidate.workloads[index].wall_ns }); for (rss_outliers) |index| if (candidate.workloads[index].max_rss_kib) |rss| try terminal.writeTextFmt(" rss {s}: {d} KiB\n", .{ candidate.workloads[index].name, rss }); } if (baseline_run) |base| { try terminal.writeTextFmt("baseline: {s}\n", .{base.ref.run_id}); if (order_effects) |effects| try writeOrderEffectsText(terminal, effects); if (comparisonSupport(base, candidate) != .supported) { try writeUnsupportedComparisonText(terminal, base, candidate); return; } if (comparisons.len == 0) { try terminal.writeText("regressions: none above threshold among supported workload comparisons\n"); } else { try terminal.writeText("regressions:\n"); for (comparisons) |row| { try terminal.writeTextFmt(" {s}: {s} mean wall {d}->{d} ns ({d:.2}%)", .{ row.kind, row.workload, row.baseline_wall_ns, row.candidate_wall_ns, row.wall_percent_change }); if (std.mem.indexOf(u8, row.kind, "wall") != null) { try terminal.writeTextFmt( ", {s}, samples {d}->{d} ({s}->{s})", .{ row.wall_status, row.baseline_wall_samples, row.candidate_wall_samples, row.baseline_wall_distribution, row.candidate_wall_distribution, }, ); if (row.wall_effect_low_percent != null and row.wall_effect_high_percent != null) { try terminal.writeTextFmt( ", 95% effect {d:.2}..{d:.2}%", .{ row.wall_effect_low_percent.?, row.wall_effect_high_percent.?, }, ); } } if (row.rss_percent_change) |rss_change| try terminal.writeTextFmt(", rss {d:.2}%", .{rss_change}); try terminal.writeText("\n"); } } if (workload_comparison_skips.len != 0) { try terminal.writeText("workload comparisons skipped:\n"); for (workload_comparison_skips) |row| { try writeWorkloadComparisonSkipText(terminal, row); } } if (metric_comparisons.len == 0) { try terminal.writeText("metric regressions: none above threshold\n"); } else { try terminal.writeText("metric regressions:\n"); for (metric_comparisons) |row| { try terminal.writeTextFmt(" {s}: {s} {d:.2}->{d:.2} ns ({d:.2}%, threshold {d:.2}%, {s}/{s}", .{ row.status, row.label, row.baseline_ns, row.candidate_ns, row.percent_change, row.threshold_percent, row.baseline_distribution.name(), row.candidate_distribution.name(), }); if (row.effect_low_percent != null or row.effect_high_percent != null) { try terminal.writeTextFmt(", effect {d:.2}..{d:.2}%", .{ row.effect_low_percent orelse 0, row.effect_high_percent orelse 0 }); } try terminal.writeText(")\n"); } } if (memory_comparisons.len == 0) { try terminal.writeText("memory regressions: none above threshold\n"); } else { try terminal.writeText("memory regressions:\n"); for (memory_comparisons) |row| { try terminal.writeTextFmt( " {s}: {s} {d:.2}->{d:.2} {s} " ++ "({d:.2}%, threshold {d:.2}%, {s}/{s}, {d}/{d} samples", .{ row.status, row.label, row.baseline_value, row.candidate_value, row.unit.name(), row.percent_change, row.threshold_percent, row.baseline_distribution.name(), row.candidate_distribution.name(), row.baseline_samples, row.candidate_samples, }, ); try terminal.writeTextFmt(", {s} budget", .{row.budget_kind.name()}); if (row.effect_low_percent != null and row.effect_high_percent != null) { try terminal.writeTextFmt( ", effect {d:.2}..{d:.2}%", .{ row.effect_low_percent.?, row.effect_high_percent.?, }, ); } try terminal.writeText(")\n"); } } try writeEnergyShiftsText(terminal, energy_shifts); try writeCounterShiftsText(terminal, counter_shifts); try writePriorityText(terminal, priority_report, options.top); }}fn writeStructuredAnalysisCaveats( terminal: pretty_usage.Terminal, workloads: []const Workload,) !void { for (workloads) |workload| { if (workload.executions.len < 2 or workload.benchmark_process_reduction != .not_applicable) { continue; } try terminal.writeTextFmt( "structured analysis {s}: benchmark process reduction {s}\n", .{ workload.name, @tagName(workload.benchmark_process_reduction.not_applicable.reason), }, ); }}fn writeHostText(terminal: pretty_usage.Terminal, value: environment.Host) !void { try terminal.writeTextFmt( "host: {s}, {s} {s}, {s}, {d} logical CPU(s)", .{ value.hostname orelse "unknown", value.os orelse "unknown", value.kernel orelse "unknown", value.arch orelse "unknown", value.cpu_count orelse 0, }, ); if (value.cpu_model) |model| try terminal.writeTextFmt(", {s}", .{model}); if (value.process_cpu_affinity) |affinity| { try terminal.writeTextFmt(", process CPUs {s}", .{affinity}); } if (value.process_memory_affinity) |affinity| { try terminal.writeTextFmt(", memory nodes {s}", .{affinity}); } try terminal.writeText("\n"); if (value.cpu_frequency_policy) |policy| { try terminal.writeTextFmt("frequency policy: {s}\n", .{policy}); }}fn writeRankedWallText(terminal: pretty_usage.Terminal, workloads: []const Workload, indices: []const usize, count: usize) !void { var index: usize = 0; while (index < count) : (index += 1) { const workload = workloads[indices[index]]; try terminal.writeTextFmt(" {d}. {s}: {d} ns mean", .{ index + 1, workload.name, workload.wall_ns }); if (workload.execution_count > 1) { try terminal.writeTextFmt( " across {d} executions, {d} ns acquisition total", .{ workload.execution_count, workload.total_wall_ns }, ); } if (workload.warmup_count != 0) { try terminal.writeTextFmt( ", {d} unmeasured warmup(s), {d} ns warmup total", .{ workload.warmup_count, workload.warmup_total_wall_ns }, ); } try writeWallDistributionText(terminal, workloadWallDistribution(workload)); if (workload.max_rss_kib) |rss| try terminal.writeTextFmt(", {d} KiB", .{rss}); try terminal.writeText("\n"); } try writeProcessResourcesText(terminal, workloads, indices, count);}fn writeWallDistributionText( terminal: pretty_usage.Terminal, distribution: measurement.WallDistribution,) !void { if (distribution.median_ns != null and distribution.p95_ns != null and distribution.stddev_ns != null) { try terminal.writeTextFmt( ", {s} {d} sample(s), median {d:.2} ns, p95 {d:.2} ns, stddev {d:.2} ns", .{ distribution.kind.name(), distribution.sample_count, distribution.median_ns.?, distribution.p95_ns.?, distribution.stddev_ns.?, }, ); if (distribution.coefficient_of_variation_percent) |cv| { try terminal.writeTextFmt(", CV {d:.2}%", .{cv}); } if (distribution.min_ns != null and distribution.max_ns != null) { try terminal.writeTextFmt( ", range {d:.2}..{d:.2} ns", .{ distribution.min_ns.?, distribution.max_ns.? }, ); } return; } try terminal.writeTextFmt( ", {s} {d} sample(s), spread unavailable", .{ distribution.kind.name(), distribution.sample_count }, );}fn writeRankedRssText(terminal: pretty_usage.Terminal, workloads: []const Workload, indices: []const usize, count: usize) !void { var index: usize = 0; while (index < count) : (index += 1) { const workload = workloads[indices[index]]; try terminal.writeTextFmt(" {d}. {s}: ", .{ index + 1, workload.name }); if (workload.max_rss_kib) |rss| { try terminal.writeTextFmt("{d} KiB, {d} ns mean wall\n", .{ rss, workload.wall_ns }); } else { try terminal.writeTextFmt("unknown, {d} ns mean wall\n", .{workload.wall_ns}); } }}fn writeProcessResourcesText( terminal: pretty_usage.Terminal, workloads: []const Workload, indices: []const usize, count: usize,) !void { var heading = false; for (indices[0..count], 0..) |workload_index, rank| { const workload = workloads[workload_index]; const source = workload.resource_usage_source orelse continue; if (!heading) { try terminal.writeText("waited-command resources:\n"); heading = true; } try terminal.writeTextFmt( " {d}. {s}: {s}", .{ rank + 1, workload.name, @tagName(source) }, ); try writeSwitchResourcesText(terminal, workload); try writeFaultResourcesText(terminal, workload); try terminal.writeText("\n"); }}fn writeSwitchResourcesText(terminal: pretty_usage.Terminal, workload: Workload) !void { const voluntary = workload.voluntary_context_switches orelse return; const involuntary = workload.involuntary_context_switches orelse return; try terminal.writeTextFmt( ", mean switches {d:.2} voluntary + {d:.2} involuntary", .{ voluntary, involuntary }, ); if (ratePerSecond(voluntary + involuntary, workload.wall_ns)) |rate| { try terminal.writeTextFmt(" ({d:.2}/s process rate)", .{rate}); }}fn writeFaultResourcesText(terminal: pretty_usage.Terminal, workload: Workload) !void { const minor = workload.minor_page_faults orelse return; const major = workload.major_page_faults orelse return; try terminal.writeTextFmt( ", mean faults {d:.2} minor + {d:.2} major", .{ minor, major }, ); if (ratePerSecond(minor + major, workload.wall_ns)) |rate| { try terminal.writeTextFmt(" ({d:.2}/s process rate)", .{rate}); }}fn ratePerSecond(value: f64, wall_ns: u64) ?f64 { if (wall_ns == 0) return null; return value * @as(f64, std.time.ns_per_s) / @as(f64, @floatFromInt(wall_ns));}pub fn writeJson(allocator: std.mem.Allocator, writer: *std.Io.Writer, candidate: Run, baseline_run: ?Run, options: Options) !void { const missing = try missingWorkloads(allocator, candidate); const slowest = try sortedByWall(allocator, candidate.workloads); const largest = try sortedByRss(allocator, candidate.workloads); const wall_outliers = try outliersByWall(allocator, candidate.workloads); const rss_outliers = try outliersByRss(allocator, candidate.workloads); const causal = try flattenCausal(allocator, candidate); const captured = try flattenCaptures(allocator, candidate); const evidence = try comparisonEvidence( allocator, candidate, baseline_run, options.regression_threshold_percent, causal, ); const order_effects = evidence.order_effects; const comparisons = evidence.workload; const workload_comparison_skips = evidence.skips; const metric_comparisons = evidence.metrics; const memory_comparisons = evidence.memory_metrics; const allocation_budget_checks = evidence.allocation_budgets; const energy_shifts = evidence.energy; const counter_shifts = evidence.counters; const priority_report = evidence.priority_report; var out = pretty_json.Writer.init(writer, .minified); try out.beginObject(); try out.objectField("schema"); try out.write("tiny.profiling.analysis/v1"); try out.objectField("candidate"); try writeRunJson(&out, candidate); try out.objectField("workload_measurements"); try writeWorkloadMeasurementsJson(&out, candidate.workloads); try out.objectField("missing"); try writeStringsJson(&out, missing); try out.objectField("slowest"); try writeRankedJson(&out, candidate.workloads, slowest, @min(options.top, slowest.len), "wall"); try out.objectField("highest_memory"); try writeRankedJson(&out, candidate.workloads, largest, @min(options.top, largest.len), "rss"); try out.objectField("outliers"); try writeOutliersJson(&out, candidate.workloads, wall_outliers, rss_outliers); try out.objectField("causal"); try writeCausalJson(&out, causal); try out.objectField("captures"); try writeCapturesJson(&out, captured); try out.objectField("capture_perturbations"); try writeCapturePerturbationsJson(&out, candidate.workloads); try out.objectField("order_effects"); try writeOrderEffectsJson(&out, order_effects); try out.objectField("regressions"); try writeComparisonsJson(&out, comparisons); try out.objectField("workload_comparison_skips"); try writeWorkloadComparisonSkipsJson(&out, workload_comparison_skips); try out.objectField("metric_regressions"); try writeMetricComparisonsJson(&out, metric_comparisons); try out.objectField("allocation_budget_checks"); try writeAllocationBudgetChecksJson(&out, allocation_budget_checks); try out.objectField("memory_regressions"); try writeMemoryComparisonsJson(&out, memory_comparisons); try out.objectField("energy_shifts"); try writeEnergyShiftsJson(&out, energy_shifts); try out.objectField("counter_shifts"); try writeCounterShiftsJson(&out, counter_shifts); try out.objectField("priority"); try writePriorityJson(&out, priority_report); if (baseline_run) |base| { try out.objectField("baseline"); try writeRunJson(&out, base); try out.objectField("comparison_support"); try writeComparisonSupportJson(&out, base, candidate); } try out.endObject(); try writer.writeByte('\n');}fn writeOrderEffectsText( terminal: pretty_usage.Terminal, effects: OrderEffects,) !void { try terminal.writeTextFmt( "order effects: fixed {s} vs random {s}: {s}\n", .{ effects.fixed_run_id, effects.random_run_id, @tagName(effects.status) }, ); if (effects.support != .supported) { try terminal.writeTextFmt( " unsupported: {s}\n", .{orderEffectSupportReason(effects.support)}, ); } else { for (effects.rows) |row| { try terminal.writeTextFmt( " {s}: {d} fixed/{d} random sample(s), ", .{ row.workload, row.fixed_count, row.random_count }, ); if (row.fixed_mean_ns != null and row.random_mean_ns != null) { try terminal.writeTextFmt( "mean {d:.2}->{d:.2} ns", .{ row.fixed_mean_ns.?, row.random_mean_ns.? }, ); } else { try terminal.writeText("mean unavailable"); } if (row.mean_percent_change) |percent| { try terminal.writeTextFmt(", random vs fixed {d:.2}%", .{percent}); } if (row.effect_low_percent != null and row.effect_high_percent != null) { try terminal.writeTextFmt( ", 95% effect {d:.2}..{d:.2}%", .{ row.effect_low_percent.?, row.effect_high_percent.? }, ); } try terminal.writeTextFmt(", {s}\n", .{@tagName(row.classification)}); } } try terminal.writeText( " limit: one unreset fixed/random pair is diagnostic, not an OrderSage test\n" ++ " limit: blocked and interleaved setup/warmup placement differ\n" ++ " limit: zero-crossing intervals do not prove independence or absence\n", );}fn writeOrderEffectsJson( out: *pretty_json.Writer, effects_value: ?OrderEffects,) !void { const effects = effects_value orelse { try out.write(null); return; }; try out.beginObject(); try out.objectField("mode"); try out.write("fixed_vs_random_interleaved"); try out.objectField("support"); try out.beginObject(); try out.objectField("state"); try out.write(@tagName(effects.support)); try out.objectField("supported"); try out.write(effects.support == .supported); try out.objectField("reason"); try out.write(orderEffectSupportReason(effects.support)); try out.objectField("environment_state"); try out.write(@tagName(effects.environment_support)); try out.endObject(); try out.objectField("status"); try out.write(@tagName(effects.status)); try out.objectField("supports_ordersage_test"); try out.write(false); try out.objectField("fixed_run_id"); try out.write(effects.fixed_run_id); try out.objectField("random_run_id"); try out.write(effects.random_run_id); try out.objectField("fixed_is_baseline"); try out.write(effects.fixed_is_baseline); try out.objectField("reset_policy"); try out.write("none_recorded"); try out.objectField("effect_method"); try out.write(order.contrast.effect_method); try out.objectField("effect_bootstrap_iterations"); try out.write(capture.compare.effect.bootstrap_iterations); try out.objectField("effect_confidence_per_mille"); try out.write(capture.compare.effect.confidence_per_mille); try out.objectField("order_sensitive_workloads"); try out.write(orderSensitiveWorkloadCount(effects.rows)); try out.objectField("limits"); try writeOrderEffectLimitsJson(out, effects.support); try out.objectField("rows"); try writeOrderEffectRowsJson(out, effects.rows); try out.endObject();}fn writeOrderEffectRowsJson( out: *pretty_json.Writer, rows: []const OrderEffectRow,) !void { try out.beginArray(); for (rows) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("fixed_acquisition"); try order.writeJson(out, row.fixed_acquisition); try out.objectField("random_acquisition"); try order.writeJson(out, row.random_acquisition); try out.objectField("fixed_count"); try out.write(row.fixed_count); try out.objectField("random_count"); try out.write(row.random_count); try out.objectField("fixed_mean_ns"); try out.write(row.fixed_mean_ns); try out.objectField("random_mean_ns"); try out.write(row.random_mean_ns); try out.objectField("mean_percent_change"); try out.write(row.mean_percent_change); try out.objectField("effect_low_percent"); try out.write(row.effect_low_percent); try out.objectField("effect_high_percent"); try out.write(row.effect_high_percent); try out.objectField("classification"); try out.write(@tagName(row.classification)); try out.endObject(); } try out.endArray();}fn writeOrderEffectLimitsJson( out: *pretty_json.Writer, support: OrderEffectSupport,) !void { try out.beginArray(); if (support != .supported) try out.write(orderEffectSupportReason(support)); try out.write( "one unreset fixed/random run pair is diagnostic, not an OrderSage order-dependence test", ); try out.write("no reset procedure is recorded between runs"); try out.write( "blocked setup and warmup placement differs from interleaved setup and warmup placement", ); try out.write( "unpaired process samples do not establish independence; " ++ "a zero-crossing interval does not prove absence", ); try out.endArray();}fn orderSensitiveWorkloadCount(rows: []const OrderEffectRow) usize { var count: usize = 0; for (rows) |row| { if (row.classification == .order_sensitive_candidate) count += 1; } return count;}fn orderEffectSupportReason(support: OrderEffectSupport) []const u8 { return switch (support) { .supported => "fixed and random acquisition evidence is diagnostic-compatible", .environment_mismatch => "build optimization or host context differs", .code_identity_missing => "a known clean Git identity is missing", .code_identity_mismatch => "Git commits differ", .dirty_code_identity => "one or both runs used a dirty worktree", .cohort_mismatch => "selected workload cohorts differ or are incomplete", .workload_failure => "one or more workloads failed", .command_identity_missing => "a workload command identity is missing", .command_identity_mismatch => "workload commands differ", .execution_scope_missing => "an execution scope identity is missing", .execution_scope_mismatch => "execution scopes differ", .warmup_design_missing => "a warmup design identity is missing", .warmup_design_mismatch => "unmeasured process warmup counts differ", .profiler_configuration_missing => "a profiler capture configuration is missing", .profiler_capture_present => "profiler capture perturbation is present", .repetition_design_mismatch => "process repetition counts differ", .raw_measurements_missing => "at least two raw process measurements " ++ "per workload are required", };}fn writeCapturePerturbationsText( terminal: pretty_usage.Terminal, workloads: []const Workload,) !void { var wrote_heading = false; for (workloads) |workload| { const measurement_value = workload.capture_perturbation orelse continue; const summary = workload.capture_perturbation_summary orelse continue; if (!wrote_heading) { try terminal.writeText("capture perturbation:\n"); wrote_heading = true; } try terminal.writeTextFmt( " {s}: {s}, {d}/{d} matched pair(s)", .{ workload.name, summary.state, summary.pair_count, measurement_value.pairs.len }, ); try writeCaptureConfigurationText(terminal, measurement_value.configuration); if (summary.control_mean_ns != null and summary.capture_mean_ns != null) { try terminal.writeTextFmt( ", control {d:.2} -> capture {d:.2} ns", .{ summary.control_mean_ns.?, summary.capture_mean_ns.? }, ); } if (summary.mean_percent_change) |percent| { try terminal.writeTextFmt(", {d:.2}%", .{percent}); } if (summary.effect_low_percent != null and summary.effect_high_percent != null) { try terminal.writeTextFmt( ", 95% paired effect {d:.2}..{d:.2}%", .{ summary.effect_low_percent.?, summary.effect_high_percent.? }, ); } try terminal.writeText("\n"); }}fn writeCaptureConfigurationText( terminal: pretty_usage.Terminal, configuration: perturbation.Configuration,) !void { std.debug.assert(configuration.any()); try terminal.writeText(", active capture "); var wrote = false; if (configuration.host_kind) |kind| { try terminal.writeText(kind); wrote = true; } if (configuration.tracy) { if (wrote) try terminal.writeText("+"); try terminal.writeText("tracy"); wrote = true; } if (configuration.allocations) { if (wrote) try terminal.writeText("+"); try terminal.writeText("allocations"); }}pub fn writeCapturePerturbationsJson( out: *pretty_json.Writer, workloads: []const Workload,) !void { try out.beginArray(); for (workloads) |workload| { const measurement_value = workload.capture_perturbation orelse continue; const summary = workload.capture_perturbation_summary orelse continue; try out.beginObject(); try out.objectField("workload"); try out.write(workload.name); try out.objectField("method"); try out.write("same_build_matched_control_capture"); try out.objectField("effect_method"); try out.write(perturbation.effect_method); try out.objectField("effect_bootstrap_iterations"); try out.write(capture.compare.effect.bootstrap_iterations); try out.objectField("effect_confidence_per_mille"); try out.write(capture.compare.effect.confidence_per_mille); try out.objectField("measurement_state"); try out.write(@tagName(measurement_value.state)); try out.objectField("effect_state"); try out.write(summary.state); try out.objectField("pair_count_requested"); try out.write(measurement_value.pairs.len); try out.objectField("pair_count_complete"); try out.write(summary.pair_count); try out.objectField("base_seed"); try out.write(measurement_value.base_seed); try out.objectField("workload_seed"); try out.write(measurement_value.workload_seed); try out.objectField("active_host_kind"); try out.write(measurement_value.configuration.host_kind); try out.objectField("active_tracy"); try out.write(measurement_value.configuration.tracy); try out.objectField("active_allocations"); try out.write(measurement_value.configuration.allocations); try out.objectField("control_mean_ns"); try out.write(summary.control_mean_ns); try out.objectField("capture_mean_ns"); try out.write(summary.capture_mean_ns); try out.objectField("mean_delta_ns"); try out.write(summary.mean_delta_ns); try out.objectField("mean_percent_change"); try out.write(summary.mean_percent_change); try out.objectField("effect_low_percent"); try out.write(summary.effect_low_percent); try out.objectField("effect_high_percent"); try out.write(summary.effect_high_percent); try out.endObject(); } try out.endArray();}fn writeRunJson(out: *pretty_json.Writer, run_value: Run) !void { try out.beginObject(); try out.objectField("run_id"); try out.write(run_value.ref.run_id); try out.objectField("root"); try out.write(run_value.ref.root); try out.objectField("results"); try out.write(run_value.ref.results_path); try out.objectField("git_commit"); try out.write(run_value.git_sha); try out.objectField("git_dirty"); try out.write(run_value.git_dirty); try out.objectField("optimize"); try out.write(run_value.optimize); try out.objectField("host"); try environment.writeJson(out, run_value.host); try out.objectField("ran"); try out.write(run_value.ran()); try out.objectField("passed"); try out.write(run_value.passed()); try out.objectField("failed"); try out.write(run_value.failed()); try out.objectField("structured_metrics"); try out.write(run_value.metricCount()); try out.objectField("memory_metrics"); try out.write(run_value.memoryMetricCount()); try out.objectField("workload_wall_statistic"); try out.write(workload_wall_statistic); try out.endObject();}fn writeComparisonsJson(out: *pretty_json.Writer, comparisons: []const Comparison) !void { try out.beginArray(); for (comparisons) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("kind"); try out.write(row.kind); try out.objectField("wall_statistic"); try out.write(workload_wall_statistic); try out.objectField("baseline_wall_ns"); try out.write(row.baseline_wall_ns); try out.objectField("candidate_wall_ns"); try out.write(row.candidate_wall_ns); try out.objectField("wall_percent_change"); try out.write(row.wall_percent_change); try out.objectField("wall_threshold_percent"); try out.write(row.wall_threshold_percent); try out.objectField("baseline_wall_samples"); try out.write(row.baseline_wall_samples); try out.objectField("candidate_wall_samples"); try out.write(row.candidate_wall_samples); try out.objectField("baseline_wall_distribution"); try out.write(row.baseline_wall_distribution); try out.objectField("candidate_wall_distribution"); try out.write(row.candidate_wall_distribution); try out.objectField("wall_status"); try out.write(row.wall_status); try out.objectField("wall_effect_low_percent"); try out.write(row.wall_effect_low_percent); try out.objectField("wall_effect_high_percent"); try out.write(row.wall_effect_high_percent); try out.objectField("wall_effect_method"); try out.write(if (row.wall_effect_low_percent != null) measurement.wall_effect_method else null); try out.objectField("wall_effect_bootstrap_iterations"); try out.write(if (row.wall_effect_low_percent != null) @as(?u32, capture.compare.effect.bootstrap_iterations) else null); try out.objectField("wall_effect_confidence_per_mille"); try out.write(if (row.wall_effect_low_percent != null) @as(?u16, capture.compare.effect.confidence_per_mille) else null); try out.objectField("baseline_max_rss_kib"); try out.write(row.baseline_max_rss_kib); try out.objectField("candidate_max_rss_kib"); try out.write(row.candidate_max_rss_kib); try out.objectField("rss_percent_change"); try out.write(row.rss_percent_change); try out.objectField("rss_threshold_percent"); try out.write(row.rss_threshold_percent); try out.endObject(); } try out.endArray();}fn writeWorkloadComparisonSkipText( terminal: pretty_usage.Terminal, row: WorkloadComparisonSkip,) !void { try terminal.writeTextFmt( " {s}: {s} ({d} baseline/{d} candidate execution(s), {d} baseline/{d} candidate warmup(s))\n", .{ row.workload, workloadComparisonSupportReason(row.support), row.baseline_execution_count, row.candidate_execution_count, row.baseline_warmup_count, row.candidate_warmup_count, }, ); if (row.support == .measurement_order_mismatch) { try writeAcquisitionText(terminal, "baseline", row.baseline_acquisition); try writeAcquisitionText(terminal, "candidate", row.candidate_acquisition); }}fn writeAcquisitionText( terminal: pretty_usage.Terminal, label: []const u8, acquisition: order.Context,) !void { std.debug.assert(acquisition.valid()); switch (acquisition) { .blocked => |blocked| { try terminal.writeTextFmt( " {s} acquisition: blocked position {d}/{d}, predecessors [", .{ label, blocked.position, blocked.workload_count }, ); for (blocked.predecessors, 0..) |name, index| { if (index != 0) try terminal.writeText(", "); try terminal.writeText(name); } try terminal.writeText("]\n"); }, .random_interleaved => |interleaved| { try terminal.writeTextFmt( " {s} acquisition: random_interleaved seed {d}, {d} workload(s) x {d} repetitions, {s}, positions [", .{ label, interleaved.seed, interleaved.workload_count, interleaved.repeat_count, order.schedule_algorithm, }, ); for (interleaved.positions, 0..) |position, index| { if (index != 0) try terminal.writeText(", "); try terminal.writeTextFmt("{d}", .{position}); } try terminal.writeText("]\n"); try terminal.writeTextFmt( " setup {s}; warmup {s}; failure {s}\n", .{ order.setup_order, order.warmup_placement, order.failure_policy }, ); }, }}fn writeWorkloadComparisonSkipsJson( out: *pretty_json.Writer, rows: []const WorkloadComparisonSkip,) !void { try out.beginArray(); for (rows) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("state"); try out.write(@tagName(row.support)); try out.objectField("reason"); try out.write(workloadComparisonSupportReason(row.support)); try out.objectField("baseline_acquisition"); try order.writeJson(out, row.baseline_acquisition); try out.objectField("candidate_acquisition"); try order.writeJson(out, row.candidate_acquisition); try out.objectField("baseline_execution_count"); try out.write(row.baseline_execution_count); try out.objectField("candidate_execution_count"); try out.write(row.candidate_execution_count); try out.objectField("baseline_warmup_count"); try out.write(row.baseline_warmup_count); try out.objectField("candidate_warmup_count"); try out.write(row.candidate_warmup_count); try out.endObject(); } try out.endArray();}fn workloadComparisonSupportReason( support: WorkloadComparisonSupport,) []const u8 { return switch (support) { .supported => "measurement designs are comparable", .scope_mismatch => "execution scopes differ", .measurement_order_mismatch => "measurement acquisition designs differ", .warmup_design_mismatch => "unmeasured process warmup counts differ", .capture_mismatch => "profiler capture designs differ", .capture_perturbation_mismatch => "capture-control designs differ", .perf_stat_summary_missing => "perf-stat measurement design is missing", .perf_stat_events_mismatch => "perf-stat event sets differ", .perf_stat_groups_mismatch => "perf-stat event groups differ", .perf_stat_design_mismatch => "perf-stat repetition or execution design differs", };}fn writeMetricComparisonsJson(out: *pretty_json.Writer, comparisons: []const metric.Comparison) !void { try out.beginArray(); for (comparisons) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("key"); try out.write(row.key); try out.objectField("label"); try out.write(row.label); try out.objectField("status"); try out.write(row.status); try out.objectField("baseline_ns"); try out.write(row.baseline_ns); try out.objectField("candidate_ns"); try out.write(row.candidate_ns); try out.objectField("percent_change"); try out.write(row.percent_change); try out.objectField("threshold_percent"); try out.write(row.threshold_percent); try out.objectField("baseline_samples"); try out.write(row.baseline_samples); try out.objectField("candidate_samples"); try out.write(row.candidate_samples); try out.objectField("baseline_distribution"); try out.write(row.baseline_distribution.name()); try out.objectField("candidate_distribution"); try out.write(row.candidate_distribution.name()); try out.objectField("effect_low_percent"); try out.write(row.effect_low_percent); try out.objectField("effect_high_percent"); try out.write(row.effect_high_percent); try out.endObject(); } try out.endArray();}fn writeMemoryComparisonsJson(out: *pretty_json.Writer, comparisons: []const memory.Comparison) !void { try out.beginArray(); for (comparisons) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("key"); try out.write(row.key); try out.objectField("label"); try out.write(row.label); try out.objectField("status"); try out.write(row.status); try out.objectField("budget_kind"); try out.write(row.budget_kind.name()); try out.objectField("unit"); try out.write(row.unit.name()); try out.objectField("baseline_value"); try out.write(row.baseline_value); try out.objectField("candidate_value"); try out.write(row.candidate_value); try out.objectField("percent_change"); try out.write(row.percent_change); try out.objectField("threshold_percent"); try out.write(row.threshold_percent); try out.objectField("baseline_samples"); try out.write(row.baseline_samples); try out.objectField("candidate_samples"); try out.write(row.candidate_samples); try out.objectField("baseline_distribution"); try out.write(row.baseline_distribution.name()); try out.objectField("candidate_distribution"); try out.write(row.candidate_distribution.name()); try out.objectField("effect_low_percent"); try out.write(row.effect_low_percent); try out.objectField("effect_high_percent"); try out.write(row.effect_high_percent); try out.objectField("effect_method"); try out.write(memory.effect_method); try out.objectField("effect_bootstrap_iterations"); try out.write(memory.effect_bootstrap_iterations); try out.objectField("effect_confidence_per_mille"); try out.write(memory.effect_confidence_per_mille); try out.endObject(); } try out.endArray();}fn writeAllocationBudgetChecksText( terminal: pretty_usage.Terminal, checks: []const budget.Check,) !void { if (checks.len == 0) return; try terminal.writeText("allocation budgets:\n"); for (checks) |check| { try terminal.writeTextFmt( " {s}: {s}, gate {s}, baseline {s}, budget {d:.2}%, " ++ "metrics {d}->{d}, comparable {d}, violations {d}", .{ check.workload, @tagName(check.status), check.gate().name(), @tagName(check.baseline_policy), check.budget_percent, check.baseline_metrics, check.candidate_metrics, check.comparable_metrics, check.violations, }, ); if (check.zero_baseline_violations != 0) { try terminal.writeTextFmt( ", zero-baseline violations {d}", .{check.zero_baseline_violations}, ); } try terminal.writeText("\n"); }}fn writeAllocationBudgetChecksJson( out: *pretty_json.Writer, checks: []const budget.Check,) !void { try out.beginArray(); for (checks) |check| { try out.beginObject(); try out.objectField("workload"); try out.write(check.workload); try out.objectField("baseline_policy"); try out.write(@tagName(check.baseline_policy)); try out.objectField("budget_percent"); try out.write(check.budget_percent); try out.objectField("baseline_metrics"); try out.write(check.baseline_metrics); try out.objectField("candidate_metrics"); try out.write(check.candidate_metrics); try out.objectField("comparable_metrics"); try out.write(check.comparable_metrics); try out.objectField("violations"); try out.write(check.violations); try out.objectField("zero_baseline_violations"); try out.write(check.zero_baseline_violations); try out.objectField("status"); try out.write(@tagName(check.status)); try out.objectField("gate"); try out.write(check.gate().name()); try out.endObject(); } try out.endArray();}fn writeCausalText(terminal: pretty_usage.Terminal, causal: []const coz.Result, top: usize) !void { if (causal.len == 0) { try terminal.writeText("causal: none captured\n"); return; } try terminal.writeText("causal:\n"); const count = @min(top, causal.len); for (causal[0..count]) |result| { try terminal.writeTextFmt(" {s} {s}:{d} via {s} ({s}): max program speedup {d:.1}%", .{ result.workload, result.file, result.line, result.progress_point, result.kind, result.max_program_speedup * 100, }); if (result.slope) |slope| try terminal.writeTextFmt(", slope {d:.2}", .{slope}); try terminal.writeTextFmt( ", support {s}, experiments {d} ({d} baseline, {d}/point), " ++ "points {d}, samples {d}\n", .{ @tagName(result.support.status), result.support.experiment_count, result.support.baseline_experiment_count, result.support.minimum_experiments_per_point, result.support.speedup_point_count, result.total_selected_samples, }, ); }}pub fn writeCausalJson(out: *pretty_json.Writer, causal: []const coz.Result) !void { try out.beginArray(); for (causal) |result| { try out.beginObject(); try out.objectField("workload"); try out.write(result.workload); try out.objectField("kind"); try out.write(result.kind); try out.objectField("file"); try out.write(result.file); try out.objectField("line"); try out.write(result.line); try out.objectField("progress_point"); try out.write(result.progress_point); try out.objectField("min_program_speedup"); try out.write(result.min_program_speedup); try out.objectField("max_program_speedup"); try out.write(result.max_program_speedup); try out.objectField("slope"); try out.write(result.slope); try out.objectField("total_selected_samples"); try out.write(result.total_selected_samples); try out.objectField("support"); try writeCausalSupportJson(out, result.support); try out.objectField("measurements"); try out.write(result.measurements.len); try out.endObject(); } try out.endArray();}fn writeCausalSupportJson(out: *pretty_json.Writer, support: coz.Support) !void { try out.beginObject(); try out.objectField("status"); try out.write(@tagName(support.status)); try out.objectField("method"); try out.write(coz.support_method); try out.objectField("action"); try out.write(coz.supportAction(support.status)); try out.objectField("speedup_point_count"); try out.write(support.speedup_point_count); try out.objectField("experiment_count"); try out.write(support.experiment_count); try out.objectField("baseline_experiment_count"); try out.write(support.baseline_experiment_count); try out.objectField("minimum_experiments_per_point"); try out.write(support.minimum_experiments_per_point); try out.endObject();}fn writeCapturesText(terminal: pretty_usage.Terminal, captured: []const NamedCapture) !void { if (captured.len == 0) return; try terminal.writeText("captures:\n"); for (captured) |row| { try terminal.writeTextFmt( " {s} {s} ({s}", .{ row.workload, row.capture.kind, row.capture.tool }, ); if (row.capture.tool_version) |version| { try terminal.writeTextFmt(", {s}", .{version}); } try terminal.writeTextFmt(", {s}): {s}", .{ row.capture.scope, row.capture.state }); if (row.capture.caveat_kind) |caveat_kind| { try terminal.writeTextFmt(", caveat {s}", .{caveat_kind}); } if (row.capture.caveat_message) |message| { try terminal.writeTextFmt(": {s}", .{message}); } try terminal.writeText("\n"); }}pub fn writeCapturesJson(out: *pretty_json.Writer, captured: []const NamedCapture) !void { try out.beginArray(); for (captured) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("kind"); try out.write(row.capture.kind); try out.objectField("tool"); try out.write(row.capture.tool); try out.objectField("tool_version"); try out.write(row.capture.tool_version); try out.objectField("scope"); try out.write(row.capture.scope); try out.objectField("capture"); try out.write(row.capture.capture_path); try out.objectField("summary"); try out.write(row.capture.summary_path); try out.objectField("state"); try out.write(row.capture.state); try out.objectField("caveat_kind"); try out.write(row.capture.caveat_kind); try out.objectField("caveat_message"); try out.write(row.capture.caveat_message); try out.endObject(); } try out.endArray();}fn writeEnergyShiftsText(terminal: pretty_usage.Terminal, shifts: []const EnergyShift) !void { if (shifts.len == 0) { try terminal.writeText("energy shifts: none above threshold\n"); return; } try terminal.writeText("energy shifts:\n"); for (shifts) |row| { try terminal.writeTextFmt( " {s}: {s} {s} energy {d:.3}->{d:.3} J ({d:.2}%)", .{ row.status, row.workload, row.event, row.baseline_joules, row.candidate_joules, row.energy_percent_change, }, ); if (row.baseline_watts != null and row.candidate_watts != null and row.power_percent_change != null) { try terminal.writeTextFmt( ", power {d:.3}->{d:.3} W ({d:.2}%)", .{ row.baseline_watts.?, row.candidate_watts.?, row.power_percent_change.? }, ); } else { try terminal.writeText(", power unavailable"); } try writeEnergyRangeText( terminal, "energy", row.baseline_energy_range_percent, row.candidate_energy_range_percent, ); try writeEnergyRangeText( terminal, "power", row.baseline_power_range_percent, row.candidate_power_range_percent, ); try terminal.writeTextFmt(", threshold {d:.2}%\n", .{row.threshold_percent}); }}fn writeEnergyRangeText( terminal: pretty_usage.Terminal, label: []const u8, baseline_range: ?f64, candidate: ?f64,) !void { if (baseline_range != null and candidate != null) { try terminal.writeTextFmt(", {s} range {d:.2}->{d:.2}%", .{ label, baseline_range.?, candidate.?, }); } else { try terminal.writeTextFmt(", {s} range unavailable", .{label}); }}fn writeEnergyShiftsJson(out: *pretty_json.Writer, shifts: []const EnergyShift) !void { try out.beginArray(); for (shifts) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("event"); try out.write(row.event); try out.objectField("baseline_joules"); try out.write(row.baseline_joules); try out.objectField("candidate_joules"); try out.write(row.candidate_joules); try out.objectField("energy_percent_change"); try out.write(row.energy_percent_change); try out.objectField("baseline_watts"); try out.write(row.baseline_watts); try out.objectField("candidate_watts"); try out.write(row.candidate_watts); try out.objectField("power_percent_change"); try out.write(row.power_percent_change); try out.objectField("baseline_energy_range_percent"); try out.write(row.baseline_energy_range_percent); try out.objectField("candidate_energy_range_percent"); try out.write(row.candidate_energy_range_percent); try out.objectField("baseline_power_range_percent"); try out.write(row.baseline_power_range_percent); try out.objectField("candidate_power_range_percent"); try out.write(row.candidate_power_range_percent); try out.objectField("threshold_percent"); try out.write(row.threshold_percent); try out.objectField("status"); try out.write(row.status); try out.endObject(); } try out.endArray();}fn writeCounterShiftsText(terminal: pretty_usage.Terminal, shifts: []const CounterShift) !void { if (shifts.len == 0) { try terminal.writeText("counter shifts: none above threshold\n"); return; } try terminal.writeText("counter shifts:\n"); for (shifts) |row| { try terminal.writeTextFmt(" {s}: {s} {s} {d:.2}->{d:.2} ({d:.2}%, threshold {d:.2}%)\n", .{ row.status, row.workload, row.event, row.baseline_value, row.candidate_value, row.percent_change, row.threshold_percent, }); }}fn writeCounterShiftsJson(out: *pretty_json.Writer, shifts: []const CounterShift) !void { try out.beginArray(); for (shifts) |row| { try out.beginObject(); try out.objectField("workload"); try out.write(row.workload); try out.objectField("event"); try out.write(row.event); try out.objectField("baseline_value"); try out.write(row.baseline_value); try out.objectField("candidate_value"); try out.write(row.candidate_value); try out.objectField("percent_change"); try out.write(row.percent_change); try out.objectField("threshold_percent"); try out.write(row.threshold_percent); try out.objectField("status"); try out.write(row.status); try out.endObject(); } try out.endArray();}fn writePriorityText(terminal: pretty_usage.Terminal, report: priority.Report, top: usize) !void { if (report.items.len == 0) { try terminal.writeText("priority: no regression candidates\n"); return; } const item_count = @min(top, report.items.len); try terminal.writeText("priority:\n"); for (report.items[0..item_count]) |item| { try terminal.writeTextFmt(" {d}. {s} {s}: score {d:.2}, {d:.2}% ({s}, confidence {d:.2})\n", .{ item.rank, item.kind.name(), item.workload, item.score, item.percent_change, item.evidence.name(), item.confidence, }); try terminal.writeTextFmt(" component {s}, label {s}\n", .{ item.component, item.label }); } if (report.components.len == 0) return; const component_count = @min(top, report.components.len); try terminal.writeText("priority components:\n"); for (report.components[0..component_count]) |component| { try terminal.writeTextFmt(" {d}. {s}: score {d:.2}, {d} workload(s), {d} issue(s), strongest {s}/{s}\n", .{ component.rank, component.component, component.score, component.affected_workloads, component.issue_count, component.strongest_workload, component.strongest_label, }); }}fn writePriorityJson(out: *pretty_json.Writer, report: priority.Report) !void { try out.beginObject(); try out.objectField("items"); try out.beginArray(); for (report.items) |item| { try out.beginObject(); try out.objectField("rank"); try out.write(item.rank); try out.objectField("kind"); try out.write(item.kind.name()); try out.objectField("workload"); try out.write(item.workload); try out.objectField("package"); try out.write(item.package); try out.objectField("component"); try out.write(item.component); try out.objectField("label"); try out.write(item.label); try out.objectField("key"); try out.write(item.key); try out.objectField("evidence"); try out.write(item.evidence.name()); try out.objectField("confidence"); try out.write(item.confidence); try out.objectField("workload_weight"); try out.write(item.workload_weight); try out.objectField("percent_change"); try out.write(item.percent_change); try out.objectField("threshold_percent"); try out.write(item.threshold_percent); try out.objectField("absolute_change"); try out.write(item.absolute_change); try out.objectField("unit"); try out.write(item.unit.name()); try out.objectField("causal_max_program_speedup"); try out.write(item.causal_max_program_speedup); try out.objectField("score"); try out.write(item.score); try out.objectField("reason"); try out.write(item.reason); try out.endObject(); } try out.endArray(); try out.objectField("components"); try out.beginArray(); for (report.components) |component| { try out.beginObject(); try out.objectField("rank"); try out.write(component.rank); try out.objectField("component"); try out.write(component.component); try out.objectField("score"); try out.write(component.score); try out.objectField("affected_workloads"); try out.write(component.affected_workloads); try out.objectField("issue_count"); try out.write(component.issue_count); try out.objectField("strongest_workload"); try out.write(component.strongest_workload); try out.objectField("strongest_label"); try out.write(component.strongest_label); try out.objectField("strongest_score"); try out.write(component.strongest_score); try out.objectField("reason"); try out.write(component.reason); try out.endObject(); } try out.endArray(); try out.endObject();}fn writeStringsJson(out: *pretty_json.Writer, values: []const []const u8) !void { try out.beginArray(); for (values) |value| try out.write(value); try out.endArray();}fn writeRankedJson(out: *pretty_json.Writer, workloads: []const Workload, indices: []const usize, count: usize, mode: []const u8) !void { try out.beginArray(); var index: usize = 0; while (index < count) : (index += 1) { const workload = workloads[indices[index]]; try out.beginObject(); try out.objectField("rank"); try out.write(index + 1); try out.objectField("mode"); try out.write(mode); try out.objectField("workload"); try out.write(workload.name); try out.objectField("acquisition"); try order.writeJson(out, workload.acquisition); try out.objectField("wall_ns"); try out.write(workload.wall_ns); try out.objectField("wall_statistic"); try out.write(workload_wall_statistic); try out.objectField("total_wall_ns"); try out.write(workload.total_wall_ns); try out.objectField("execution_count"); try out.write(workload.execution_count); try out.objectField("executions"); try writeMeasuredExecutionsJson(out, workload.executions); try out.objectField("structured_analysis"); try out.write(workload.structuredAnalysisState()); try out.objectField("benchmark_process_domain"); try reducer.writeDomainJson(out, workload.benchmark_process_domain); try out.objectField("benchmark_process_reduction"); try reducer.writeJson(out, workload.benchmark_process_reduction); try out.objectField("warmup_count"); try out.write(workload.warmup_count); try out.objectField("warmup_total_wall_ns"); try out.write(workload.warmup_total_wall_ns); try out.objectField("warmup_wall_distribution"); if (workload.warmup_distribution) |distribution| { try writeWallDistributionJson(out, distribution); } else { try out.write(null); } try out.objectField("wall_distribution"); try writeWorkloadWallDistributionJson(out, workload); try out.objectField("max_rss_kib"); try out.write(workload.max_rss_kib); try out.endObject(); } try out.endArray();}fn writeMeasuredExecutionsJson( out: *pretty_json.Writer, executions: []const measurement.Execution,) !void { try out.beginArray(); for (executions) |execution| { try out.beginObject(); try out.objectField("index"); try out.write(execution.index); try out.objectField("acquisition_position"); try out.write(execution.acquisition_position); try out.objectField("pid"); try out.write(execution.pid); try out.objectField("exit_code"); try out.write(execution.exit_code); try out.objectField("wall_ns"); try out.write(execution.wall_ns); try out.objectField("artifacts"); try writeMeasuredArtifactsJson(out, execution.artifacts); try out.endObject(); } try out.endArray();}fn writeMeasuredArtifactsJson( out: *pretty_json.Writer, artifacts: ?measurement.ExecutionArtifacts,) !void { const actual = artifacts orelse { try out.write(null); return; }; try out.beginObject(); inline for (.{ .{ "root", actual.root }, .{ "stdout", actual.stdout }, .{ "stderr", actual.stderr }, .{ "bench_jsonl", actual.bench_jsonl }, .{ "structured", actual.structured }, }) |field| { try out.objectField(field[0]); try out.write(field[1]); } try out.objectField("structured_rows"); try out.write(actual.structured_rows); try out.objectField("structured_parse_errors"); try out.write(actual.structured_parse_errors); try out.endObject();}fn writeWorkloadMeasurementsJson( out: *pretty_json.Writer, workloads: []const Workload,) !void { try out.beginArray(); for (workloads) |workload| { try out.beginObject(); try out.objectField("workload"); try out.write(workload.name); try out.objectField("acquisition"); try order.writeJson(out, workload.acquisition); try out.objectField("wall_ns"); try out.write(workload.wall_ns); try out.objectField("wall_statistic"); try out.write(workload_wall_statistic); try out.objectField("total_wall_ns"); try out.write(workload.total_wall_ns); try out.objectField("execution_count"); try out.write(workload.execution_count); try out.objectField("executions"); try writeMeasuredExecutionsJson(out, workload.executions); try out.objectField("structured_analysis"); try out.write(workload.structuredAnalysisState()); try out.objectField("warmup_count"); try out.write(workload.warmup_count); try out.objectField("warmup_total_wall_ns"); try out.write(workload.warmup_total_wall_ns); try out.objectField("warmup_wall_distribution"); if (workload.warmup_distribution) |distribution| { try writeWallDistributionJson(out, distribution); } else { try out.write(null); } try out.objectField("wall_distribution"); try writeWorkloadWallDistributionJson(out, workload); try out.objectField("resources"); try writeProcessResourcesJson(out, workload); try out.endObject(); } try out.endArray();}fn writeProcessResourcesJson( out: *pretty_json.Writer, workload: Workload,) !void { try out.beginObject(); try out.objectField("resource_usage_source"); if (workload.resource_usage_source) |source| { try out.write(@tagName(source)); } else { try out.write(null); } try out.objectField("max_rss_kib"); try out.write(workload.max_rss_kib); try out.objectField("mean_user_s"); try out.write(workload.user_s); try out.objectField("mean_system_s"); try out.write(workload.system_s); try out.objectField("mean_minor_page_faults"); try out.write(workload.minor_page_faults); try out.objectField("mean_major_page_faults"); try out.write(workload.major_page_faults); try out.objectField("mean_voluntary_context_switches"); try out.write(workload.voluntary_context_switches); try out.objectField("mean_involuntary_context_switches"); try out.write(workload.involuntary_context_switches); try out.objectField("page_faults_per_s"); try out.write(totalFaultRate(workload)); try out.objectField("context_switches_per_s"); try out.write(totalSwitchRate(workload)); try out.endObject();}fn totalFaultRate(workload: Workload) ?f64 { const minor = workload.minor_page_faults orelse return null; const major = workload.major_page_faults orelse return null; return ratePerSecond(minor + major, workload.wall_ns);}fn totalSwitchRate(workload: Workload) ?f64 { const voluntary = workload.voluntary_context_switches orelse return null; const involuntary = workload.involuntary_context_switches orelse return null; return ratePerSecond(voluntary + involuntary, workload.wall_ns);}fn writeWallDistributionJson( out: *pretty_json.Writer, distribution: measurement.WallDistribution,) !void { try out.beginObject(); try out.objectField("kind"); try out.write(distribution.kind.name()); try out.objectField("sample_count"); try out.write(distribution.sample_count); try out.objectField("mean_ns"); try out.write(distribution.mean_ns); try out.objectField("min_ns"); try out.write(distribution.min_ns); try out.objectField("median_ns"); try out.write(distribution.median_ns); try out.objectField("p95_ns"); try out.write(distribution.p95_ns); try out.objectField("p99_ns"); try out.write(distribution.p99_ns); try out.objectField("max_ns"); try out.write(distribution.max_ns); try out.objectField("stddev_ns"); try out.write(distribution.stddev_ns); try out.objectField("coefficient_of_variation_percent"); try out.write(distribution.coefficient_of_variation_percent); try out.endObject();}fn writeWorkloadWallDistributionJson( out: *pretty_json.Writer, workload: Workload,) !void { if (workload.execution_count == 0) { try out.write(null); return; } try writeWallDistributionJson(out, workloadWallDistribution(workload));}fn writeOutliersJson(out: *pretty_json.Writer, workloads: []const Workload, wall: []const usize, rss: []const usize) !void { try out.beginArray(); for (wall) |index| { try out.beginObject(); try out.objectField("kind"); try out.write("wall"); try out.objectField("workload"); try out.write(workloads[index].name); try out.objectField("wall_ns"); try out.write(workloads[index].wall_ns); try out.objectField("wall_statistic"); try out.write(workload_wall_statistic); try out.objectField("total_wall_ns"); try out.write(workloads[index].total_wall_ns); try out.objectField("execution_count"); try out.write(workloads[index].execution_count); try out.endObject(); } for (rss) |index| { try out.beginObject(); try out.objectField("kind"); try out.write("rss"); try out.objectField("workload"); try out.write(workloads[index].name); try out.objectField("max_rss_kib"); try out.write(workloads[index].max_rss_kib); try out.endObject(); } try out.endArray();}test "profiling analysis serializes both contexts for unsupported comparisons" { const allocator = std.testing.allocator; const run_ref = baseline.RunRef{ .run_id = "run", .root = "run", .manifest_path = "run/manifest.json", .results_path = "run/results.jsonl", }; const baseline_host = environment.Host{ .hostname = "bench-a", .os = "linux", .kernel = "7.0.11", .arch = "x86_64", .cpu_count = 16, .cpu_frequency_policy = "policy-a", .process_cpu_affinity = "0-15", .process_memory_affinity = "0", }; var candidate_host = baseline_host; candidate_host.cpu_frequency_policy = "policy-b"; const baseline_run = Run{ .ref = run_ref, .optimize = "ReleaseFast", .host = baseline_host }; const candidate_run = Run{ .ref = run_ref, .optimize = "ReleaseFast", .host = candidate_host }; var output: std.Io.Writer.Allocating = .init(allocator); defer output.deinit(); var writer = pretty_json.Writer.init(&output.writer, .minified); try writeComparisonSupportJson(&writer, baseline_run, candidate_run); const text = try output.toOwnedSlice(); defer allocator.free(text); try std.testing.expect( std.mem.indexOf(u8, text, "\"state\":\"cpu_frequency_policy_mismatch\"") != null, ); try std.testing.expect( std.mem.indexOf(u8, text, "\"baseline_host\":{\"hostname\":\"bench-a\"") != null, ); try std.testing.expect( std.mem.indexOf(u8, text, "\"candidate_host\":{\"hostname\":\"bench-a\"") != null, ); try std.testing.expect( std.mem.indexOf(u8, text, "\"cpu_frequency_policy\":\"policy-b\"") != null, );}test "profiling analysis serializes missing process affinity support" { const allocator = std.testing.allocator; const run_ref = baseline.RunRef{ .run_id = "run", .root = "run", .manifest_path = "run/manifest.json", .results_path = "run/results.jsonl", }; const host_value = environment.Host{ .os = "linux", .arch = "x86_64", .cpu_count = 16, .process_cpu_affinity = "0-15", .process_memory_affinity = "0", }; var candidate_host = host_value; candidate_host.process_memory_affinity = null; const base = Run{ .ref = run_ref, .optimize = "ReleaseFast", .host = host_value }; const candidate = Run{ .ref = run_ref, .optimize = "ReleaseFast", .host = candidate_host }; var output: std.Io.Writer.Allocating = .init(allocator); defer output.deinit(); var writer = pretty_json.Writer.init(&output.writer, .minified); try writeComparisonSupportJson(&writer, base, candidate); const text = try output.toOwnedSlice(); defer allocator.free(text); try std.testing.expect( std.mem.indexOf(u8, text, "\"state\":\"process_memory_affinity_missing\"") != null, ); try std.testing.expect( std.mem.indexOf(u8, text, "\"process_memory_affinity\":null") != null, );}test "profiling analysis serializes missing frequency policy support" { const allocator = std.testing.allocator; const run_ref = baseline.RunRef{ .run_id = "run", .root = "run", .manifest_path = "run/manifest.json", .results_path = "run/results.jsonl", }; const host_value = environment.Host{ .os = "linux", .arch = "x86_64", .cpu_count = 16, .cpu_frequency_policy = "policy-a", .process_cpu_affinity = "0-15", .process_memory_affinity = "0", }; var candidate_host = host_value; candidate_host.cpu_frequency_policy = null; const base = Run{ .ref = run_ref, .optimize = "ReleaseFast", .host = host_value }; const candidate = Run{ .ref = run_ref, .optimize = "ReleaseFast", .host = candidate_host }; var output: std.Io.Writer.Allocating = .init(allocator); defer output.deinit(); var writer = pretty_json.Writer.init(&output.writer, .minified); try writeComparisonSupportJson(&writer, base, candidate); const text = try output.toOwnedSlice(); defer allocator.free(text); try std.testing.expect( std.mem.indexOf(u8, text, "\"state\":\"cpu_frequency_policy_missing\"") != null, ); try std.testing.expect( std.mem.indexOf(u8, text, "\"cpu_frequency_policy\":null") != null, );}pub fn expectRepeatedMeasurementJson( allocator: std.mem.Allocator, workload: Workload,) !void { var output: std.Io.Writer.Allocating = .init(allocator); var writer = pretty_json.Writer.init(&output.writer, .minified); try writeWorkloadMeasurementsJson(&writer, &.{workload}); const document = try std.json.parseFromSliceLeaky( std.json.Value, allocator, output.written(), .{}, ); const workloads = try json.array(document); const row = try json.object(workloads.items[0]); try std.testing.expectEqualStrings( "multiple_execution_receipts_reduced", json.string(row.get("structured_analysis")).?, ); const executions = try json.array(row.get("executions").?); try std.testing.expectEqual(@as(usize, 2), executions.items.len); const first = try json.object(executions.items[0]); const second = try json.object(executions.items[1]); try std.testing.expectEqual(@as(u64, 101), json.asU64(first.get("pid")).?); try std.testing.expectEqual(@as(u64, 102), json.asU64(second.get("pid")).?); const first_artifacts = try json.object(first.get("artifacts").?); const second_artifacts = try json.object(second.get("artifacts").?); try std.testing.expectEqualStrings( "moved/workloads/w/executions/001", json.string(first_artifacts.get("root")).?, ); try std.testing.expectEqual( @as(u64, 2), json.asU64(second_artifacts.get("structured_rows")).?, ); try std.testing.expectEqual( @as(u64, 1), json.asU64(second_artifacts.get("structured_parse_errors")).?, );}test "profiling analysis writes process-level resource rates" { const allocator = std.testing.allocator; const workload = Workload{ .name = "w", .package = "p", .step = "bench", .status = "passed", .exit_code = 0, .wall_ns = std.time.ns_per_s, .resource_usage_source = .wait4_rusage, .minor_page_faults = 96, .major_page_faults = 1, .voluntary_context_switches = 2, .involuntary_context_switches = 1, .result_path = null, }; var output: std.Io.Writer.Allocating = .init(allocator); var writer = pretty_json.Writer.init(&output.writer, .minified); try writeProcessResourcesJson(&writer, workload); const text = try output.toOwnedSlice(); defer allocator.free(text); try std.testing.expect( std.mem.indexOf(u8, text, "\"resource_usage_source\":\"wait4_rusage\"") != null, ); try std.testing.expect(std.mem.indexOf(u8, text, "\"page_faults_per_s\":97") != null); try std.testing.expect(std.mem.indexOf(u8, text, "\"context_switches_per_s\":3") != null);}test "profiling analysis serializes allocation sample evidence" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const rows = [_]memory.Comparison{.{ .workload = "allocator", .key = "allocations|allocated_bytes", .label = "allocated bytes", .budget_kind = .allocation, .unit = .bytes, .baseline_value = 100, .candidate_value = 130, .percent_change = 30, .threshold_percent = 10, .baseline_samples = 4, .candidate_samples = 4, .baseline_distribution = .raw_executions, .candidate_distribution = .raw_executions, .effect_low_percent = 20, .effect_high_percent = 40, .status = "allocation_sample_regression", }}; var output: std.Io.Writer.Allocating = .init(allocator); var writer = pretty_json.Writer.init(&output.writer, .minified); try writeMemoryComparisonsJson(&writer, &rows); const text = try output.toOwnedSlice(); try std.testing.expect(std.mem.indexOf( u8, text, "\"baseline_distribution\":\"raw_executions\"", ) != null); try std.testing.expect(std.mem.indexOf( u8, text, "\"effect_low_percent\":20", ) != null); try std.testing.expect(std.mem.indexOf( u8, text, "\"budget_kind\":\"allocation\"", ) != null); try std.testing.expect(std.mem.indexOf( u8, text, "deterministic_percentile_bootstrap_unpaired_mean_percent_change", ) != null);}test "profiling analysis serializes energy comparison ranges" { const shifts = [_]EnergyShift{.{ .workload = "a", .event = "power/energy-pkg/u", .baseline_joules = 10, .candidate_joules = 11, .energy_percent_change = 10, .baseline_watts = 5, .candidate_watts = 6, .power_percent_change = 20, .baseline_energy_range_percent = 2, .candidate_energy_range_percent = 3, .baseline_power_range_percent = 4, .candidate_power_range_percent = 5, .threshold_percent = 10, .status = "energy_shift_caveated", }}; var output: std.Io.Writer.Allocating = .init(std.testing.allocator); defer output.deinit(); var writer = pretty_json.Writer.init(&output.writer, .minified); try writeEnergyShiftsJson(&writer, &shifts); try std.testing.expect(std.mem.indexOf( u8, output.written(), "\"power_percent_change\":20", ) != null); try std.testing.expect(std.mem.indexOf( u8, output.written(), "\"candidate_power_range_percent\":5", ) != null);}test "profiling analysis suppresses regressions for acquisition diagnostics" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const fixture = try orderEffectTestFixture(allocator); var output: std.Io.Writer.Allocating = .init(allocator); try writeJson( allocator, &output.writer, fixture.random, fixture.fixed, .{ .input = "random", .baseline_input = "fixed", .json = true }, ); const text = try output.toOwnedSlice(); try std.testing.expect(std.mem.indexOf( u8, text, "\"order_effects\":{\"mode\":\"fixed_vs_random_interleaved\"", ) != null); try std.testing.expect(std.mem.indexOf( u8, text, "\"status\":\"order_sensitive_candidate\"", ) != null); try std.testing.expect(std.mem.indexOf(u8, text, "\"regressions\":[]") != null); try std.testing.expect(std.mem.indexOf(u8, text, "\"metric_regressions\":[]") != null); try std.testing.expect(std.mem.indexOf(u8, text, "\"memory_regressions\":[]") != null); try std.testing.expect(std.mem.indexOf(u8, text, "\"counter_shifts\":[]") != null); try std.testing.expect(std.mem.indexOf( u8, text, "\"state\":\"measurement_order_mismatch\"", ) != null);}Source: src/profiling/analyze/root.zig:7
zig
pub const render = @import("render.zig");Complete call list for analyze.render.writeJson
26 direct calls.
tiny.profiling.analyze.compare.missingWorkloads[function] atsrc/profiling/analyze/compare.zig:46tiny.profiling.analyze.evidence.comparisonEvidence[function] atsrc/profiling/analyze/evidence.zig:37tiny.profiling.analyze.evidence.flattenCaptures[function] atsrc/profiling/analyze/evidence.zig:103tiny.profiling.analyze.evidence.flattenCausal[function] atsrc/profiling/analyze/evidence.zig:121tiny.profiling.analyze.evidence.outliersByRss[function] atsrc/profiling/analyze/evidence.zig:180tiny.profiling.analyze.evidence.outliersByWall[function] atsrc/profiling/analyze/evidence.zig:169tiny.profiling.analyze.evidence.sortedByRss[function] atsrc/profiling/analyze/evidence.zig:163tiny.profiling.analyze.evidence.sortedByWall[function] atsrc/profiling/analyze/evidence.zig:157src.profiling.analyze.render.writeAllocationBudgetChecksJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1213in nearest public ownertiny.profiling.analyze.rendertiny.profiling.analyze.render.writeCapturePerturbationsJson[function] atsrc/profiling/analyze/render.zig:842tiny.profiling.analyze.render.writeCapturesJson[function] atsrc/profiling/analyze/render.zig:1349tiny.profiling.analyze.render.writeCausalJson[function] atsrc/profiling/analyze/render.zig:1277src.profiling.analyze.render.writeComparisonSupportJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:168in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeComparisonsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:927in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeCounterShiftsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1495in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeEnergyShiftsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1439in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeMemoryComparisonsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1134in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeMetricComparisonsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1097in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeOrderEffectsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:650in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeOutliersJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1854in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writePriorityJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1553in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeRankedJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1630in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeRunJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:896in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeStringsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1624in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeWorkloadComparisonSkipsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1050in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeWorkloadMeasurementsJson[function] — private; no exact target atsrc/profiling/analyze/render.zig:1729in nearest public ownertiny.profiling.analyze.render
Complete call list for analyze.render.writeText
23 direct calls.
tiny.profiling.analyze.compare.missingWorkloads[function] atsrc/profiling/analyze/compare.zig:46tiny.profiling.analyze.evidence.comparisonEvidence[function] atsrc/profiling/analyze/evidence.zig:37tiny.profiling.analyze.evidence.flattenCaptures[function] atsrc/profiling/analyze/evidence.zig:103tiny.profiling.analyze.evidence.flattenCausal[function] atsrc/profiling/analyze/evidence.zig:121tiny.profiling.analyze.evidence.outliersByRss[function] atsrc/profiling/analyze/evidence.zig:180tiny.profiling.analyze.evidence.outliersByWall[function] atsrc/profiling/analyze/evidence.zig:169tiny.profiling.analyze.evidence.sortedByRss[function] atsrc/profiling/analyze/evidence.zig:163tiny.profiling.analyze.evidence.sortedByWall[function] atsrc/profiling/analyze/evidence.zig:157src.profiling.analyze.render.writeAllocationBudgetChecksText[function] — private; no exact target atsrc/profiling/analyze/render.zig:1181in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeCapturePerturbationsText[function] — private; no exact target atsrc/profiling/analyze/render.zig:784in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeCapturesText[function] — private; no exact target atsrc/profiling/analyze/render.zig:1327in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeCausalText[function] — private; no exact target atsrc/profiling/analyze/render.zig:1245in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeCounterShiftsText[function] — private; no exact target atsrc/profiling/analyze/render.zig:1476in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeEnergyShiftsText[function] — private; no exact target atsrc/profiling/analyze/render.zig:1378in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeHostText[function] — private; no exact target atsrc/profiling/analyze/render.zig:380in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeOrderEffectsText[function] — private; no exact target atsrc/profiling/analyze/render.zig:604in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writePriorityText[function] — private; no exact target atsrc/profiling/analyze/render.zig:1518in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeRankedRssText[function] — private; no exact target atsrc/profiling/analyze/render.zig:463in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeRankedWallText[function] — private; no exact target atsrc/profiling/analyze/render.zig:404in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeStructuredAnalysisCaveats[function] — private; no exact target atsrc/profiling/analyze/render.zig:360in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeUnsupportedComparisonText[function] — private; no exact target atsrc/profiling/analyze/render.zig:44in nearest public ownertiny.profiling.analyze.rendersrc.profiling.analyze.render.writeWorkloadComparisonSkipText[function] — private; no exact target atsrc/profiling/analyze/render.zig:987in nearest public ownertiny.profiling.analyze.rendertiny.profiling.report.format.ns[function] atsrc/profiling/report/format.zig:7
Audit
| Definitions | 7 |
|---|---|
| Public names | 9 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |