From 7e0210b6ee257414cbbe78e9f3eed22c9ba3176b Mon Sep 17 00:00:00 2001 From: adybag14-cyber Date: Fri, 29 May 2026 01:36:34 +0100 Subject: [PATCH 1/2] test(zigux): restack lane16 list_sort bench replay --- zigux/tests/phase1_list_sort_bench_replay.zig | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 zigux/tests/phase1_list_sort_bench_replay.zig diff --git a/zigux/tests/phase1_list_sort_bench_replay.zig b/zigux/tests/phase1_list_sort_bench_replay.zig new file mode 100644 index 00000000000000..0120eebdd29a68 --- /dev/null +++ b/zigux/tests/phase1_list_sort_bench_replay.zig @@ -0,0 +1,99 @@ +const std = @import("std"); +const list_sort = @import("list_sort"); + +const iterations_list_sort = 1_000; +const expected_checksum_per_iteration: u64 = 690; +const expected_checksum: u64 = expected_checksum_per_iteration * iterations_list_sort; + +const Entry = struct { + key: i32, + ordinal: usize, + node: list_sort.ListHead = .{}, +}; + +const cmp = struct { + fn compare(_: ?*anyopaque, a: *const list_sort.ListHead, b: *const list_sort.ListHead) i32 { + const lhs: *const Entry = @fieldParentPtr("node", a); + const rhs: *const Entry = @fieldParentPtr("node", b); + if (lhs.key < rhs.key) return -1; + if (lhs.key > rhs.key) return 1; + return 0; + } +}.compare; + +fn seedEntries() [128]Entry { + var entries: [128]Entry = undefined; + for (&entries, 0..) |*entry, idx| { + entry.* = .{ + .key = @intCast((127 - idx) % 11), + .ordinal = idx, + }; + } + return entries; +} + +fn runListSortBench() !u64 { + var checksum: u64 = 0; + var iter: usize = 0; + while (iter < iterations_list_sort) : (iter += 1) { + var head: list_sort.ListHead = .{}; + head.init(); + var entries = seedEntries(); + for (&entries) |*entry| { + list_sort.listAddTail(&entry.node, &head); + } + + list_sort.listSort(null, &head, cmp); + + var current = head.next; + while (current != &head) : (current = current.?.next) { + const entry: *const Entry = @fieldParentPtr("node", current.?); + checksum +%= @intCast(entry.key + @as(i32, @intCast(entry.ordinal & 1))); + try std.testing.expect(current.?.next.?.prev == current.?); + try std.testing.expect(current.?.prev.?.next == current.?); + } + } + + return checksum; +} + +test "phase1 list_sort bench replay preserves stable key order" { + var head: list_sort.ListHead = .{}; + head.init(); + var entries = seedEntries(); + for (&entries) |*entry| { + list_sort.listAddTail(&entry.node, &head); + } + + list_sort.listSort(null, &head, cmp); + + var last_key: ?i32 = null; + var previous_duplicate_ordinal: ?usize = null; + var item_count: usize = 0; + var per_iteration_checksum: u64 = 0; + var current = head.next; + while (current != &head) : (current = current.?.next) { + const entry: *const Entry = @fieldParentPtr("node", current.?); + if (last_key) |key| { + try std.testing.expect(key <= entry.key); + if (key == entry.key) { + try std.testing.expect(previous_duplicate_ordinal.? < entry.ordinal); + } else { + previous_duplicate_ordinal = null; + } + } + last_key = entry.key; + previous_duplicate_ordinal = entry.ordinal; + per_iteration_checksum +%= @intCast(entry.key + @as(i32, @intCast(entry.ordinal & 1))); + try std.testing.expect(current.?.next.?.prev == current.?); + try std.testing.expect(current.?.prev.?.next == current.?); + item_count += 1; + } + + try std.testing.expectEqual(@as(usize, 128), item_count); + try std.testing.expectEqual(expected_checksum_per_iteration, per_iteration_checksum); +} + +test "phase1 list_sort bench replay keeps the exact 1000-iteration checksum" { + try std.testing.expectEqual(expected_checksum, try runListSortBench()); +} From 3c19c324148b3257031275a8cfa84c8835862654 Mon Sep 17 00:00:00 2001 From: adybag14-cyber Date: Fri, 29 May 2026 01:36:50 +0100 Subject: [PATCH 2/2] test(zigux): add lane16 list_sort bench replay runner --- .../phase1_list_sort_bench_replay_build.zig | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 zigux/tests/phase1_list_sort_bench_replay_build.zig diff --git a/zigux/tests/phase1_list_sort_bench_replay_build.zig b/zigux/tests/phase1_list_sort_bench_replay_build.zig new file mode 100644 index 00000000000000..8fea412ffe3b9b --- /dev/null +++ b/zigux/tests/phase1_list_sort_bench_replay_build.zig @@ -0,0 +1,39 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const root_module = b.createModule(.{ + .root_source_file = b.path("phase1_list_sort_bench_replay.zig"), + .target = target, + .optimize = optimize, + }); + const list_sort_module = b.createModule(.{ + .root_source_file = b.path("../../tools/lib/list_sort.zig"), + .target = target, + .optimize = optimize, + }); + + root_module.addImport("list_sort", list_sort_module); + + const replay_tests = b.addTest(.{ + .name = "phase1-list-sort-bench-replay", + .root_module = root_module, + }); + const run_replay = b.addRunArtifact(replay_tests); + + const replay_step = b.step( + "phase1-list-sort-bench-replay", + "Run the focused Phase 1 list_sort bench replay from zigux/tests", + ); + replay_step.dependOn(&run_replay.step); + + const test_step = b.step( + "test", + "Run the focused Phase 1 list_sort bench replay from zigux/tests", + ); + test_step.dependOn(&run_replay.step); + + b.default_step.dependOn(test_step); +}