Skip to content

← Autograd Mechanics step 6 of 8

Medium Primitives

The value backward needed

y = x.exp()
y[0] = 0.0
y.sum().backward()
RuntimeError: one of the variables needed for gradient computation
has been modified by an inplace operation

Why it can tell

The derivative of exp is exp itself, so exp‘s backward needs its own output. It saved y for that. Then you overwrote part of y, and the saved value is no longer the value the derivative refers to.

Every tensor carries a version counter that increments on every in-place write. Autograd records the version at save time and checks it at backward time. That check is the entire mechanism, and it is why this fails loudly instead of silently computing a wrong gradient, which is what would otherwise happen.

Which in-place ops are safe

Not all of them break. relu_ is fine, because ReLU’s backward needs only the sign of its output, which the mutation preserves. add_ on a tensor nothing saved is fine.

The rule is not “avoid in-place near autograd”. It is that an in-place write to a tensor some node saved is an error, and you generally cannot tell by looking which those are. So: use in-place freely under no_grad and on tensors you just created, and be suspicious of it in the middle of a forward pass.

The fix

Express the change as a new tensor:

y = torch.where(mask, torch.zeros_like(y), y)

One allocation, a correct gradient, and the gradient at the masked positions is zero, which is what “this output was replaced by a constant” means.

The other version of this error

Modifying a parameter in place during the forward pass produces the same message and is usually a normalisation or clipping step that should have been under no_grad or should have produced a new tensor.

Your task

def masked_exp(x: torch.Tensor, zero_at: int) -> torch.Tensor

Return x.exp() with position zero_at replaced by zero, in a way that still supports backward. Return the tensor; the harness differentiates it.