(ctx, grad_output: torch.Tensor)
| 40 | |
| 41 | @staticmethod |
| 42 | def backward(ctx, grad_output: torch.Tensor) -> Tuple[torch.Tensor, None]: |
| 43 | (indices,) = ctx.saved_tensors |
| 44 | assert grad_output.ndim >= 2 |
| 45 | other_shape = grad_output.shape[1:] |
| 46 | grad_output = rearrange(grad_output, "b ... -> b (...)") |
| 47 | grad_input = torch.zeros( |
| 48 | [ctx.first_axis_dim, grad_output.shape[1]], device=grad_output.device, dtype=grad_output.dtype |
| 49 | ) |
| 50 | # TD [2022-03-04] For some reason torch.scatter is a bit faster than indexing. |
| 51 | # grad_input[indices] = grad_output |
| 52 | grad_input.scatter_(0, repeat(indices, "z -> z d", d=grad_output.shape[1]), grad_output) |
| 53 | return grad_input.reshape(ctx.first_axis_dim, *other_shape), None |
| 54 | |
| 55 | |
| 56 | index_first_axis = IndexFirstAxis.apply |
no outgoing calls