tiny.profiling.analyze.ordering
Defined in analyze.
API (2)
Actions
Public operations.
Source
Source: src/profiling/analyze/ordering.zig
zig
const std = @import("std");const sys = @import("sys");const host = @import("../root.zig").host;const measurement = @import("../root.zig").measurement;const order = @import("../root.zig").order;const ComparisonSupport = @import("root.zig").model.ComparisonSupport;const OrderEffectRow = @import("root.zig").model.OrderEffectRow;const OrderEffectStatus = @import("root.zig").model.OrderEffectStatus;const OrderEffectSupport = @import("root.zig").model.OrderEffectSupport;const OrderEffectTestFixture = @import("fixture/root.zig").OrderEffectTestFixture;const OrderEffects = @import("root.zig").model.OrderEffects;const Run = @import("root.zig").model.Run;const Workload = @import("root.zig").model.Workload;const comparisonSupport = @import("root.zig").compare.comparisonSupport;const orderEffectTestFixture = @import("fixture/root.zig").orderEffectTestFixture;const sameOptionalString = @import("root.zig").model.sameOptionalString;const sameStrings = @import("root.zig").model.sameStrings;pub fn buildOrderEffects( allocator: std.mem.Allocator, base: Run, candidate: Run,) !?OrderEffects { const base_method = runAcquisitionMethod(base) orelse return null; const candidate_method = runAcquisitionMethod(candidate) orelse return null; if (base_method == candidate_method) return null; const fixed_is_baseline = base_method == .blocked and candidate_method == .random_interleaved; if (!fixed_is_baseline and !(base_method == .random_interleaved and candidate_method == .blocked)) { return null; } const fixed = if (fixed_is_baseline) base else candidate; const random = if (fixed_is_baseline) candidate else base; const environment_support = comparisonSupport(fixed, random); const support = orderEffectSupport(fixed, random, environment_support); if (support != .supported) return .{ .support = support, .environment_support = environment_support, .fixed_run_id = fixed.ref.run_id, .random_run_id = random.ref.run_id, .fixed_is_baseline = fixed_is_baseline, .status = .unsupported, .rows = &.{}, }; const summary = try summarizeOrderEffects(allocator, fixed, random); return .{ .support = .supported, .environment_support = environment_support, .fixed_run_id = fixed.ref.run_id, .random_run_id = random.ref.run_id, .fixed_is_baseline = fixed_is_baseline, .status = summary.status, .rows = summary.rows, };}const OrderEffectSummary = struct { status: OrderEffectStatus, rows: []const OrderEffectRow,};fn summarizeOrderEffects( allocator: std.mem.Allocator, fixed: Run, random: Run,) !OrderEffectSummary { const rows = try allocator.alloc(OrderEffectRow, fixed.workloads.len); var status = OrderEffectStatus.no_order_effect_observed; for (fixed.workloads, random.workloads, rows) |fixed_workload, random_workload, *row| { row.* = try summarizeOrderEffectWorkload( allocator, fixed_workload, random_workload, ); status = combinedOrderEffectStatus(status, row.classification); } return .{ .status = status, .rows = rows };}fn summarizeOrderEffectWorkload( allocator: std.mem.Allocator, fixed: Workload, random: Workload,) !OrderEffectRow { var fixed_scratch: [host.process.max_executions]f64 = undefined; var random_scratch: [host.process.max_executions]f64 = undefined; const fixed_samples = try measurement.wallEffectSamples( &fixed_scratch, fixed.executions, null, ); const random_samples = try measurement.wallEffectSamples( &random_scratch, random.executions, null, ); const result = try order.contrast.summarize( allocator, fixed.name, fixed_samples, random_samples, ); return .{ .workload = fixed.name, .fixed_acquisition = fixed.acquisition, .random_acquisition = random.acquisition, .fixed_count = result.fixed_count, .random_count = result.random_count, .fixed_mean_ns = result.fixed_mean_ns, .random_mean_ns = result.random_mean_ns, .mean_percent_change = result.mean_percent_change, .effect_low_percent = if (result.effect_interval) |value| value.low else null, .effect_high_percent = if (result.effect_interval) |value| value.high else null, .classification = result.classification, };}fn combinedOrderEffectStatus( status: OrderEffectStatus, classification: order.contrast.Classification,) OrderEffectStatus { return switch (classification) { .order_sensitive_candidate => .order_sensitive_candidate, .insufficient_repetitions => if (status == .no_order_effect_observed) .insufficient_repetitions else status, .no_order_effect_observed => status, };}fn runAcquisitionMethod(run_value: Run) ?order.Method { const first = if (run_value.workloads.len != 0) run_value.workloads[0] else return null; return first.acquisition.method();}fn orderEffectSupport( fixed: Run, random: Run, environment_support: ComparisonSupport,) OrderEffectSupport { if (environment_support != .supported) return .environment_mismatch; const fixed_sha = fixed.git_sha orelse return .code_identity_missing; const random_sha = random.git_sha orelse return .code_identity_missing; const fixed_dirty = fixed.git_dirty orelse return .code_identity_missing; const random_dirty = random.git_dirty orelse return .code_identity_missing; if (!std.mem.eql(u8, fixed_sha, random_sha)) return .code_identity_mismatch; if (fixed_dirty or random_dirty) return .dirty_code_identity; if (!sameCohort(fixed, random)) return .cohort_mismatch; for (fixed.workloads, random.workloads) |fixed_workload, random_workload| { const support = workloadOrderEffectSupport(fixed_workload, random_workload); if (support != .supported) return support; } return .supported;}fn workloadOrderEffectSupport( fixed: Workload, random: Workload,) OrderEffectSupport { if (fixed.exit_code != 0 or random.exit_code != 0) return .workload_failure; if (!fixed.command_identity_recorded or !random.command_identity_recorded or fixed.command_argv.len == 0 or random.command_argv.len == 0) { return .command_identity_missing; } if (!sameOptionalString(fixed.command_cwd, random.command_cwd) or !sameStrings(fixed.command_argv, random.command_argv)) { return .command_identity_mismatch; } if (!fixed.scope_recorded or !random.scope_recorded) { return .execution_scope_missing; } if (!std.mem.eql(u8, fixed.scope, random.scope)) { return .execution_scope_mismatch; } if (!fixed.warmup_recorded or !random.warmup_recorded) { return .warmup_design_missing; } if (fixed.warmup_count != random.warmup_count) return .warmup_design_mismatch; if (!fixed.profiler_configuration_recorded or !random.profiler_configuration_recorded) { return .profiler_configuration_missing; } if (workloadHasProfilerCapture(fixed) or workloadHasProfilerCapture(random)) { return .profiler_capture_present; } const random_design = switch (random.acquisition) { .blocked => return .cohort_mismatch, .random_interleaved => |value| value, }; if (fixed.executions.len != random_design.repeat_count or random.executions.len != random_design.repeat_count) { return .repetition_design_mismatch; } if (!fixed.measurement_recorded or !random.measurement_recorded or fixed.executions.len < order.contrast.minimum_repetitions or random.executions.len < order.contrast.minimum_repetitions) { return .raw_measurements_missing; } return .supported;}fn sameCohort(fixed: Run, random: Run) bool { if (!fixed.selection_known or !random.selection_known or fixed.workloads.len < 2 or fixed.workloads.len != random.workloads.len) { return false; } for (fixed.workloads, random.workloads) |fixed_workload, random_workload| { if (!std.mem.eql(u8, fixed_workload.name, random_workload.name)) { return false; } const fixed_design = switch (fixed_workload.acquisition) { .blocked => |value| value, .random_interleaved => return false, }; const random_design = switch (random_workload.acquisition) { .blocked => return false, .random_interleaved => |value| value, }; if (fixed_design.workload_count != fixed.workloads.len or random_design.workload_count != random.workloads.len) { return false; } } return true;}fn workloadHasProfilerCapture(workload: Workload) bool { if (workload.captures.len != 0 or workload.capture_perturbation != null or workload.perf_stat != null or workload.causal_enabled or workload.tracy_enabled or workload.allocations_enabled) { return true; } if (workload.analysisArtifacts()) |artifacts| { if (artifactHasBytes(artifacts.allocations)) return true; } for (workload.executions) |execution| { const artifacts = execution.artifacts orelse continue; if (artifactHasBytes(artifacts.allocations)) return true; } return false;}fn artifactHasBytes(path: []const u8) bool { const stat = sys.fs.statFile(path) catch |err| return switch (err) { error.FileNotFound => false, else => true, }; return stat.size != 0;}test "profiling analysis diagnoses fixed versus interleaved acquisition" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const fixture = try orderEffectTestFixture(allocator); const effects = (try buildOrderEffects(allocator, fixture.fixed, fixture.random)).?; try std.testing.expectEqual(OrderEffectSupport.supported, effects.support); try std.testing.expectEqual( OrderEffectStatus.order_sensitive_candidate, effects.status, ); try std.testing.expect(effects.fixed_is_baseline); try std.testing.expectEqual(@as(usize, 2), effects.rows.len); try std.testing.expectEqual( order.contrast.Classification.order_sensitive_candidate, effects.rows[0].classification, ); try std.testing.expectEqual( order.contrast.Classification.no_order_effect_observed, effects.rows[1].classification, ); const reversed = (try buildOrderEffects(allocator, fixture.random, fixture.fixed)).?; try std.testing.expect(!reversed.fixed_is_baseline); try std.testing.expectEqualStrings("fixed", reversed.fixed_run_id); try std.testing.expectEqualStrings("random", reversed.random_run_id);}pub fn expectOrderEffectWorkloadSupport( allocator: std.mem.Allocator, fixture: OrderEffectTestFixture, altered_first: Workload, expected: OrderEffectSupport,) !void { var workloads = [_]Workload{ altered_first, fixture.random.workloads[1] }; var altered = fixture.random; altered.workloads = &workloads; try std.testing.expectEqual( expected, (try buildOrderEffects(allocator, fixture.fixed, altered)).?.support, );}test "profiling order diagnostics accept an explicitly recorded root cwd" { 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 fixed_workloads = [_]Workload{ fixture.fixed.workloads[0], fixture.fixed.workloads[1], }; var random_workloads = [_]Workload{ fixture.random.workloads[0], fixture.random.workloads[1], }; fixed_workloads[0].command_cwd = null; random_workloads[0].command_cwd = null; var fixed = fixture.fixed; var random = fixture.random; fixed.workloads = &fixed_workloads; random.workloads = &random_workloads; try std.testing.expectEqual( OrderEffectSupport.supported, (try buildOrderEffects(allocator, fixed, random)).?.support, );}Source: src/profiling/analyze/root.zig:6
zig
pub const ordering = @import("ordering.zig");Audit
| Definitions | 3 |
|---|---|
| Public names | 3 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |