| 194 | } |
| 195 | |
| 196 | void matmul_backward(Context& ctx, float* dinp, float* dweight, float* dbias, |
| 197 | const float* dout, const float* inp, const float* weight, |
| 198 | int B, int T, int C, int OC){ |
| 199 | struct MatmulParams { |
| 200 | uint32_t B; |
| 201 | uint32_t T; |
| 202 | uint32_t C; |
| 203 | uint32_t OC; |
| 204 | }; |
| 205 | unsigned long b = static_cast<unsigned long>(B); |
| 206 | unsigned long t = static_cast<unsigned long>(T); |
| 207 | unsigned long c = static_cast<unsigned long>(C); |
| 208 | unsigned long oc = static_cast<unsigned long>(OC); |
| 209 | setLogLevel(kError); |
| 210 | Tensor dinp_t = createTensor(ctx, Shape{b * t * c}, kf32, dinp); |
| 211 | Tensor dweight_t = createTensor(ctx, Shape{oc * c}, kf32, dweight); |
| 212 | Tensor dbias_t = createTensor(ctx, Shape{oc}, kf32, dbias); |
| 213 | Tensor dout_t = createTensor(ctx, Shape{b * t * oc}, kf32, dout); |
| 214 | Tensor inp_t = createTensor(ctx, Shape{b * t * c}, kf32, inp); |
| 215 | Tensor weight_t = createTensor(ctx, Shape{oc * c}, kf32, weight); |
| 216 | std::promise<void> promise; |
| 217 | std::future<void> future = promise.get_future(); |
| 218 | Kernel op = createKernel(ctx, {kShaderMatmulBackward, 256, kf32}, |
| 219 | Bindings{dinp_t, dweight_t, dbias_t, dout_t, inp_t, weight_t}, |
| 220 | /* nWorkgroups */ {cdiv(b * t, 256), 1, 1}, |
| 221 | /* params */ |
| 222 | MatmulParams{ |
| 223 | static_cast<uint32_t>(b), |
| 224 | static_cast<uint32_t>(t), |
| 225 | static_cast<uint32_t>(c), |
| 226 | static_cast<uint32_t>(oc) |
| 227 | }); |
| 228 | dispatchKernel(ctx, op, promise); |
| 229 | wait(ctx, future); |
| 230 | toCPU(ctx, dinp_t, dinp, b * t * c * sizeof(float)); |
| 231 | toCPU(ctx, dweight_t, dweight, oc * c * sizeof(float)); |
| 232 | toCPU(ctx, dbias_t, dbias, oc * sizeof(float)); |
| 233 | } |
| 234 | |
| 235 | void attention_forward(Context& ctx, float* out, float* preatt, float* att, |
| 236 | float* inp, |
no test coverage detected