lib/accy/src/kernel/library/catalog/family/random/root.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 
 3 const descriptor_mod = @import("../../root.zig");
 4 const random = @import("../../../root.zig").random;
 5 const match_mod = @import("../../match/root.zig");
 6 const query_mod = descriptor_mod;
 7 
 8 const candidate = @import("candidate.zig");
 9 const philox = @import("philox.zig");
10 const squares = @import("squares.zig");
11 const threefry = @import("threefry.zig");
12 
13 const OwnedDescriptor = descriptor_mod.OwnedDescriptor;
14 const RandomQuery = query_mod.RandomQuery;
15 
16 pub const RandomCandidateDescriptors = candidate.RandomCandidateDescriptors;
17 
18 pub fn selectRandom(backing_allocator: std.mem.Allocator, query: RandomQuery) !?OwnedDescriptor {
19     if (!canonicalRandom(query)) return null;
20     return switch (query.algorithm) {
21         .philox => philox.select(backing_allocator, query),
22         .threefry => threefry.select(backing_allocator, query),
23         .squares => squares.select(backing_allocator, query),
24     };
25 }
26 
27 pub fn selectRandomCandidates(
28     backing_allocator: std.mem.Allocator,
29     query: RandomQuery,
30 ) !RandomCandidateDescriptors {
31     var result = RandomCandidateDescriptors{};
32     errdefer result.deinit();
33 
34     if (!canonicalRandom(query)) return result;
35     if (query.schedule != null) {
36         if (try selectRandom(backing_allocator, query)) |descriptor| {
37             result.items[result.count] = descriptor;
38             result.count += 1;
39         }
40         return result;
41     }
42 
43     switch (query.algorithm) {
44         .philox => try philox.appendCandidates(backing_allocator, query, &result),
45         .threefry => try threefry.appendCandidates(backing_allocator, query, &result),
46         .squares => try squares.appendCandidates(backing_allocator, query, &result),
47     }
48     return result;
49 }
50 
51 fn canonicalRandom(query: RandomQuery) bool {
52     if (!random.randomDTypeSupported(query.dtype)) return false;
53     if (query.count == 0) return false;
54     const rounds = match_mod.randomEffectiveRounds(query);
55     return switch (query.algorithm) {
56         .philox => rounds >= 1 and rounds <= random.philox_max_rounds,
57         .threefry => rounds >= 1 and rounds <= random.threefry_max_rounds,
58         .squares => query.rounds == 0,
59     };
60 }