HI,
The problem is that the multiplication needs the values of its operands to compute the backpass.
If for any reason this operand is modified inplace, the computed gradient will be wrong.
The old implementation that was using .data for gradient accumulation was not notifying the autograd of the inplace operation and thus the gradient were wrong.
The new implementation that uses torch.no_grad() does notify the autograd and so throws an error.
Both my suggestion with .clone() and your change to do -grad make a copy of grad before passing it to the multiplication. Thus when grad is modified inplace, it does not modify the value needed by the multiplication to compute its backward.
So this will compute the correct gradient.