Skip to documentation
SLOP

tiny.profiling.report.model

Reference tiny.profiling report model

Defined in report.

API (11)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callsreportmodel
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallstest; no linksrc.profiling.report.flametest: flame differential baseline req...test; no linksrc.profiling.report.modeltest: model fixture JSON escapes dyna...test; no linksrc.profiling.report.modeltest: model leaves incompatible host ...test; no linksrc.profiling.report.modeltest: model loads runs chronologicall...test; no linksrc.profiling.report.modeltest: model retains the process place...+7 morereport.analysisloadprivate; no linksrc.profiling.report.modelbuildHistoriesprivate; no linksrc.profiling.report.modelloadManifestreport.modelload
Static calls · unresolved targets: 3 · external targets: 2.
Called byCallstest; no linksrc.profiling.report.flametest: flame differential baseline req...test; no linksrc.profiling.report.modeltest: model loads runs chronologicall...test; no linksrc.profiling.report.modeltest: model retains the process place...test; no linksrc.profiling.report.pagetest: page index renders lede trends ...test; no linksrc.profiling.report.pagetest: page renders energy and power s...+5 moreprivate; no linksrc.profiling.report.modelwriteFixtureRunreport.modelwriteTestFixture
Static calls · unresolved targets: 0 · external targets: 0.

Source: src/profiling/report/model.zig

zig
const std = @import("std");const capture = @import("capture");const memtrace = @import("memtrace");const pretty = @import("pretty");const sys = @import("sys");const profiling = @import("../root.zig");const analysis = @import("root.zig").analysis;const analyze = profiling.analyze;const environment = profiling.environment;const json = profiling.json;const pretty_json = pretty.json;const fs_io = sys.fs.debugIo();const max_manifest_bytes = 16 * 1024 * 1024;pub const Manifest = struct {    run_id: []const u8,    started_unix_ns: i128,    wall_ns: ?u64,    suite: []const u8,    git_sha: ?[]const u8,    git_branch: ?[]const u8,    git_dirty: ?bool,    zig_version: ?[]const u8,    optimize: ?[]const u8,    host: environment.Host,};pub const Entry = struct {    dir: []const u8,    root: []const u8,    manifest: Manifest,    run: analyze.Run,    recorded: ?analysis.Recorded,    pub fn findWorkload(self: *const Entry, name: []const u8) ?*const analyze.Workload {        for (self.run.workloads) |*workload| {            if (std.mem.eql(u8, workload.name, name)) return workload;        }        return null;    }};pub const MetricHistory = struct {    key: []const u8,    label: []const u8,    primary: []?f64,    low: []?f64,    high: []?f64,};pub const MemoryHistory = struct {    key: []const u8,    label: []const u8,    unit: []const u8,    values: []?f64,};pub const WorkloadHistory = struct {    name: []const u8,    package: []const u8,    wall: []?f64,    rss: []?f64,    metrics: []MetricHistory,    memory: []MemoryHistory,};pub const Site = struct {    runs: []Entry,    histories: []WorkloadHistory,    pub fn latest(self: Site) ?*const Entry {        if (self.runs.len == 0) return null;        return &self.runs[self.runs.len - 1];    }    pub fn findHistory(self: Site, name: []const u8) ?*const WorkloadHistory {        for (self.histories) |*history| {            if (std.mem.eql(u8, history.name, name)) return history;        }        return null;    }};pub fn load(allocator: std.mem.Allocator, profiling_dir: []const u8) !Site {    var entries: std.ArrayList(Entry) = .empty;    const listing = sys.fs.listDirAlloc(allocator, profiling_dir) catch |err| switch (err) {        error.FileNotFound => return .{ .runs = &.{}, .histories = &.{} },        else => |actual| return actual,    };    for (listing) |item| {        if (item.kind != .directory) continue;        const manifest_path = try std.fs.path.join(allocator, &.{ item.path, "manifest.json" });        if (!sys.fs.exists(manifest_path)) continue;        const manifest = (try loadManifest(allocator, manifest_path, item.name)) orelse continue;        const run = analyze.loadRun(allocator, item.path) catch continue;        try entries.append(allocator, .{            .dir = item.name,            .root = item.path,            .manifest = manifest,            .run = run,            .recorded = try analysis.load(allocator, item.path),        });    }    const runs = try entries.toOwnedSlice(allocator);    std.mem.sort(Entry, runs, {}, startedBefore);    return .{        .runs = runs,        .histories = try buildHistories(allocator, runs),    };}fn startedBefore(_: void, left: Entry, right: Entry) bool {    return left.manifest.started_unix_ns < right.manifest.started_unix_ns;}fn loadManifest(allocator: std.mem.Allocator, path: []const u8, dir_name: []const u8) !?Manifest {    const text = sys.fs.readFileAlloc(allocator, path, max_manifest_bytes) catch |err| switch (err) {        error.FileNotFound => return null,        else => |actual| return actual,    };    const value = std.json.parseFromSliceLeaky(std.json.Value, allocator, text, .{}) catch return null;    const object = json.object(value) catch return null;    const selection = if (object.get("selection")) |actual| json.object(actual) catch null else null;    const environment_object = if (object.get("environment")) |actual|        json.object(actual) catch null    else        null;    const summary = if (object.get("summary")) |actual| json.object(actual) catch null else null;    const git = if (environment_object) |env|        (if (env.get("git")) |actual| json.object(actual) catch null else null)    else        null;    const zig_info = if (environment_object) |env|        (if (env.get("zig")) |actual| json.object(actual) catch null else null)    else        null;    const build = if (environment_object) |env|        (if (env.get("build")) |actual| json.object(actual) catch null else null)    else        null;    return .{        .run_id = json.string(object.get("run_id")) orelse dir_name,        .started_unix_ns = json.asI128(object.get("started_unix_ns")) orelse 0,        .wall_ns = if (summary) |actual| json.asU64(actual.get("wall_ns")) else null,        .suite = if (selection) |actual| json.string(actual.get("suite")) orelse "unknown" else "unknown",        .git_sha = if (git) |actual| json.string(actual.get("commit")) else null,        .git_branch = if (git) |actual| json.string(actual.get("branch")) else null,        .git_dirty = if (git) |actual| json.asBool(actual.get("dirty")) else null,        .zig_version = if (zig_info) |actual| json.string(actual.get("version")) else null,        .optimize = if (build) |actual| json.string(actual.get("optimize")) else null,        .host = profiling.environment.parse(object.get("environment")),    };}fn buildHistories(allocator: std.mem.Allocator, runs: []const Entry) ![]WorkloadHistory {    var names: std.StringArrayHashMapUnmanaged(void) = .empty;    for (runs, 0..) |entry, run_index| {        if (!compatibleWithLatest(runs, run_index)) continue;        for (entry.run.workloads) |workload| try names.put(allocator, workload.name, {});    }    var histories: std.ArrayList(WorkloadHistory) = .empty;    for (names.keys()) |name| {        try histories.append(allocator, try buildWorkloadHistory(allocator, runs, name));    }    return try histories.toOwnedSlice(allocator);}fn buildWorkloadHistory(allocator: std.mem.Allocator, runs: []const Entry, name: []const u8) !WorkloadHistory {    const wall = try allocator.alloc(?f64, runs.len);    const rss = try allocator.alloc(?f64, runs.len);    var package: []const u8 = "";    var metric_keys: std.StringArrayHashMapUnmanaged([]const u8) = .empty;    var memory_keys: std.StringArrayHashMapUnmanaged(MemoryHistory) = .empty;    for (runs, 0..) |entry, run_index| {        wall[run_index] = null;        rss[run_index] = null;        if (!compatibleWithLatest(runs, run_index)) continue;        const workload = entry.findWorkload(name) orelse continue;        if (workload.package.len != 0) package = workload.package;        if (workloadComparableWithLatest(runs, run_index, name)) {            wall[run_index] = @floatFromInt(workload.wall_ns);            if (workload.max_rss_kib) |value| rss[run_index] = @floatFromInt(value);        }        for (workload.metrics) |metric| {            if (metric.primaryNs() == null) continue;            if (!metric_keys.contains(metric.key)) try metric_keys.put(allocator, metric.key, metric.label);        }        for (workload.memory_metrics) |metric| {            if (!memory_keys.contains(metric.key)) {                try memory_keys.put(allocator, metric.key, .{                    .key = metric.key,                    .label = metric.label,                    .unit = metric.unit.name(),                    .values = &.{},                });            }        }    }    var metrics: std.ArrayList(MetricHistory) = .empty;    var key_iterator = metric_keys.iterator();    while (key_iterator.next()) |pair| {        const primary = try allocator.alloc(?f64, runs.len);        const low = try allocator.alloc(?f64, runs.len);        const high = try allocator.alloc(?f64, runs.len);        for (runs, 0..) |entry, run_index| {            primary[run_index] = null;            low[run_index] = null;            high[run_index] = null;            if (!compatibleWithLatest(runs, run_index)) continue;            const workload = entry.findWorkload(name) orelse continue;            for (workload.metrics) |metric| {                if (!std.mem.eql(u8, metric.key, pair.key_ptr.*)) continue;                primary[run_index] = metric.primaryNs();                if (metric.primaryInterval()) |interval| {                    low[run_index] = interval.low_ns;                    high[run_index] = interval.high_ns;                }                break;            }        }        try metrics.append(allocator, .{            .key = pair.key_ptr.*,            .label = pair.value_ptr.*,            .primary = primary,            .low = low,            .high = high,        });    }    var memory: std.ArrayList(MemoryHistory) = .empty;    var memory_iterator = memory_keys.iterator();    while (memory_iterator.next()) |pair| {        const values = try allocator.alloc(?f64, runs.len);        for (runs, 0..) |entry, run_index| {            values[run_index] = null;            if (!compatibleWithLatest(runs, run_index)) continue;            const workload = entry.findWorkload(name) orelse continue;            for (workload.memory_metrics) |metric| {                if (!std.mem.eql(u8, metric.key, pair.key_ptr.*)) continue;                values[run_index] = metric.value;                break;            }        }        var history = pair.value_ptr.*;        history.values = values;        try memory.append(allocator, history);    }    return .{        .name = name,        .package = package,        .wall = wall,        .rss = rss,        .metrics = try metrics.toOwnedSlice(allocator),        .memory = try memory.toOwnedSlice(allocator),    };}fn compatibleWithLatest(runs: []const Entry, run_index: usize) bool {    if (runs.len == 0) return false;    std.debug.assert(run_index < runs.len);    return analyze.comparisonSupport(runs[run_index].run, runs[runs.len - 1].run) == .supported;}fn workloadComparableWithLatest(    runs: []const Entry,    run_index: usize,    name: []const u8,) bool {    if (runs.len == 0 or !compatibleWithLatest(runs, run_index)) return false;    const workload = runs[run_index].findWorkload(name) orelse return false;    const latest = runs[runs.len - 1].findWorkload(name) orelse return false;    return analyze.workloadComparisonSupport(workload.*, latest.*) == .supported;}fn writeFixtureSymbolSummary(    allocator: std.mem.Allocator,    workload_dir: []const u8,    quality: ?capture.stackcollapse.Summary,) !void {    const symbols_path = try std.fs.path.join(        allocator,        &.{ workload_dir, "perf.symbols.summary.json" },    );    try capture.perfreport.writeSymbolSummaryFile(symbols_path, .{        .source_path = "perf.symbols.tsv",        .total_lost_samples = 0,        .sample_count_text = "10",        .sample_count_approx = 10,        .call_graph = "fp",        .sampling_frequency_hz = 99,        .minimum_sample_count = 400,        .report_percent_limit = 0.5,        .maximum_two_sigma_share_half_width_percentage_points = 31.622776601683793,        .callchain_quality = quality,        .event = "cycles:P",        .event_count_approx = 1000,        .rows = &.{.{            .overhead_percent = 12.25,            .samples = 2,            .symbol = "[.] alloc.refill",            .shared_object = "gpalloc-bench",            .ipc = null,            .ipc_coverage_percent = null,        }},    });}fn writeFixtureResults(    allocator: std.mem.Allocator,    root: []const u8,    workload_dir: []const u8,    run_id: []const u8,    started_unix_ns: i128,    wall_ns: u64,    hostname: []const u8,    has_captures: bool,) !void {    const results_path = try std.fs.path.join(allocator, &.{ root, "results.jsonl" });    const finished_unix_ns = started_unix_ns + wall_ns;    const empty_strings: []const []const u8 = &.{};    const command_argv: []const []const u8 = &.{ "zig", "build", "gpalloc-bench" };    var file = try sys.fs.cwd().createFile(fs_io, results_path, .{ .truncate = true });    defer file.close(fs_io);    var buffer: [8192]u8 = undefined;    var file_writer = file.writer(fs_io, &buffer);    const writer = &file_writer.interface;    {        var json_writer = pretty_json.Writer.init(writer, .minified);        const row = try json_writer.object();        try row.fields(.{            .schema = "tiny.profiling.run/v1",            .event = "run_start",            .run_id = run_id,            .started_unix_ns = started_unix_ns,        });        try row.field("selection", .{            .suite = "smoke",            .filters = empty_strings,            .workload_count = @as(u8, 1),        });        try row.field("environment", .{            .build = .{ .optimize = "ReleaseFast" },            .host = .{                .hostname = hostname,                .os = "linux",                .kernel = "7.0.11",                .arch = "x86_64",                .cpu_model = "AMD Ryzen 7 7800X3D",                .cpu_count = @as(u8, 16),                .cpu_frequency_policy = "policy-a",                .process_cpu_affinity = "0-15",                .process_memory_affinity = "0",            },        });        try row.field("artifacts", .{            .root = root,            .results = "results.jsonl",            .manifest = "manifest.json",        });        try row.endLine();    }    {        var json_writer = pretty_json.Writer.init(writer, .minified);        const row = try json_writer.object();        try row.fields(.{            .schema = profiling.record.workload_schema,            .event = "workload",            .run_id = run_id,            .index = @as(u8, 0),        });        try row.field("acquisition", .{            .position = @as(u8, 1),            .workload_count = @as(u8, 1),            .predecessors = empty_strings,        });        try row.field("workload", .{            .name = "gpalloc.allocator",            .package = "lib/gpalloc",            .step = "gpalloc-bench",            .surface = "benchmark",        });        try row.fields(.{            .scope = "whole-step",            .causal = false,            .tracy = false,            .trace_allocations = false,        });        try row.field("command", .{            .text = "zig build gpalloc-bench",            .cwd = @as(?[]const u8, null),            .argv = command_argv,        });        try row.field("status", .{            .state = "passed",            .exit_code = @as(u8, 0),        });        try row.field("timing", .{            .started_unix_ns = started_unix_ns,            .finished_unix_ns = finished_unix_ns,            .wall_ns = wall_ns,        });        try row.field("resources", .{            .resource_usage_source = "wait4_rusage",            .max_rss_kib = @as(u32, 49_836),            .user_s = @as(f64, 0.3),            .system_s = @as(f64, 0.4),            .minor_page_faults = @as(u8, 96),            .major_page_faults = @as(u8, 0),            .voluntary_context_switches = @as(u8, 2),            .involuntary_context_switches = @as(u8, 1),        });        const measurement_row = try row.object("measurement");        try measurement_row.fields(.{            .execution_count = @as(u8, 1),            .acquisition_order = "fixed_plan_order",            .workload_output_retention = "all_measured_executions",            .measured_artifact_layout = "workload_root",            .allocation_summary_retention = "disabled",        });        try measurement_row.field("benchmark_process_domain", .{            .benchmark_surface = true,            .direct_execution = false,            .host_profiler = has_captures,            .tracy = false,            .causal = false,            .allocation_trace = false,            .capture_control = false,        });        try measurement_row.field("benchmark_process_reduction", .{            .schema = profiling.reduction.schema,            .state = "not_applicable",            .process_count = @as(u8, 1),            .reason = "outside_direct_benchmark_domain",        });        const executions = try measurement_row.array("executions");        const execution = try executions.object();        try execution.fields(.{            .index = @as(u8, 1),            .spawn_state = "spawned",            .pid = @as(u16, 101),            .exit_code = @as(u8, 0),            .wall_ns = wall_ns,        });        const artifacts = try execution.object("artifacts");        try artifacts.field("root", workload_dir);        inline for (.{            .{ "stdout", "/stdout.txt" },            .{ "stderr", "/stderr.txt" },            .{ "bench_jsonl", "/bench.jsonl" },            .{ "coz_jsonl", "/bench.coz.jsonl" },            .{ "coz_analysis", "/bench.coz.analysis.json" },            .{ "tracy_jsonl", "/bench.tracy.jsonl" },            .{ "tracy_summary", "/bench.tracy.summary.jsonl" },        }) |field| {            try artifacts.stringParts(field[0], &.{ workload_dir, field[1] });        }        try artifacts.stringParts(            "structured",            &.{ workload_dir, "/structured.jsonl" },        );        try artifacts.stringParts(            "allocations",            &.{ workload_dir, "/allocations.jsonl" },        );        try artifacts.fields(.{            .structured_rows = @as(u8, 2),            .structured_parse_errors = @as(u8, 0),        });        try artifacts.end();        try execution.end();        try executions.end();        try measurement_row.end();        const workload_artifacts = try row.object("artifacts");        try workload_artifacts.field("root", workload_dir);        try workload_artifacts.end();        const captures = try row.array("captures");        if (has_captures) {            const perf = try captures.object();            try perf.fields(.{                .kind = "perf_record",                .tool = "perf",                .scope = "whole-step",            });            try perf.stringParts("capture", &.{ workload_dir, "/perf.data" });            try perf.stringParts(                "summary",                &.{ workload_dir, "/perf.symbols.summary.json" },            );            try perf.field("state", "summary_written");            try perf.end();            const offcpu = try captures.object();            try offcpu.fields(.{                .kind = "offcpu_time",                .tool = "offcputime-bpfcc",                .scope = "workload-binary",            });            try offcpu.stringParts(                "capture",                &.{ workload_dir, "/offcpu.time.txt" },            );            try offcpu.stringParts(                "summary",                &.{ workload_dir, "/offcpu.summary.json" },            );            try offcpu.field("state", "summary_written");            try offcpu.end();        }        try captures.end();        try row.endLine();    }    {        var json_writer = pretty_json.Writer.init(writer, .minified);        const row = try json_writer.object();        try row.fields(.{            .schema = "tiny.profiling.run/v1",            .event = "run_end",            .run_id = run_id,            .started_unix_ns = started_unix_ns,        });        try row.field("summary", .{            .selected = @as(u8, 1),            .ran = @as(u8, 1),            .passed = @as(u8, 1),            .failed = @as(u8, 0),            .stopped_early = false,            .exit_code = @as(u8, 0),            .started_unix_ns = started_unix_ns,            .finished_unix_ns = finished_unix_ns,            .wall_ns = wall_ns,        });        try row.endLine();    }    try writer.flush();}fn writeFixtureCaptureArtifacts(    allocator: std.mem.Allocator,    workload_dir: []const u8,    folded_text: []const u8,    callchain_quality: ?capture.stackcollapse.Summary,) !void {    const folded_path = try std.fs.path.join(        allocator,        &.{ workload_dir, "perf.folded.txt" },    );    try sys.fs.writeFile(folded_path, folded_text);    try writeFixtureSymbolSummary(allocator, workload_dir, callchain_quality);    const children_path = try std.fs.path.join(        allocator,        &.{ workload_dir, "perf.children.summary.json" },    );    const children_rows = [_]capture.perfreport.ChildrenRow{.{        .children_overhead_percent = 88.5,        .self_overhead_percent = 12.25,        .samples = 9,        .symbol = "[.] alloc.refill",        .shared_object = "gpalloc-bench",        .ipc = null,        .ipc_coverage_percent = null,    }};    try capture.perfreport.writeChildrenSummaryFile(children_path, .{        .source_path = "perf.children.tsv",        .total_lost_samples = 0,        .sample_count_text = "10",        .sample_count_approx = 10,        .event = "cycles:P",        .event_count_approx = 1000,        .rows = &children_rows,    });    const allocations_path = try std.fs.path.join(        allocator,        &.{ workload_dir, "allocations.jsonl" },    );    var allocations_file = try sys.fs.cwd().createFile(        fs_io,        allocations_path,        .{ .truncate = true },    );    defer allocations_file.close(fs_io);    var allocations_buffer: [8192]u8 = undefined;    var allocations_writer = allocations_file.writer(fs_io, &allocations_buffer);    const trace_rows = [_]struct {        event: memtrace.Event,        scope: ?[]const u8 = null,    }{        .{ .event = .{ .seq = 1, .kind = .trace_start } },        .{ .event = .{            .seq = 2,            .kind = .allocator,            .allocator_id = 1,            .retains_freed_memory = true,        } },        .{            .event = .{                .seq = 3,                .kind = .alloc,                .allocator_id = 1,                .allocation_id = 1,                .address = 128,                .len = 4096,                .return_address = 2748,            },            .scope = "root/refill",        },        .{            .event = .{                .seq = 4,                .kind = .alloc,                .allocator_id = 1,                .allocation_id = 2,                .address = 8320,                .len = 1024,                .return_address = 2749,            },            .scope = "root/free",        },        .{            .event = .{                .seq = 5,                .kind = .free,                .allocator_id = 1,                .allocation_id = 2,                .address = 8320,                .len = 1024,                .return_address = 2749,            },            .scope = "root/free",        },        .{ .event = .{ .seq = 6, .kind = .trace_stop } },    };    for (trace_rows) |row| {        try row.event.writeJsonLine(&allocations_writer.interface, null, row.scope);    }    try allocations_writer.interface.flush();    const srcline_path = try std.fs.path.join(        allocator,        &.{ workload_dir, "perf.srcline.summary.json" },    );    const srcline_rows = [_]capture.perfreport.SrclineRow{.{        .overhead_percent = 12.25,        .samples = 2,        .source_line = "heap.zig:212",        .symbol = "[.] alloc.refill",        .shared_object = "gpalloc-bench",        .ipc = null,        .ipc_coverage_percent = null,    }};    try capture.perfreport.writeSrclineSummaryFile(srcline_path, .{        .source_path = "perf.srcline.tsv",        .total_lost_samples = 0,        .sample_count_text = "10",        .sample_count_approx = 10,        .event = "cycles:P",        .event_count_approx = 1000,        .rows = &srcline_rows,    });    const offcpu_path = try std.fs.path.join(        allocator,        &.{ workload_dir, "offcpu.summary.json" },    );    const blocked_frames: []const []const u8 = &.{ "futex_wait", "do_futex" };    const blocked_rows = [_]capture.offcpu.BlockedRow{.{        .key = "a",        .source = "offcputime",        .subclass = "synchronization",        .task = "gpalloc-bench",        .stack_kind = "folded",        .weight = 9000,        .weight_unit = "nanoseconds",        .duration_ns = 9000,        .count = null,        .frames = blocked_frames,    }};    try capture.offcpu.writeBlockedSummaryFile(offcpu_path, .{        .source_path = "offcpu.time.txt",        .source = "offcputime",        .weight_unit = "nanoseconds",        .total_weight = 9000,        .total_duration_ns = 9000,        .total_count = null,        .rows = &blocked_rows,    });}fn writeFixtureManifest(    allocator: std.mem.Allocator,    root: []const u8,    run_id: []const u8,    started_unix_ns: i128,    wall_ns: u64,    hostname: []const u8,) !void {    const manifest_path = try std.fs.path.join(        allocator,        &.{ root, "manifest.json" },    );    const finished_unix_ns = started_unix_ns + wall_ns;    const empty_strings: []const []const u8 = &.{};    var file = try sys.fs.cwd().createFile(fs_io, manifest_path, .{ .truncate = true });    defer file.close(fs_io);    var buffer: [8192]u8 = undefined;    var file_writer = file.writer(fs_io, &buffer);    const writer = &file_writer.interface;    var json_writer = pretty_json.Writer.init(writer, .minified);    const document = try json_writer.object();    try document.fields(.{        .schema = "tiny.profiling.run/v1",        .event = "manifest",        .run_id = run_id,        .started_unix_ns = started_unix_ns,    });    try document.field("selection", .{        .suite = "smoke",        .filters = empty_strings,        .workload_count = @as(u8, 1),    });    try document.field("environment", .{        .git = .{            .commit = "abcdef123456",            .branch = "main",            .dirty = false,        },        .zig = .{ .version = "0.16.0" },        .build = .{ .optimize = "ReleaseFast" },        .host = .{            .hostname = hostname,            .os = "linux",            .kernel = "7.0.11",            .arch = "x86_64",            .cpu_model = "AMD Ryzen 7 7800X3D",            .cpu_count = @as(u8, 16),            .cpu_frequency_policy = "policy-a",            .process_cpu_affinity = "0-15",            .process_memory_affinity = "0",        },    });    try document.field("summary", .{        .selected = @as(u8, 1),        .ran = @as(u8, 1),        .passed = @as(u8, 1),        .failed = @as(u8, 0),        .stopped_early = false,        .exit_code = @as(u8, 0),        .started_unix_ns = started_unix_ns,        .finished_unix_ns = finished_unix_ns,        .wall_ns = wall_ns,    });    const artifacts = try document.object("artifacts");    try artifacts.field("root", root);    try artifacts.stringParts("results", &.{ root, "/results.jsonl" });    try artifacts.stringParts("manifest", &.{ root, "/manifest.json" });    try artifacts.stringParts("workloads", &.{ root, "/workloads" });    try artifacts.end();    try document.end();    try writer.flush();}fn writeFixtureStructured(    allocator: std.mem.Allocator,    workload_dir: []const u8,    median_ns: u64,) !void {    const structured_path = try std.fs.path.join(        allocator,        &.{ workload_dir, "structured.jsonl" },    );    var file = try sys.fs.cwd().createFile(fs_io, structured_path, .{ .truncate = true });    defer file.close(fs_io);    var buffer: [8192]u8 = undefined;    var file_writer = file.writer(fs_io, &buffer);    const writer = &file_writer.interface;    try pretty_json.writeMinifiedLine(writer, .{        .schema = "tiny.profiling.structured/v1",        .workload = .{            .name = "gpalloc.allocator",            .package = "lib/gpalloc",            .step = "gpalloc-bench",        },        .source = .{            .kind = "bench_jsonl",            .path = "x",            .line = @as(u8, 1),        },        .row = .{            .schema = "tiny.profiling.metric/v1",            .family = "timing",            .unit = "ns",            .id = "alloc-free",            .name = "alloc-free",            .median_ns = median_ns,            .sample_count = @as(u8, 10),            .confidence_intervals = .{                .median_ns = .{                    .low_ns = median_ns - 5,                    .high_ns = median_ns + 5,                },            },        },    });    try pretty_json.writeMinifiedLine(writer, .{        .schema = "tiny.profiling.structured/v1",        .workload = .{            .name = "gpalloc.allocator",            .package = "lib/gpalloc",            .step = "gpalloc-bench",        },        .source = .{            .kind = "bench_jsonl",            .path = "x",            .line = @as(u8, 2),        },        .row = .{            .schema = "tiny.profiling.metric/v1",            .family = "memory",            .unit = "bytes",            .metric = "allocated_bytes",            .name = "allocated_bytes",            .value = @as(u64, 4096),        },    });    try writer.flush();}fn writeFixtureRun(    allocator: std.mem.Allocator,    profiling_dir: []const u8,    run_id: []const u8,    started_unix_ns: i128,    wall_ns: u64,    median_ns: u64,    hostname: []const u8,    folded: ?[]const u8,    callchain_quality: ?capture.stackcollapse.Summary,) !void {    const root = try std.fs.path.join(allocator, &.{ profiling_dir, run_id });    const workload_dir = try std.fs.path.join(allocator, &.{ root, "workloads", "gpalloc.allocator" });    try sys.fs.createDirPath(workload_dir);    if (folded) |folded_text| {        try writeFixtureCaptureArtifacts(            allocator,            workload_dir,            folded_text,            callchain_quality,        );    }    try writeFixtureManifest(        allocator,        root,        run_id,        started_unix_ns,        wall_ns,        hostname,    );    try writeFixtureStructured(allocator, workload_dir, median_ns);    try writeFixtureResults(        allocator,        root,        workload_dir,        run_id,        started_unix_ns,        wall_ns,        hostname,        folded != null,    );}pub fn writeTestFixture(allocator: std.mem.Allocator, profiling_dir: []const u8) !void {    const baseline_folded =        \\gpalloc-bench;main;alloc;refill 5        \\gpalloc-bench;main;free 5        \\    ;    const baseline_quality: capture.stackcollapse.Summary = .{        .sample_count = 10,        .unique_callchain_count = 2,        .weighted_frame_count = 25,        .resolved_frame_count = 25,        .maximum_depth_frames = 3,    };    try writeFixtureRun(        allocator,        profiling_dir,        "run-100-aaa",        100_000,        60_000_000,        1_000,        "bench-a",        baseline_folded,        baseline_quality,    );    const candidate_folded =        \\gpalloc-bench;main;[unknown];alloc;refill 6        \\gpalloc-bench;main;alloc 3        \\gpalloc-bench;main;free 1        \\    ;    const candidate_quality: capture.stackcollapse.Summary = .{        .sample_count = 10,        .unique_callchain_count = 3,        .weighted_frame_count = 32,        .resolved_frame_count = 26,        .unresolved_frame_count = 6,        .samples_with_unresolved_frames = 6,        .maximum_depth_frames = 4,    };    try writeFixtureRun(        allocator,        profiling_dir,        "run-200-bbb",        200_000,        66_000_000,        1_200,        "bench-a",        candidate_folded,        candidate_quality,    );}test "model loads runs chronologically and builds histories" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const profiling_dir = ".zig-cache/profile-web-model-test";    defer sys.fs.deleteTree(profiling_dir) catch {};    try writeTestFixture(allocator, profiling_dir);    const site = try load(allocator, profiling_dir);    try std.testing.expectEqual(@as(usize, 2), site.runs.len);    try std.testing.expectEqualStrings("run-100-aaa", site.runs[0].manifest.run_id);    try std.testing.expectEqualStrings("run-200-bbb", site.runs[1].manifest.run_id);    try std.testing.expectEqualStrings("smoke", site.runs[0].manifest.suite);    try std.testing.expectEqual(@as(u64, 60_000_000), site.runs[0].manifest.wall_ns.?);    try std.testing.expectEqualStrings("bench-a", site.runs[0].manifest.host.hostname.?);    try std.testing.expectEqualStrings("policy-a", site.runs[0].manifest.host.cpu_frequency_policy.?);    try std.testing.expectEqualStrings("run-200-bbb", site.latest().?.manifest.run_id);    try std.testing.expectEqual(@as(usize, 1), site.histories.len);    const history = site.findHistory("gpalloc.allocator").?;    try std.testing.expectEqualStrings("lib/gpalloc", history.package);    try std.testing.expectEqual(@as(usize, 2), history.wall.len);    try std.testing.expectEqual(@as(f64, 60_000_000), history.wall[0].?);    try std.testing.expectEqual(@as(f64, 66_000_000), history.wall[1].?);    try std.testing.expectEqual(@as(usize, 1), history.metrics.len);    try std.testing.expectEqual(@as(f64, 1_000), history.metrics[0].primary[0].?);    try std.testing.expectEqual(@as(f64, 1_200), history.metrics[0].primary[1].?);    try std.testing.expectEqual(@as(f64, 1_205), history.metrics[0].high[1].?);    try std.testing.expectEqual(@as(usize, 1), history.memory.len);    try std.testing.expectEqual(@as(f64, 4096), history.memory[0].values[1].?);    try std.testing.expectEqual(@as(usize, 2), site.runs[0].run.workloads[0].captures.len);    try std.testing.expectEqual(@as(usize, 2), site.runs[1].run.workloads[0].captures.len);    try std.testing.expectEqualStrings("perf_record", site.runs[1].run.workloads[0].captures[0].kind);    try std.testing.expectEqual(        @as(usize, 1),        site.runs[1].run.workloads[0].acquisition.blocked.position,    );}test "model fixture JSON escapes dynamic host strings" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const profiling_dir = ".zig-cache/profile-web-model-json-escaping-test";    defer sys.fs.deleteTree(profiling_dir) catch {};    try writeFixtureRun(        allocator,        profiling_dir,        "run-escaped",        100_000,        60_000_000,        1_000,        "bench\"line\nhost",        null,        null,    );    const site = try load(allocator, profiling_dir);    try std.testing.expectEqualStrings(        "bench\"line\nhost",        site.runs[0].manifest.host.hostname.?,    );    try std.testing.expectEqualStrings(        "bench\"line\nhost",        site.runs[0].run.host.hostname.?,    );}test "model retains the process placement envelope" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const profiling_dir = ".zig-cache/profile-web-model-placement-test";    defer sys.fs.deleteTree(profiling_dir) catch {};    try writeTestFixture(allocator, profiling_dir);    const site = try load(allocator, profiling_dir);    const host = site.runs[0].manifest.host;    try std.testing.expectEqualStrings("0-15", host.process_cpu_affinity.?);    try std.testing.expectEqualStrings("0", host.process_memory_affinity.?);}test "model leaves acquisition-context wall history gaps" {    const host_value = environment.Host{        .hostname = "bench-a",        .os = "linux",        .kernel = "7.0.11",        .arch = "x86_64",        .cpu_model = "CPU",        .cpu_count = 8,        .cpu_frequency_policy = "policy-a",        .process_cpu_affinity = "0-7",        .process_memory_affinity = "0",    };    const base_workloads = [_]analyze.Workload{.{        .name = "target",        .package = "p",        .step = "bench",        .acquisition = .{ .blocked = .{            .position = 2,            .workload_count = 2,            .predecessors = &.{"a"},        } },        .status = "passed",        .exit_code = 0,        .wall_ns = 10,        .max_rss_kib = null,        .user_s = null,        .system_s = null,        .result_path = null,    }};    const candidate_workloads = [_]analyze.Workload{.{        .name = "target",        .package = "p",        .step = "bench",        .acquisition = .{ .blocked = .{            .position = 2,            .workload_count = 2,            .predecessors = &.{"b"},        } },        .status = "passed",        .exit_code = 0,        .wall_ns = 20,        .max_rss_kib = null,        .user_s = null,        .system_s = null,        .result_path = null,    }};    const entries = [_]Entry{        .{            .dir = "base",            .root = "base",            .manifest = .{                .run_id = "base",                .started_unix_ns = 1,                .wall_ns = 1,                .suite = "smoke",                .git_sha = null,                .git_branch = null,                .git_dirty = null,                .zig_version = null,                .optimize = "ReleaseFast",                .host = host_value,            },            .run = .{                .ref = .{                    .run_id = "base",                    .root = "base",                    .manifest_path = "base/manifest.json",                    .results_path = "base/results.jsonl",                },                .optimize = "ReleaseFast",                .host = host_value,                .workloads = &base_workloads,            },            .recorded = null,        },        .{            .dir = "candidate",            .root = "candidate",            .manifest = .{                .run_id = "candidate",                .started_unix_ns = 2,                .wall_ns = 1,                .suite = "smoke",                .git_sha = null,                .git_branch = null,                .git_dirty = null,                .zig_version = null,                .optimize = "ReleaseFast",                .host = host_value,            },            .run = .{                .ref = .{                    .run_id = "candidate",                    .root = "candidate",                    .manifest_path = "candidate/manifest.json",                    .results_path = "candidate/results.jsonl",                },                .optimize = "ReleaseFast",                .host = host_value,                .workloads = &candidate_workloads,            },            .recorded = null,        },    };    try std.testing.expect(!workloadComparableWithLatest(&entries, 0, "target"));    try std.testing.expect(workloadComparableWithLatest(&entries, 1, "target"));}test "model leaves incompatible host runs as trend gaps" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const profiling_dir = ".zig-cache/profile-web-host-cohort-test";    defer sys.fs.deleteTree(profiling_dir) catch {};    try writeFixtureRun(        allocator,        profiling_dir,        "run-100-aaa",        100_000,        60_000_000,        1_000,        "bench-a",        null,        null,    );    try writeFixtureRun(        allocator,        profiling_dir,        "run-200-bbb",        200_000,        66_000_000,        1_200,        "bench-b",        null,        null,    );    const site = try load(allocator, profiling_dir);    const history = site.findHistory("gpalloc.allocator").?;    try std.testing.expectEqual(@as(?f64, null), history.wall[0]);    try std.testing.expectEqual(@as(f64, 66_000_000), history.wall[1].?);    try std.testing.expectEqual(@as(?f64, null), history.metrics[0].primary[0]);    try std.testing.expectEqual(@as(f64, 1_200), history.metrics[0].primary[1].?);}test "model tolerates a missing profiling directory" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const site = try load(allocator, ".zig-cache/profile-web-does-not-exist");    try std.testing.expectEqual(@as(usize, 0), site.runs.len);    try std.testing.expectEqual(@as(usize, 0), site.histories.len);}

Source: src/profiling/report/root.zig:5

zig
pub const model = @import("model.zig");

Complete caller list for report.model.load

12 direct callers.

Complete caller list for report.model.writeTestFixture

10 direct callers.

Audit

Definitions12
Public names12
Members32
Version26.7.0
Revisiondaab053ee433