Gradient computation error

bingqing_liu: <pre><code class="lang-auto">embedding=nn.Parameter(torch.rand(2,3))
d=nn.Parameter(torch.rand(3,3))
user_embeddings=embedding.clone()
user_embedding_input = user_embeddings[0] 
a=user_embedding_input*3#option1
print(a)
a=torch.matmul(d,user_embedding_input)#option2
print(a)
user_embeddings[0]=a
loss=a.sum()
loss.backward()
</code></pre>
<p>i found that use option2 will cause this error,but option1 works well,why?</p>
<blockquote>
<p>one of the variables needed for gradient computation has been modified by an inplace operation</p>
</blockquote>

KFrank: <p>Hi Bingqing!</p>
<aside class="quote no-group" data-username="bingqing_liu" data-post="1" data-topic="146049" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/bingqing_liu/48/31455_2.png" class="avatar"> bingqing_liu:</div>
<blockquote>
<pre><code class="lang-auto">user_embedding_input = user_embeddings[0]
</code></pre>
</blockquote>
</aside>
<p><code>user_embedding_input</code> is a view into <code>user embeddings</code> and references<br>
the same underlying data.</p>
<aside class="quote no-group">
<blockquote>
<pre><code class="lang-auto">a=user_embedding_input*3#option1
</code></pre>
</blockquote>
</aside>
<p>During backpropagation, the gradient of <code>a</code> with respect to<br>
<code>user_embedding_input</code> is <code>3</code> and doesn’t depend on<br>
<code>user_embedding_input</code>, so autograd doesn’t care whether<br>
whether <code>user_embedding_input</code> “has been modified inplace.”</p>
<aside class="quote no-group">
<blockquote>
<pre><code class="lang-auto">a=torch.matmul(d,user_embedding_input)#option2
</code></pre>
</blockquote>
</aside>
<p>Here, the gradient of <code>a</code> with respect to <code>d</code> is (morally speaking)<br>
<code>user_embedding_input</code>, so autograd will complain during<br>
backpropagation if <code>user_embedding_input</code> has been modified.</p>
<aside class="quote no-group">
<blockquote>
<pre><code class="lang-auto">user_embeddings[0]=a
</code></pre>
</blockquote>
</aside>
<p>Because <code>user_embedding_input</code> and <code>user_embeddings</code> refer to<br>
the same data, this line does modify <code>user_embedding_input</code>.  So<br>
autograd does complain during option2’s backpropagation about<br>
<code>user_embedding_input</code> having been modified.</p>
<aside class="quote no-group">
<blockquote>
<p>i found that use option2 will cause this error,but option1 works well,why?</p>
</blockquote>
</aside>
<p>Two things have to happen for the error to occur.  First, something<br>
has to modify <code>user_embedding_input</code>, and this happens because<br>
<code>user_embedding_input</code> is a view into <code>user_embeddings</code>, which<br>
you do modify.</p>
<p>And second, <code>user_embedding_input</code> itself has to be used during<br>
backpropagation to calculate gradients.  <code>user_embedding_input</code><br>
is used in option2’s gradient calculation, but not in options1’s, so<br>
you only get the error for option2.</p>
<p>Best.</p>
<p>K. Frank</p>

bingqing_liu: <p>Got it!!So kind of you,thank you!!!</p>

bingqing_liu: <pre><code class="lang-auto">embedding=nn.Parameter(torch.rand(2,3))
d=nn.Parameter(torch.rand(3,3))
user_embeddings=embedding.clone()
user_embedding_input = user_embeddings[[0],:] 
a=torch.matmul(user_embedding_input,d)
print(a)
user_embeddings[[0],:]=a
loss=a.sum()
loss.backward()
</code></pre>
<p>According your reply,i have known  [0] is a selectbackward,so i change this to [[0],:] to become a indexbackward,and it works well.</p>
<p>but i still have a question,why i add a <code>question line</code> which means i have changed the user_embedding_input,it’s a inplace operation,but it still works?and the printed d.grad equals to user_embedding_input before assignment.</p>
<pre><code class="lang-auto">embedding=nn.Parameter(torch.rand(2,3))
d=nn.Parameter(torch.rand(3,3))
user_embeddings=embedding.clone()
user_embedding_input = user_embeddings[[0],:] 
a=torch.matmul(user_embedding_input,d)
print(a)
user_embeddings[[0],:]=a
user_embedding_input=3#question line
loss=a.sum()
loss.backward()
</code></pre>