torch.autograd.function.FunctionCtx.input_grad_buffers#
- property FunctionCtx.input_grad_buffers: tuple[Tensor | None, ...]#
Return existing buffers for accumulating gradients of this Function’s inputs.
Each entry corresponds to an argument passed to
forward(), in the same order. Each entry isNoneor the autograd engine’s currentInputBufferfor that input. A non-Nonebuffer contains gradient contributions already produced during the current backward. A custom backward may accumulate its contribution directly into the buffer and returnNonefor that input, fusing gradient computation with accumulation and avoiding a separate gradient tensor.Availability follows backward execution order and is independent for each input. An entry is
Nonewhen no earlier producer has contributed to that input, or when the existing buffer is aliased or cannot safely be updated in place.For example,
xhas another forward use whileweightdoes not. The custom backward conditionally fuses accumulation only forgrad_x:>>> class Matmul(torch.autograd.Function): >>> @staticmethod >>> def forward(ctx, x, weight): >>> ctx.save_for_backward(x, weight) >>> return x @ weight >>> >>> @staticmethod >>> def backward(ctx, grad_output): >>> x, weight = ctx.saved_tensors >>> x_buffer, _ = ctx.input_grad_buffers >>> if x_buffer is not None: >>> # Computes grad_x and adds it to the existing buffer. >>> matmul_backward_input_acc( >>> grad_output, weight, acc_into=x_buffer >>> ) >>> grad_x = None >>> else: >>> grad_x = matmul_backward_input(grad_output, weight) >>> grad_weight = matmul_backward_weight(grad_output, x) >>> return grad_x, grad_weight >>> >>> loss = Matmul.apply(x, weight).sum() + other_op(x).sum()
If
other_opproduces its contribution first,x_buffercan expose that partial sum. IfMatmulruns first,x_bufferisNoneand it returns a separate tensor instead. The fallback lets the function work under either ordering.Warning
A returned buffer is valid only while the current custom
backwardinvocation is running. Mutate it synchronously and do not retain it. A later producer may replace the engine’s buffer, making a retained tensor stale.After receiving a non-
Nonebuffer, callingbackwardorgradbefore the custom backward returns raises an error.All engine-scheduled producers that use or subsequently update an exposed buffer must execute on the same device, autograd engine thread, and stream.
This property is available only while a Python custom
backwardis executing during an eager, first-orderbackward(),torch.autograd.backward(), ortorch.autograd.grad()call. It is unavailable withcreate_graph=True, anomaly detection, a post-hook on the producing autograd node, or stale capture stream overrides.Note
For a leaf input, a non-
Noneentry exposes its execution-localInputBuffer, not its existing.grad. All contributions are first combined in that buffer. Duringbackward,AccumulateGradthen runs once with the completed buffer to update.gradand run its usual hooks.torch.autograd.grad()instead returns the completed buffer without updating.grad.During
backward, a custom backward that instead accumulates directly into a leaf.gradand returnsNonedoes not use this interface. It is responsible for managing.gradstate, including initialization and lifetime, synchronization with all other producers, and anyAccumulateGradhook behavior bypassed by the direct write.