Skip to documentation
SLOP

tiny.profiling.experiment.parse

Reference tiny.profiling experiment parse

Defined in experiment.

API (2)

Actions

Public operations.

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

Source

Called byCallsprivate; no linksrc.profiling.commandrunExperimentexperiment.parseparseexperiment.parseload
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsexperiment.parseloadtest; no linksrc.profiling.experiment.parsetest: profiling experiment parses bin...test; no linksrc.profiling.experiment.parsetest: profiling experiment requires b...experiment.model.Metricparseprivate; no linksrc.profiling.experiment.parseparseDesignprivate; no linksrc.profiling.experiment.parseparseVariantprivate; no linksrc.profiling.experiment.parserequiredStringjsonasF64+3 moreexperiment.parseparse
Static calls · unresolved targets: 1 · external targets: 2.

Source: src/profiling/experiment/parse.zig

zig
const std = @import("std");const sys = @import("sys");const profiling = @import("../root.zig");const model = @import("model.zig");const json = profiling.json;const scenario = profiling.scenario;pub fn load(    allocator: std.mem.Allocator,    path: []const u8,) !model.Plan {    const text = try sys.fs.readFileAlloc(        allocator,        path,        model.maximum_plan_bytes,    );    const value = try std.json.parseFromSliceLeaky(        std.json.Value,        allocator,        text,        .{},    );    return try parse(allocator, value);}pub fn parse(    allocator: std.mem.Allocator,    value: std.json.Value,) !model.Plan {    const object = try json.object(value);    const actual_schema = json.string(object.get("schema")) orelse        return error.InvalidExperimentSchema;    if (!std.mem.eql(u8, actual_schema, model.schema)) {        return error.InvalidExperimentSchema;    }    const plan = model.Plan{        .name = try requiredString(object, "name"),        .scenario = try scenario.parse(            allocator,            object.get("scenario") orelse return error.MissingScenario,        ),        .baseline = try parseVariant(allocator, object, "baseline"),        .candidate = try parseVariant(allocator, object, "candidate"),        .metric = model.Metric.parse(            try requiredString(object, "metric"),        ) orelse return error.InvalidExperimentMetric,        .practical_effect_percent = json.asF64(            object.get("practical_effect_percent"),        ) orelse return error.InvalidPracticalEffect,        .seed = json.asU64(object.get("seed")) orelse            return error.InvalidExperimentSeed,        .design = try parseDesign(object.get("design")),    };    try plan.validate();    return plan;}fn parseVariant(    allocator: std.mem.Allocator,    object: std.json.ObjectMap,    field: []const u8,) !model.Variant {    const value = object.get(field) orelse return error.MissingVariant;    const variant = try json.object(value);    const binary = json.string(variant.get("binary"));    const ref_name = json.string(variant.get("ref"));    if ((binary == null) == (ref_name == null)) return error.InvalidVariant;    if (binary) |path| return .{ .binary = path };    return .{ .git_ref = .{        .name = ref_name.?,        .build = try parseBuild(allocator, variant.get("build")),    } };}fn parseBuild(    allocator: std.mem.Allocator,    value: ?std.json.Value,) !?model.Build {    const actual = value orelse return null;    const object = try json.object(actual);    return .{        .argv = try parseArguments(allocator, object.get("argv")),        .artifact = try requiredString(object, "artifact"),        .cwd = json.string(object.get("cwd")),    };}fn parseArguments(    allocator: std.mem.Allocator,    value: ?std.json.Value,) ![]const []const u8 {    const rows = try json.array(value orelse return error.InvalidVariantBuild);    if (rows.items.len == 0 or        rows.items.len > scenario.maximum_arguments)    {        return error.InvalidVariantBuild;    }    const result = try allocator.alloc([]const u8, rows.items.len);    for (rows.items, 0..) |item, index| {        const argument = json.string(item) orelse            return error.InvalidVariantBuild;        if (argument.len == 0 or            argument.len > scenario.maximum_string_bytes)        {            return error.InvalidVariantBuild;        }        result[index] = argument;    }    return result;}fn parseDesign(value: ?std.json.Value) !model.Design {    const actual = value orelse return .{};    const object = try json.object(actual);    return .{        .calibration_pairs = try optionalUsize(            object,            "calibration_pairs",            model.default_calibration_pairs,        ),        .minimum_evaluation_pairs = try optionalUsize(            object,            "minimum_evaluation_pairs",            model.default_minimum_evaluation_pairs,        ),        .maximum_evaluation_pairs = try optionalUsize(            object,            "maximum_evaluation_pairs",            model.default_maximum_evaluation_pairs,        ),    };}fn optionalUsize(    object: std.json.ObjectMap,    field: []const u8,    default: usize,) !usize {    const value = object.get(field) orelse return default;    return std.math.cast(        usize,        json.asU64(value) orelse return error.InvalidExperimentDesign,    ) orelse error.InvalidExperimentDesign;}fn requiredString(    object: std.json.ObjectMap,    field: []const u8,) ![]const u8 {    return json.string(object.get(field)) orelse error.InvalidExperimentPlan;}test "profiling experiment parses binary scenario plans" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const value = try std.json.parseFromSliceLeaky(        std.json.Value,        allocator,        \\{"schema":"tiny.profiling.experiment/v1","name":"startup",        \\ "scenario":{"schema":"tiny.profiling.scenario/v1","name":"cli",        \\   "argv":["{binary}","--version"],"oracle":{"exit_code":0}},        \\ "baseline":{"binary":"base"},"candidate":{"binary":"candidate"},        \\ "metric":"wall_ns","practical_effect_percent":5,"seed":42,        \\ "design":{"calibration_pairs":6,"maximum_evaluation_pairs":40}}    ,        .{},    );    const plan = try parse(allocator, value);    try std.testing.expectEqual(model.Metric.wall_ns, plan.metric);    try std.testing.expectEqual(@as(usize, 6), plan.design.calibration_pairs);    try std.testing.expectEqual(        @as(usize, 40),        plan.design.maximum_evaluation_pairs,    );}test "profiling experiment requires builds for ref command scenarios" {    var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator);    defer arena_state.deinit();    const allocator = arena_state.allocator();    const value = try std.json.parseFromSliceLeaky(        std.json.Value,        allocator,        \\{"schema":"tiny.profiling.experiment/v1","name":"startup",        \\ "scenario":{"schema":"tiny.profiling.scenario/v1","name":"cli",        \\   "argv":["{binary}"]},        \\ "baseline":{"ref":"main"},"candidate":{"binary":"candidate"},        \\ "metric":"wall_ns","practical_effect_percent":5,"seed":42}    ,        .{},    );    try std.testing.expectError(        error.RefCommandRequiresBuild,        parse(allocator, value),    );}

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

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

Complete call list for experiment.parse.parse

8 direct calls.

Audit

Definitions3
Public names3
Members0
Version26.7.0
Revisiondaab053ee433