tiny.profiling.driver.schedule
Defined in driver.
API (1)
Actions
Public operations.
Source
Source: src/profiling/driver/root.zig:12
zig
pub const schedule = @import("schedule.zig");Source: src/profiling/driver/schedule.zig
zig
const std = @import("std");const pretty_usage = @import("pretty_usage");const sys = @import("sys");const catalog = @import("../root.zig").catalog;const order = @import("../root.zig").order;const plan = @import("../root.zig").plan;const record = @import("../root.zig").record;const InterleavedWorkload = @import("root.zig").model.InterleavedWorkload;const RunProgress = @import("root.zig").model.RunProgress;const WorkloadContext = @import("root.zig").model.WorkloadContext;const absoluteExecutionArtifactEnv = @import("root.zig").paths.absoluteExecutionArtifactEnv;const aggregateMeasuredCommand = @import("root.zig").acquire.aggregateMeasuredCommand;const aggregateUnmeasuredFailure = @import("root.zig").acquire.aggregateUnmeasuredFailure;const failureExitCode = @import("root.zig").validation.failureExitCode;const initializeWorkload = @import("root.zig").prepare.initializeWorkload;const makeResetTestPaths = @import("fixture/root.zig").makeResetTestPaths;const prepareWorkload = @import("root.zig").prepare.prepareWorkload;const recordCompletedWorkload = @import("root.zig").publish.recordCompletedWorkload;const resetTestContext = @import("fixture/root.zig").resetTestContext;const resetTestPrepared = @import("fixture/root.zig").resetTestPrepared;const resetTestWorkload = @import("fixture/root.zig").resetTestWorkload;const runMeasuredCommand = @import("root.zig").acquire.runMeasuredCommand;const runWarmups = @import("root.zig").prepare.runWarmups;const writeInterleaveProgress = @import("root.zig").progress.writeInterleaveProgress;pub fn runInterleavedWorkloads( context: *const WorkloadContext, seed: u64,) !RunProgress { const backing_allocator = context.backing_allocator; const selected = try plan.collect(backing_allocator, context.request.selection); defer backing_allocator.free(selected); try order.validateDesign(selected.len, context.request.measure_repeat); const selected_names = try backing_allocator.alloc([]const u8, selected.len); defer backing_allocator.free(selected_names); for (selected, 0..) |workload, index| selected_names[index] = workload.name; const entries = try order.schedule( backing_allocator, selected.len, context.request.measure_repeat, seed, ); defer backing_allocator.free(entries); const states = try backing_allocator.alloc(InterleavedWorkload, selected.len); defer backing_allocator.free(states); var initialized: usize = 0; defer for (states[0..initialized]) |*state| state.arena.deinit(); for (selected, 0..) |workload, index| { states[index] = .{ .arena = std.heap.ArenaAllocator.init(backing_allocator), .workload = workload, .index = index, .prepared = undefined, .started_unix_ns = 0, .finished_unix_ns = 0, .setup = null, .prepare = null, .setup_failed = false, .prepare_failed = false, .execution = null, }; initialized += 1; const allocator = states[index].arena.allocator(); states[index].prepared = try prepareWorkload(allocator, context, workload); try pretty_usage.Terminal.stderr(allocator, .{}).writeTextFmt( "profile: {s}\n", .{states[index].prepared.command}, ); states[index].started_unix_ns = sys.time.realNanoTimestamp(); try initializeInterleaved(allocator, context, &states[index]); } try pretty_usage.Terminal.stderr(backing_allocator, .{}).writeTextFmt( "profile: random interleaving {d} process acquisitions across {d} workloads, seed {d}\n", .{ entries.len, selected.len, seed }, ); for (entries) |entry| { const state = &states[entry.workload_index]; try runInterleavedEntry(context, state, entry, entries.len); } var progress = RunProgress{ .ran = states.len, .failures = 0, .first_failure_exit_code = 0, .stopped_early = false, }; for (states) |*state| { if (state.execution == null) return error.InvalidInterleaveSchedule; const allocator = state.arena.allocator(); const acquisition = try order.interleavedContext( allocator, selected_names, entries, state.index, context.request.measure_repeat, seed, ); const exit_code = try recordCompletedWorkload( allocator, context, state.workload, state.index, state.prepared, state.completed(), acquisition, state.started_unix_ns, state.finished_unix_ns, ); if (exit_code == 0) continue; progress.failures += 1; if (progress.first_failure_exit_code == 0) { progress.first_failure_exit_code = failureExitCode(exit_code); } } return progress;}fn initializeInterleaved( allocator: std.mem.Allocator, context: *const WorkloadContext, state: *InterleavedWorkload,) !void { const initialization = try initializeWorkload( allocator, context, state.prepared, ); state.setup = initialization.setup; state.prepare = initialization.prepare; state.setup_failed = initialization.setup_failed; state.prepare_failed = initialization.prepare_failed; if (initialization.failure) |failure| { state.execution = failure; state.finished_unix_ns = sys.time.realNanoTimestamp(); }}fn runInterleavedEntry( context: *const WorkloadContext, state: *InterleavedWorkload, entry: order.Entry, entry_count: usize,) !void { if (state.failed()) return; const allocator = state.arena.allocator(); if (context.progress_output == .terminal) { try writeInterleaveProgress( allocator, state.workload.name, entry, entry_count, context.request.measure_repeat, ); } if (!try interleavedWarmupSucceeded(allocator, context, state)) return; if (@as(usize, entry.repetition_index) != state.executions.items.len) { return error.InvalidInterleaveSchedule; } const execution_paths = try record.executionPaths( allocator, state.prepared.paths, context.request.measure_repeat, @as(usize, entry.repetition_index) + 1, ); const artifacts = try absoluteExecutionArtifactEnv(allocator, execution_paths); const measurement = try runMeasuredCommand( allocator, context, state.workload, state.prepared, state.prepared.wrapped.argv, artifacts, .measurement, .measurement, entry.repetition_index + 1, &state.resets, ); const result = measurement.execution; if (measurement.measured) { try state.executions.append(allocator, .{ .index = @as(usize, entry.repetition_index) + 1, .result = result, .paths = execution_paths, .acquisition_position = entry.position, }); } else { state.reset_failed = true; } if (measurement.host_state) |window| { try state.host_state_windows.append(allocator, window); } state.execution = aggregateMeasuredCommand(state.execution, measurement); state.finished_unix_ns = sys.time.realNanoTimestamp();}fn interleavedWarmupSucceeded( allocator: std.mem.Allocator, context: *const WorkloadContext, state: *InterleavedWorkload,) !bool { if (state.warmup_attempted) return true; state.warmup_attempted = true; const warmup = try runWarmups( allocator, context, state.workload, state.prepared, &state.resets, ); state.warmup_executions = warmup.executions; const failure = warmup.failure orelse return true; state.warmup_failed = !warmup.reset_failed; state.reset_failed = warmup.reset_failed; state.execution = if (warmup.reset_failed) aggregateUnmeasuredFailure(null, failure) else failure; state.finished_unix_ns = sys.time.realNanoTimestamp(); return false;}test "profiling driver maps interleaved measured execution artifacts" { var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const root = try tmp.parent_dir.realPathFileAlloc( std.testing.io, tmp.sub_path[0..], allocator, ); const paths = try makeResetTestPaths(allocator, root); var parent = sys.process.Environ.Map.init(allocator); try parent.put("PATH", "/usr/bin:/bin"); var workload = resetTestWorkload(&.{"/bin/true"}, &.{}); workload.reset = null; const child_argv = [_][]const u8{ "/bin/sh", "-c", "printf '%s' \"$BENCH_JSONL\"" }; const context = resetTestContext(allocator, &parent, paths.run, 0, 3); var state = InterleavedWorkload{ .arena = std.heap.ArenaAllocator.init(std.testing.allocator), .workload = workload, .index = 0, .prepared = undefined, .started_unix_ns = sys.time.realNanoTimestamp(), .finished_unix_ns = 0, .setup = null, .prepare = null, .setup_failed = false, .prepare_failed = false, .execution = null, }; defer state.arena.deinit(); const state_allocator = state.arena.allocator(); state.prepared = try resetTestPrepared( state_allocator, &parent, workload, paths.workload, &child_argv, ); try initializeInterleaved(state_allocator, &context, &state); for ([_]usize{ 2, 5, 6 }, 0..) |position, index| { try runInterleavedEntry(&context, &state, .{ .workload_index = 0, .repetition_index = @intCast(index), .position = position, }, 6); } try std.testing.expectEqual(@as(usize, 3), state.executions.items.len); for (state.executions.items, [_]usize{ 2, 5, 6 }, 0..) |execution, position, index| { try std.testing.expectEqual(index + 1, execution.index); try std.testing.expectEqual(@as(?usize, position), execution.acquisition_position); try std.testing.expect((execution.result.pid orelse 0) > 0); const suffix = try std.fmt.allocPrint(allocator, "/{d:0>3}", .{index + 1}); try std.testing.expect(std.mem.endsWith(u8, execution.paths.?.root, suffix)); }}test "profiling driver suppresses interleaved positions after preparation failure" { var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const root = try tmp.parent_dir.realPathFileAlloc( std.testing.io, tmp.sub_path[0..], allocator, ); const paths = try makeResetTestPaths(allocator, root); var parent = sys.process.Environ.Map.init(allocator); try parent.put("PATH", "/usr/bin:/bin"); const environment = [_]catalog.EnvironmentOverride{.{ .name = "HOME", .value = root, }}; var workload = resetTestWorkload(&.{ "/bin/sh", "-c", "printf reset > \"$HOME/reset\"", }, &environment); workload.prepare = .{ .argv = &.{ "/bin/sh", "-c", "printf interleaved-prepare; exit 17", } }; const child_argv = [_][]const u8{ "/bin/sh", "-c", "printf product > \"$HOME/product\"", }; const context = resetTestContext(allocator, &parent, paths.run, 0, 3); var state = InterleavedWorkload{ .arena = std.heap.ArenaAllocator.init(std.testing.allocator), .workload = workload, .index = 0, .prepared = undefined, .started_unix_ns = sys.time.realNanoTimestamp(), .finished_unix_ns = 0, .setup = null, .prepare = null, .setup_failed = false, .prepare_failed = false, .execution = null, }; defer state.arena.deinit(); const state_allocator = state.arena.allocator(); state.prepared = try resetTestPrepared( state_allocator, &parent, workload, paths.workload, &child_argv, ); try initializeInterleaved(state_allocator, &context, &state); for (0..3) |index| { try runInterleavedEntry(&context, &state, .{ .workload_index = 0, .repetition_index = @intCast(index), .position = index + 1, }, 3); } try std.testing.expect(state.failed()); try std.testing.expect(!state.setup_failed); try std.testing.expect(state.prepare_failed); try std.testing.expectEqual(@as(i64, 17), state.execution.?.exit_code); try std.testing.expect(state.execution.?.pid == null); try std.testing.expectEqual(@as(u64, 0), state.execution.?.wall_ns); try std.testing.expect(state.execution.?.resource_usage_source == null); try std.testing.expect(state.execution.?.maxrss_kib == null); try std.testing.expectEqual(@as(usize, 0), state.resets.items.len); try std.testing.expectEqual(@as(usize, 0), state.executions.items.len); try std.testing.expectEqual(@as(usize, 0), state.host_state_windows.items.len); const prepare = state.prepare.?; try std.testing.expect((prepare.execution.pid orelse 0) > 0); try std.testing.expectEqual(@as(i64, 17), prepare.execution.exit_code); try std.testing.expectEqualStrings( "interleaved-prepare", try sys.fs.readFileAlloc(allocator, prepare.stdout_path, 4096), ); const suppressed_paths = [_][]const u8{ "reset", "product" }; for (suppressed_paths) |name| { const path = try std.fs.path.join(allocator, &.{ root, name }); try std.testing.expectError(error.FileNotFound, sys.fs.statFile(path)); }}test "profiling driver skips later interleaved positions after reset failure" { var tmp = std.testing.tmpDir(.{}); defer tmp.cleanup(); var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); const root = try tmp.parent_dir.realPathFileAlloc( std.testing.io, tmp.sub_path[0..], allocator, ); const paths = try makeResetTestPaths(allocator, root); var base_environment = sys.process.Environ.Map.init(allocator); try base_environment.put("PATH", "/usr/bin:/bin"); const environment = [_]catalog.EnvironmentOverride{.{ .name = "HOME", .value = root }}; const reset_argv = [_][]const u8{ "/bin/sh", "-c", "count=0; test ! -f \"$HOME/reset-count\" || count=$(cat \"$HOME/reset-count\"); count=$((count + 1)); printf '%s' \"$count\" > \"$HOME/reset-count\"; printf 'reset\\n' >> \"$HOME/order\"; test \"$count\" -lt 2 || exit 11", }; const child_argv = [_][]const u8{ "/bin/sh", "-c", "printf 'child\\n' >> \"$HOME/order\"", }; var workload = resetTestWorkload(&reset_argv, &environment); workload.prepare = .{ .argv = &.{ "/bin/sh", "-c", "printf 'prepare\\n' >> \"$HOME/order\"", } }; const context = resetTestContext(allocator, &base_environment, paths.run, 0, 3); var state = InterleavedWorkload{ .arena = std.heap.ArenaAllocator.init(std.testing.allocator), .workload = workload, .index = 0, .prepared = undefined, .started_unix_ns = sys.time.realNanoTimestamp(), .finished_unix_ns = 0, .setup = null, .prepare = null, .setup_failed = false, .prepare_failed = false, .execution = null, }; defer state.arena.deinit(); const state_allocator = state.arena.allocator(); state.prepared = try resetTestPrepared( state_allocator, &base_environment, workload, paths.workload, &child_argv, ); try initializeInterleaved(state_allocator, &context, &state); try std.testing.expect(!state.prepare_failed); try std.testing.expect((state.prepare.?.execution.pid orelse 0) > 0); try runInterleavedEntry(&context, &state, .{ .workload_index = 0, .repetition_index = 0, .position = 1, }, 3); try runInterleavedEntry(&context, &state, .{ .workload_index = 0, .repetition_index = 1, .position = 2, }, 3); try runInterleavedEntry(&context, &state, .{ .workload_index = 0, .repetition_index = 2, .position = 3, }, 3); try std.testing.expect(state.failed()); try std.testing.expect(state.reset_failed); try std.testing.expectEqual(@as(usize, 2), state.resets.items.len); try std.testing.expectEqual(@as(usize, 1), state.executions.items.len); var expected = state.executions.items[0].result; expected.pid = null; expected.exit_code = 11; try std.testing.expect(std.meta.eql(expected, state.execution.?)); const order_path = try std.fs.path.join(allocator, &.{ root, "order" }); const order_text = try sys.fs.readFileAlloc(allocator, order_path, 4096); try std.testing.expectEqualStrings("prepare\nreset\nchild\nreset\n", order_text);}Complete call list for driver.schedule.runInterleavedWorkloads
9 direct calls.
tiny.profiling.driver.prepare.prepareWorkload[function] atsrc/profiling/driver/prepare.zig:23tiny.profiling.driver.publish.recordCompletedWorkload[function] atsrc/profiling/driver/publish.zig:20src.profiling.driver.schedule.initializeInterleaved[function] — private; no exact target atsrc/profiling/driver/schedule.zig:120in nearest public ownertiny.profiling.driver.schedulesrc.profiling.driver.schedule.runInterleavedEntry[function] — private; no exact target atsrc/profiling/driver/schedule.zig:140in nearest public ownertiny.profiling.driver.scheduletiny.profiling.driver.validation.failureExitCode[function] atsrc/profiling/driver/validation.zig:154tiny.profiling.order.interleavedContext[function] atsrc/profiling/order.zig:156tiny.profiling.order.schedule[function] atsrc/profiling/order.zig:120tiny.profiling.order.validateDesign[function] atsrc/profiling/order.zig:105tiny.profiling.plan.collect[function] atsrc/profiling/plan.zig:107
Audit
| Definitions | 2 |
|---|---|
| Public names | 2 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |