1use super::{groups64, ComputeEngine, Kernel};
4use crate::{UnifiedTensor, WgpuContext};
5
6impl ComputeEngine {
7 pub fn add(
9 &self,
10 ctx: &WgpuContext,
11 a: &UnifiedTensor,
12 b: &UnifiedTensor,
13 out: &UnifiedTensor,
14 ) {
15 self.binary(ctx, &self.add, a, b, out);
16 }
17
18 pub fn mul(
20 &self,
21 ctx: &WgpuContext,
22 a: &UnifiedTensor,
23 b: &UnifiedTensor,
24 out: &UnifiedTensor,
25 ) {
26 self.binary(ctx, &self.mul, a, b, out);
27 }
28
29 pub fn sub(
31 &self,
32 ctx: &WgpuContext,
33 a: &UnifiedTensor,
34 b: &UnifiedTensor,
35 out: &UnifiedTensor,
36 ) {
37 self.binary(ctx, &self.sub, a, b, out);
38 }
39
40 pub(super) fn binary(
41 &self,
42 ctx: &WgpuContext,
43 kernel: &Kernel,
44 a: &UnifiedTensor,
45 b: &UnifiedTensor,
46 out: &UnifiedTensor,
47 ) {
48 self.run(
49 ctx,
50 kernel,
51 &[(0, a.buffer()), (1, b.buffer()), (2, out.buffer())],
52 groups64(a.shape.iter().product()),
53 );
54 }
55
56 pub fn add_backward(
58 &self,
59 ctx: &WgpuContext,
60 grad_out: &UnifiedTensor,
61 grad_a: &UnifiedTensor,
62 grad_b: &UnifiedTensor,
63 ) {
64 self.run(
65 ctx,
66 &self.add_bw,
67 &[
68 (3, grad_out.buffer()),
69 (4, grad_a.buffer()),
70 (5, grad_b.buffer()),
71 ],
72 groups64(grad_out.shape.iter().product()),
73 );
74 }
75
76 pub fn sub_backward(
78 &self,
79 ctx: &WgpuContext,
80 grad_out: &UnifiedTensor,
81 grad_a: &UnifiedTensor,
82 grad_b: &UnifiedTensor,
83 ) {
84 self.run(
85 ctx,
86 &self.sub_bw,
87 &[
88 (3, grad_out.buffer()),
89 (4, grad_a.buffer()),
90 (5, grad_b.buffer()),
91 ],
92 groups64(grad_out.shape.iter().product()),
93 );
94 }
95
96 pub fn mul_backward(
98 &self,
99 ctx: &WgpuContext,
100 grad_out: &UnifiedTensor,
101 a: &UnifiedTensor,
102 b: &UnifiedTensor,
103 grad_a: &UnifiedTensor,
104 grad_b: &UnifiedTensor,
105 ) {
106 self.run(
107 ctx,
108 &self.mul_bw,
109 &[
110 (3, grad_out.buffer()),
111 (4, a.buffer()),
112 (5, b.buffer()),
113 (6, grad_a.buffer()),
114 (7, grad_b.buffer()),
115 ],
116 groups64(grad_out.shape.iter().product()),
117 );
118 }
119
120 pub fn silu(&self, ctx: &WgpuContext, input: &UnifiedTensor, out: &UnifiedTensor) {
122 self.run(
123 ctx,
124 &self.silu,
125 &[(0, input.buffer()), (1, out.buffer())],
126 groups64(input.shape.iter().product()),
127 );
128 }
129
130 pub fn silu_backward(
133 &self,
134 ctx: &WgpuContext,
135 grad_out: &UnifiedTensor,
136 input: &UnifiedTensor,
137 grad_in: &UnifiedTensor,
138 ) {
139 self.run(
140 ctx,
141 &self.silu_bw,
142 &[
143 (3, grad_out.buffer()),
144 (4, input.buffer()),
145 (5, grad_in.buffer()),
146 ],
147 groups64(grad_out.shape.iter().product()),
148 );
149 }
150
151 pub fn relu(&self, ctx: &WgpuContext, input: &UnifiedTensor, out: &UnifiedTensor) {
153 self.run(
154 ctx,
155 &self.relu,
156 &[(0, input.buffer()), (1, out.buffer())],
157 groups64(input.shape.iter().product()),
158 );
159 }
160
161 pub fn relu_backward(
163 &self,
164 ctx: &WgpuContext,
165 grad_out: &UnifiedTensor,
166 input: &UnifiedTensor,
167 grad_in: &UnifiedTensor,
168 ) {
169 self.run(
170 ctx,
171 &self.relu_bw,
172 &[
173 (3, grad_out.buffer()),
174 (4, input.buffer()),
175 (5, grad_in.buffer()),
176 ],
177 groups64(grad_out.shape.iter().product()),
178 );
179 }
180
181 pub fn silu_gate_fused(
184 &self,
185 ctx: &WgpuContext,
186 up: &UnifiedTensor,
187 gate: &UnifiedTensor,
188 out: &UnifiedTensor,
189 ) {
190 self.binary(ctx, &self.silu_gate, up, gate, out);
191 }
192
193 pub fn silu_gate_backward(
195 &self,
196 ctx: &WgpuContext,
197 up: &UnifiedTensor,
198 gate: &UnifiedTensor,
199 grad_out: &UnifiedTensor,
200 grad_up: &UnifiedTensor,
201 grad_gate: &UnifiedTensor,
202 ) {
203 self.run(
204 ctx,
205 &self.silu_gate_bw,
206 &[
207 (0, up.buffer()),
208 (1, gate.buffer()),
209 (3, grad_out.buffer()),
210 (4, grad_up.buffer()),
211 (5, grad_gate.buffer()),
212 ],
213 groups64(up.shape.iter().product()),
214 );
215 }
216}