One of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [128, 128]], which is output 0 of TBackward, is at version 2; expected version 1 instead

username: coballe
cooked: <p>I am training a network to predict trajectories of particles. The main training loop is:</p>
<pre><code>    for t,time_slice in enumerate(TrajectoryBatch(traj_batch,time_steps = time_steps)):

        time_slice.to(device)
        
        if t == 0:
            enc_pred = 0
        else:
            enc_pred = rollout
        
        # forward pass
        enc,recon,rollout,pred = mod(time_slice)
    
        # compute loss
        dx,dg = torch.cdist(time_slice.x,time_slice.x),torch.cdist(enc,enc) # distance matrices for metric loss

        l1 = (1/time_steps)*ae_loss(time_slice.x,recon)
        l2 = (1/time_steps)*pred_loss(time_slice.y,pred)
        l3 = (1/time_steps)*met_loss(dx,dg)
        
        if t == 0:
            l4 = (1/time_steps)*lin_pred_loss(enc,enc)
        
        else:
            l4 = (1/time_steps)*lin_pred_loss(enc,enc_pred)
        
        time_slice_loss = ae_reg*l1+pred_reg*l2+met_reg*l3+lin_pred_reg*l4
        
        
        # backprop
        time_slice_loss.backward(retain_graph = True)
        optimizer.step()
        optimizer.zero_grad()
        
        ep_loss += float(time_slice_loss)
        pred_acc_train += float(l2)
</code></pre>
<p>The code runs for t == 0, but then gives the error message:</p>
<blockquote>
<hr>
<p>RuntimeError                              Traceback (most recent call last)<br>
 in <br>
43             # backprop<br>
44<br>
—&gt; 45             time_slice_loss.backward(retain_graph = True)<br>
46             optimizer.step()<br>
47             optimizer.zero_grad()</p>
<p>~/anaconda3/envs/tf_gpu/lib/python3.8/site-packages/torch/tensor.py in backward(self, gradient, retain_graph, create_graph)<br>
219                 retain_graph=retain_graph,<br>
220                 create_graph=create_graph)<br>
 → 221         torch.autograd.backward(self, gradient, retain_graph, create_graph)<br>
222<br>
223     def register_hook(self, hook):</p>
<p>~/anaconda3/envs/tf_gpu/lib/python3.8/site-packages/torch/autograd/<strong>init</strong>.py in backward(tensors, grad_tensors, retain_graph, create_graph, grad_variables)<br>
128         retain_graph = create_graph<br>
129<br>
 → 130     Variable.<em>execution_engine.run_backward(<br>
131         tensors, grad_tensors</em>, retain_graph, create_graph,<br>
132         allow_unreachable=True)  # allow_unreachable flag<br>
RuntimeError: one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [128, 128]], which is output 0 of TBackward, is at version 1; expected version 0 instead. Hint: the backtrace further above shows the operation that failed to compute its gradient. The variable in question was changed in there or anywhere later. Good luck!</p>
</blockquote>
<p>The issue is related to the loss component, l4</p>
<pre><code class="lang-auto">l4 = (1/time_steps)*lin_pred_loss(enc,enc_pred)
</code></pre>
<p>because the code runs when l4 is not included in the total loss.</p>
<p>The variable enc_pred is an output of the previous forward pass. I’ve read through other posts pertaining to this error message, but I couldn’t find anything that resolved the issue. I’ve tried substituting:</p>
<pre><code class="lang-auto">enc_pred = rollout.clone()
</code></pre>
<p>and,</p>
<pre><code class="lang-auto">time_slice_loss = (ae_reg*l1+pred_reg*l2+met_reg*l3+lin_pred_reg*l4).clone()
</code></pre>
<p>with no success. Any help is greatly appreciated.</p>
<p>UPDATE:</p>
<p>The code runs with</p>
<pre><code class="lang-auto">enc_pred = rollout.detach()
</code></pre>
<p>although I’ll have to think about what exactly is going on.</p>

username: albanD
cooked: <aside class="quote no-group" data-username="coballe" data-post="1" data-topic="108178">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/c/53a042/48.png" class="avatar"> coballe:</div>
<blockquote>
<p>The code runs with</p>
<pre><code class="lang-auto">enc_pred = rollout.detach()
</code></pre>
</blockquote>
</aside>
<p>You most likely don’t want that as this is the same as not including this part into the loss function!</p>
<p>The error you see does come from an inplace op that is causing issue.<br>
From your code sample, a possible reason is that <code>optimizer.step()</code> modifies the weights inplace. But the original values are needed for the gradient computation, so if you try to backward again, it will fail with this error.</p>

username: coballe
cooked: <p>Does</p>
<pre><code class="lang-auto">enc_pred = rollout.detach()
</code></pre>
<p>result in enc_pred being treated as a constant in</p>
<pre><code class="lang-auto">l4 = (1/time_steps)*lin_pred_loss(enc,enc_pred)
</code></pre>
<p>or does it cause l4 to be disregarded altogether?</p>

username: albanD
cooked: <p>It only causes it to be considered as a constant. So not gradient will “flow back” through <code>enc_pred</code>.</p>

username: coballe
cooked: <p>I see. In the model, enc flows through the first part of the network that enc_pred does. Could this be an issue?</p>
<p>For example, does autograd update the network by flowing through enc, then throw an error when flowing through enc_pred since weights have been modified in place?</p>

username: albanD
cooked: <p>I don’t know what your model is <img src="https://discuss.pytorch.org/images/emoji/apple/smiley.png?v=9" title=":smiley:" class="emoji" alt=":smiley:"> But that sounds like something that is plausible.<br>
You can easily avoid this by re-doing a forward pass after you update the weights.</p>