tiny.profiling.budget
Defined in tiny.profiling.
API (7)
Actions
Public operations.
Types and contracts
Public types and contracts.
Source
Source: src/profiling/budget.zig
zig
const std = @import("std");const catalog = @import("catalog.zig");const memory = @import("memory.zig");pub const Baseline = union(enum) { bootstrap, design_changed, metrics: []const memory.Metric,};pub const Status = enum { bootstrap, design_changed, within_budget, baseline_missing, candidate_missing, baseline_incompatible, regressed,};pub const Gate = enum { pass, bootstrap, fail, pub fn name(self: Gate) []const u8 { return @tagName(self); }};pub const Check = struct { workload: []const u8, baseline_policy: catalog.AllocationBaselinePolicy, budget_percent: f64, baseline_metrics: usize = 0, candidate_metrics: usize = 0, comparable_metrics: usize = 0, violations: usize = 0, zero_baseline_violations: usize = 0, status: Status, pub fn gate(self: Check) Gate { return switch (self.status) { .within_budget => .pass, .bootstrap, .design_changed, .baseline_missing => .bootstrap, .candidate_missing, .baseline_incompatible, .regressed, => .fail, }; }};pub fn evaluate( workload_name: []const u8, baseline: Baseline, candidate: []const memory.Metric,) ?Check { const workload = catalog.find(workload_name) orelse return null; if (!workload.supportsAllocationCounters()) return null; const budget_percent = workload.allocationBudgetPercent().?; var result = Check{ .workload = workload.name, .baseline_policy = workload.allocationBaselinePolicy(), .budget_percent = budget_percent, .candidate_metrics = count(candidate, workload.name), .status = .within_budget, }; if (result.candidate_metrics == 0) { result.status = .candidate_missing; return result; } switch (baseline) { .bootstrap => { result.status = .bootstrap; return result; }, .design_changed => { result.status = .design_changed; return result; }, .metrics => |baseline_metrics| { result.baseline_metrics = count(baseline_metrics, workload.name); if (result.baseline_metrics == 0) { result.status = .baseline_missing; return result; } for (candidate) |candidate_metric| { if (!belongsTo(candidate_metric, workload.name)) continue; const base_metric = find( baseline_metrics, workload.name, candidate_metric.key, candidate_metric.unit, ) orelse continue; result.comparable_metrics += 1; if (!exceeds(base_metric.value, candidate_metric.value, budget_percent)) { continue; } result.violations += 1; if (base_metric.value <= 0 and candidate_metric.value > base_metric.value) { result.zero_baseline_violations += 1; } } if (result.comparable_metrics == 0) { result.status = .baseline_incompatible; } else if (result.violations != 0) { result.status = .regressed; } return result; }, }}fn count(metrics: []const memory.Metric, workload_name: []const u8) usize { var result: usize = 0; for (metrics) |metric| { if (belongsTo(metric, workload_name)) result += 1; } return result;}fn belongsTo(metric: memory.Metric, workload_name: []const u8) bool { return std.mem.eql(u8, metric.workload, workload_name) and memory.isAllocationMetric(metric);}fn find( metrics: []const memory.Metric, workload_name: []const u8, key: []const u8, unit: memory.Unit,) ?memory.Metric { for (metrics) |metric| { if (!belongsTo(metric, workload_name)) continue; if (!std.mem.eql(u8, metric.key, key)) continue; if (metric.unit != unit) continue; return metric; } return null;}fn exceeds(baseline_value: f64, candidate_value: f64, budget_percent: f64) bool { if (!std.math.isFinite(baseline_value) or !std.math.isFinite(candidate_value)) { return true; } if (baseline_value <= 0) return candidate_value > baseline_value; const percent = ((candidate_value - baseline_value) / baseline_value) * 100; return percent >= budget_percent;}fn testMetric(key: []const u8, value: f64) memory.Metric { return .{ .workload = "gpalloc.allocator", .key = key, .label = key, .source_kind = "bench_jsonl", .source_path = "bench.jsonl", .source_line = 1, .unit = .bytes, .value = value, };}test "allocation budget checks bootstrap and candidate coverage" { const candidate = [_]memory.Metric{testMetric("small|alloc_bytes_per_eval", 100)}; const bootstrap = evaluate( "gpalloc.allocator", .bootstrap, &candidate, ).?; try std.testing.expectEqual(Status.bootstrap, bootstrap.status); try std.testing.expectEqual(Gate.bootstrap, bootstrap.gate()); const changed = evaluate( "gpalloc.allocator", .design_changed, &candidate, ).?; try std.testing.expectEqual(Status.design_changed, changed.status); try std.testing.expectEqual(Gate.bootstrap, changed.gate()); const missing = evaluate( "gpalloc.allocator", .bootstrap, &.{}, ).?; try std.testing.expectEqual(Status.candidate_missing, missing.status); try std.testing.expectEqual(Gate.fail, missing.gate());}test "allocation budget checks per-workload growth and zero baselines" { const baseline = [_]memory.Metric{ testMetric("small|alloc_bytes_per_eval", 100), testMetric("zero|alloc_bytes_per_eval", 0), }; const within = [_]memory.Metric{ testMetric("small|alloc_bytes_per_eval", 129), testMetric("zero|alloc_bytes_per_eval", 0), }; const passing = evaluate( "gpalloc.allocator", .{ .metrics = &baseline }, &within, ).?; try std.testing.expectEqual(Status.within_budget, passing.status); try std.testing.expectEqual(Gate.pass, passing.gate()); const regressed = [_]memory.Metric{ testMetric("small|alloc_bytes_per_eval", 130), testMetric("zero|alloc_bytes_per_eval", 1), }; const failing = evaluate( "gpalloc.allocator", .{ .metrics = &baseline }, ®ressed, ).?; try std.testing.expectEqual(Status.regressed, failing.status); try std.testing.expectEqual(@as(usize, 2), failing.violations); try std.testing.expectEqual(@as(usize, 1), failing.zero_baseline_violations); try std.testing.expectEqual(Gate.fail, failing.gate());}test "allocation budget checks baseline coverage" { const baseline = [_]memory.Metric{testMetric("old", 100)}; const candidate = [_]memory.Metric{testMetric("new", 100)}; const incompatible = evaluate( "gpalloc.allocator", .{ .metrics = &baseline }, &candidate, ).?; try std.testing.expectEqual(Status.baseline_incompatible, incompatible.status); const missing = evaluate( "gpalloc.allocator", .{ .metrics = &.{} }, &candidate, ).?; try std.testing.expectEqual(Status.baseline_missing, missing.status); try std.testing.expectEqual(Gate.bootstrap, missing.gate()); try std.testing.expect(evaluate("choir.compiler", .bootstrap, &candidate) == null);}Source: src/profiling/root.zig:15
zig
pub const budget = @import("budget.zig");Audit
| Definitions | 8 |
|---|---|
| Public names | 8 |
| Members | 22 |
| Version | 26.7.0 |
| Revision | daab053ee433 |