lib/accy/src/tensor/interpret/leaf.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const program_mod = @import("../root.zig").program;
2 const trace = @import("../root.zig").trace;
3 const context = @import("context.zig");
4 const dispatch = @import("dispatch.zig");
5 const step_mod = @import("step.zig");
6
7 pub fn semantics(comptime BoundValue: type, impl: anytype) Semantics(BoundValue, @TypeOf(impl)) {
8 return .{ .impl = impl };
9 }
10
11 pub fn Semantics(comptime BoundValue: type, comptime Impl: type) type {
12 return struct {
13 impl: Impl,
14
15 pub const Value: type = BoundValue;
16 pub const Result: type = Impl.Result;
17
18 pub fn operation(self: *@This(), step: *step_mod.Step(Value)) !Value {
19 var buffer: [program_mod.max_operation_operands]Value = undefined;
20 return self.bind(step.op, step_mod.arguments(Value, step.op, step.values, &buffer));
21 }
22
23 pub fn bind(self: *@This(), op: *const program_mod.Operation, args: []const Value) !Value {
24 if (comptime @hasDecl(Impl, "bind")) {
25 return self.impl.bind(op, args);
26 }
27
28 var ctx = context.LeafBindContext(Value){
29 .op = op,
30 .args = args,
31 };
32 if (try dispatch.primitive(Value, &self.impl, &ctx)) |value| return value;
33 if (comptime @hasDecl(Impl, "default")) return self.impl.default(&ctx);
34 @compileError("tensor leaf semantics without bind must provide primitive handlers and default");
35 }
36
37 pub fn finish(self: *@This(), outputs: []const Value) !Result {
38 return self.impl.finish(outputs);
39 }
40
41 pub fn builderHandle(self: *@This()) *trace.Builder {
42 return self.impl.builderHandle();
43 }
44 };
45 }