| 427 | } |
| 428 | |
| 429 | void crossentropy_softmax_backward(Context& ctx, float* dlogits, |
| 430 | float* dlosses, float* probs, int* targets, |
| 431 | int B, int T, int V, int Vp){ |
| 432 | struct CrossEntropySoftmaxBackwardParams { |
| 433 | uint32_t B; |
| 434 | uint32_t T; |
| 435 | uint32_t V; |
| 436 | uint32_t VP; |
| 437 | }; |
| 438 | unsigned long b = static_cast<unsigned long>(B); |
| 439 | unsigned long t = static_cast<unsigned long>(T); |
| 440 | unsigned long v = static_cast<unsigned long>(V); |
| 441 | unsigned long vp = static_cast<unsigned long>(Vp); |
| 442 | setLogLevel(kError); |
| 443 | Tensor dlogits_t = createTensor(ctx, Shape{b * t * vp}, kf32, dlogits); |
| 444 | Tensor dlosses_t = createTensor(ctx, Shape{b * t}, kf32, dlosses); |
| 445 | Tensor probs_t = createTensor(ctx, Shape{b * t * vp}, kf32, probs); |
| 446 | Tensor targets_t = createTensor(ctx, Shape{b * t}, ki32, targets); |
| 447 | std::promise<void> promise; |
| 448 | std::future<void> future = promise.get_future(); |
| 449 | Kernel op = createKernel(ctx, {kShaderCrossEntropySoftmaxBackward, 256, kf32}, |
| 450 | Bindings{dlogits_t, dlosses_t, probs_t, targets_t}, |
| 451 | /* nWorkgroups */ {cdiv(b * t, 256), 1, 1}, |
| 452 | /* params */ |
| 453 | CrossEntropySoftmaxBackwardParams{ |
| 454 | static_cast<uint32_t>(b), |
| 455 | static_cast<uint32_t>(t), |
| 456 | static_cast<uint32_t>(v), |
| 457 | static_cast<uint32_t>(vp) |
| 458 | }); |
| 459 | dispatchKernel(ctx, op, promise); |
| 460 | wait(ctx, future); |
| 461 | toCPU(ctx, dlogits_t, dlogits, b * t * vp * sizeof(float)); |
| 462 | } |
no test coverage detected