| 590 | } |
| 591 | |
| 592 | void input_gradient( |
| 593 | cudaStream_t stream, |
| 594 | uint32_t dim, |
| 595 | const GPUMatrix<T>& input, |
| 596 | GPUMatrix<T>& d_dinput, |
| 597 | float backprop_scale = default_loss_scale<PARAMS_T>() // Prevents underflows during half-precision backprop. Same reason for loss_scale to exist. |
| 598 | ) { |
| 599 | // Make sure our temporary buffers have the correct size for the given batch size |
| 600 | uint32_t batch_size = input.n(); |
| 601 | |
| 602 | GPUMatrix<COMPUTE_T> d_doutput = {padded_output_width(), batch_size, stream}; |
| 603 | GPUMatrix<COMPUTE_T> output = {padded_output_width(), batch_size, stream}; |
| 604 | |
| 605 | if (dim >= padded_output_width()) { |
| 606 | throw std::runtime_error{"Invalid dimension to compute the input gradient for."}; |
| 607 | } |
| 608 | |
| 609 | // Set "loss gradient" at network outputs to 1 at the chosen dimension and 0 elsewhere. |
| 610 | one_hot_batched(stream, output.n_elements(), padded_output_width(), dim, d_doutput.data(), backprop_scale); |
| 611 | |
| 612 | auto ctx = forward(stream, input, &output, true /* inference matrices */, true /* prep forward buffers for input gradients */); |
| 613 | backward(stream, *ctx, input, output, d_doutput, &d_dinput, true /* inference matrices */, GradientMode::Ignore); |
| 614 | |
| 615 | mult(stream, d_dinput.n_elements(), d_dinput.data(), 1.0f / backprop_scale); |
| 616 | } |
| 617 | |
| 618 | virtual uint32_t input_width() const = 0; |
| 619 |
nothing calls this directly
no test coverage detected