lib/accy/src/kernel/dsl/program/execute.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const kernel = @import("../../root.zig");
3 const kernel_compile = @import("../../compile/root.zig");
4 const executable = @import("../../../executable/root.zig");
5 const body = @import("../root.zig").body;
6 const parameter = @import("../../program/root.zig").parameter;
7
8 pub fn buildSource(comptime definition: anytype, allocator: std.mem.Allocator, limits: kernel.Limits) !kernel.Graph {
9 return interpretSource(definition, allocator, limits, kernel.interpret.graph());
10 }
11
12 pub fn interpretSource(comptime definition: anytype, allocator: std.mem.Allocator, limits: kernel.Limits, initial: anytype) !result(@TypeOf(initial)) {
13 var builder = try kernel.Builder.init(allocator, limits, definition.name, parameter.schema(definition.parameters));
14 errdefer builder.deinit();
15
16 const initial_spec = kernel.interpret.asSpec(initial);
17 var state = initial_spec.attach(&builder);
18 try body.call(definition, &state);
19 try state.return_();
20 return state.finish();
21 }
22
23 pub fn buildInstanceSource(comptime definition: anytype, instance: anytype, allocator: std.mem.Allocator, limits: kernel.Limits) !kernel.Graph {
24 return interpretInstanceSource(definition, instance, allocator, limits, kernel.interpret.graph());
25 }
26
27 pub fn buildNamedInstanceSource(comptime definition: anytype, name: []const u8, instance: anytype, allocator: std.mem.Allocator, limits: kernel.Limits) !kernel.Graph {
28 return interpretNamedInstanceSource(definition, name, instance, allocator, limits, kernel.interpret.graph());
29 }
30
31 pub fn interpretInstanceSource(comptime definition: anytype, instance: anytype, allocator: std.mem.Allocator, limits: kernel.Limits, initial: anytype) !result(@TypeOf(initial)) {
32 return interpretNamedInstanceSource(definition, definition.name, instance, allocator, limits, initial);
33 }
34
35 pub fn interpretNamedInstanceSource(comptime definition: anytype, name: []const u8, instance: anytype, allocator: std.mem.Allocator, limits: kernel.Limits, initial: anytype) !result(@TypeOf(initial)) {
36 var builder = try kernel.Builder.init(allocator, limits, name, parameter.schema(definition.parameters));
37 errdefer builder.deinit();
38
39 const initial_spec = kernel.interpret.asSpec(initial);
40 var state = initial_spec.attach(&builder);
41 try body.callInstance(definition, instance, &state);
42 try state.return_();
43 return state.finish();
44 }
45
46 pub fn buildDerived(comptime SourceProgram: type, comptime transform_spec: anytype, allocator: std.mem.Allocator, limits: kernel.Limits) !kernel.Graph {
47 return SourceProgram.interpret(allocator, limits, transform_spec);
48 }
49
50 pub fn interpretDerived(comptime SourceProgram: type, comptime transform_spec: anytype, allocator: std.mem.Allocator, limits: kernel.Limits, initial: anytype) !stackedResult(@TypeOf(transform_spec), @TypeOf(initial)) {
51 return SourceProgram.interpret(allocator, limits, kernel.interpret.stack(.{ transform_spec, kernel.interpret.asSpec(initial) }));
52 }
53
54 pub fn buildAnalysisTransform(
55 comptime ProgramType: type,
56 comptime analysis_impl: anytype,
57 comptime make_transform: anytype,
58 allocator: std.mem.Allocator,
59 limits: kernel.Limits,
60 ) !kernel.Graph {
61 var analysis = try ProgramType.interpret(allocator, limits, analysis_impl);
62 defer kernel.interpret.deinitIfPresent(&analysis);
63 return ProgramType.interpret(allocator, limits, make_transform(&analysis));
64 }
65
66 pub fn interpretAnalysisTransform(
67 comptime ProgramType: type,
68 comptime analysis_impl: anytype,
69 comptime make_transform: anytype,
70 allocator: std.mem.Allocator,
71 limits: kernel.Limits,
72 initial: anytype,
73 ) !stackedResult(TransformSpec(analysis_impl, make_transform), @TypeOf(initial)) {
74 var analysis = try ProgramType.interpret(allocator, limits, analysis_impl);
75 defer kernel.interpret.deinitIfPresent(&analysis);
76 return ProgramType.interpret(allocator, limits, kernel.interpret.stack(.{ kernel.interpret.asSpec(make_transform(&analysis)), kernel.interpret.asSpec(initial) }));
77 }
78
79 pub fn launch(comptime ProgramType: type, allocator: std.mem.Allocator, limits: kernel.Limits) !kernel.Launch {
80 var graph = try ProgramType.build(allocator, limits);
81 defer graph.deinit();
82 return graph.launch();
83 }
84
85 pub fn scheduleSnapshot(comptime ProgramType: type, allocator: std.mem.Allocator, limits: kernel.Limits) !kernel.ScheduleSnapshot {
86 var graph = try ProgramType.build(allocator, limits);
87 defer graph.deinit();
88 return graph.scheduleSnapshot(allocator);
89 }
90
91 pub fn createPlan(comptime ProgramType: type, allocator: std.mem.Allocator, limits: kernel.Limits, options: kernel.PlanOptions) !kernel.Plan {
92 var graph = try ProgramType.build(allocator, limits);
93 defer graph.deinit();
94 return graph.createPlan(allocator, options);
95 }
96
97 pub fn createCheckedPlan(comptime ProgramType: type, allocator: std.mem.Allocator, limits: kernel.Limits, options: kernel.PlanOptions) !kernel.Plan {
98 var graph = try ProgramType.build(allocator, limits);
99 defer graph.deinit();
100 return graph.createCheckedPlan(allocator, options);
101 }
102
103 pub fn compileFragment(
104 comptime ProgramType: type,
105 allocator: std.mem.Allocator,
106 limits: kernel.Limits,
107 handle: kernel.BackendHandle,
108 options: executable.FragmentCompilerOptions,
109 ) !*executable.CompiledFragment {
110 var graph = try ProgramType.build(allocator, limits);
111 defer graph.deinit();
112 return kernel_compile.compileFragment(allocator, handle, &graph, options);
113 }
114
115 pub fn createKernelArtifact(
116 comptime ProgramType: type,
117 allocator: std.mem.Allocator,
118 limits: kernel.Limits,
119 handle: kernel.BackendHandle,
120 options: executable.KernelCompilerOptions,
121 ) !kernel.KernelArtifact {
122 var graph = try ProgramType.build(allocator, limits);
123 defer graph.deinit();
124 return kernel_compile.createArtifact(allocator, handle, &graph, options);
125 }
126
127 pub fn createKernelCallArtifact(
128 comptime ProgramType: type,
129 allocator: std.mem.Allocator,
130 limits: kernel.Limits,
131 handle: kernel.BackendHandle,
132 options: kernel.KernelCallArtifactOptions,
133 ) !kernel.OwnedKernelCallArtifact {
134 var graph = try ProgramType.build(allocator, limits);
135 defer graph.deinit();
136 return kernel.createKernelCallArtifact(allocator, handle, &graph, options);
137 }
138
139 pub fn runCpu(comptime ProgramType: type, allocator: std.mem.Allocator, limits: kernel.Limits, args: []const kernel.Argument) !void {
140 var graph = try ProgramType.build(allocator, limits);
141 defer graph.deinit();
142 try graph.runCpu(allocator, args);
143 }
144
145 pub fn runCpuWithDiagnostic(
146 comptime ProgramType: type,
147 allocator: std.mem.Allocator,
148 limits: kernel.Limits,
149 args: []const kernel.Argument,
150 diagnostic: *kernel.ExecutionDiagnostic,
151 ) !void {
152 var graph = try ProgramType.build(allocator, limits);
153 defer graph.deinit();
154 try graph.runCpuWithDiagnostic(allocator, args, diagnostic);
155 }
156
157 pub fn verify(comptime ProgramType: type, allocator: std.mem.Allocator, limits: kernel.Limits) !void {
158 var graph = try ProgramType.build(allocator, limits);
159 defer graph.deinit();
160 try graph.verify();
161 }
162
163 pub fn AnalysisResult(comptime analysis_impl: anytype) type {
164 return kernel.interpret.Result(kernel.interpret.InterpretSpec(@TypeOf(analysis_impl)));
165 }
166
167 pub fn TransformSpec(comptime analysis_impl: anytype, comptime make_transform: anytype) type {
168 return kernel.interpret.InterpretSpec(@TypeOf(make_transform(@as(*const AnalysisResult(analysis_impl), undefined))));
169 }
170
171 pub fn result(comptime Initial: type) type {
172 return kernel.interpret.Result(kernel.interpret.InterpretSpec(Initial));
173 }
174
175 pub fn stackedResult(comptime Transform: type, comptime Initial: type) type {
176 return kernel.interpret.Result(@TypeOf(kernel.interpret.stack(.{ @as(Transform, undefined), @as(kernel.interpret.InterpretSpec(Initial), undefined) })));
177 }