RuntimeError: Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method

gil_bc: <p>Hello everyone, I’m trying to use an implemented layer that uses torch.autograd.Function.<br>
I get the error mentioned in the headline:<br>
“RuntimeError: Legacy autograd function with non-static forward method is deprecated. Please use new-style autograd function with static forward method.”<br>
I tried to update with the <span class="mention">@staticmethod</span><br>
The layer is implemented as follows:</p>
<pre><code>class SparseMM(torch.autograd.Function):

@staticmethod
def forward(self, sparse, dense):
    self.sparse = sparse
    # self.save_for_backward(torch.mm(self.sparse, dense))
    return torch.mm(self.sparse, dense)

@staticmethod
def backward(self, grad_output):
    grad_input = None
    if self.needs_input_grad[0]:
        grad_input = torch.mm(self.sparse.t(), grad_output)
    return grad_input
</code></pre>
<p>and using it as follows:</p>
<p>x = self.SparseMM.apply(self, D, x.t())</p>
<p>I still get the error. I’m not sure why. I looked at the example they turn to, and looked at some other threads here around the same problem, but couldn’t fix this.</p>
<p>Anyone has an idea why?<br>
thanks</p>

gil_bc: <p>I would really appreciate some help…</p>

Caruso: <p>Hi <a class="mention" href="/u/gil_bc">@gil_bc</a>,<br>
when i ran your code i got a different error message, because you only return the gradient for one of your input tensors.<br>
I got the following running, but its just a normal matrix multiplication. I am also not sure what type your sparse input is, so if its a normal Tensor or SparseTensor. I tested mine only with normal Tensors.</p>
<pre><code class="lang-auto">class SparseMM(torch.autograd.Function):
    @staticmethod
    def forward(ctx, sparse, dense):
        ctx.save_for_backward(sparse, dense)
        return torch.mm(sparse, dense)

    @staticmethod
    def backward(ctx, grad_output):
        sparse, dense = ctx.saved_tensors
        grad_sparse = grad_dense = None
        if ctx.needs_input_grad[0]:
            grad_sparse = torch.mm(grad_output, dense.t())
        if ctx.needs_input_grad[1]:
            grad_dense = torch.mm(sparse.t(), grad_output)
        return grad_sparse, grad_dense


S = torch.randn(3, 2, requires_grad=True)
D = torch.randn(4, 2, requires_grad=True)

sparse_mm = SparseMM.apply
x = sparse_mm(S, D.t())
x.backward(torch.ones_like(x))
</code></pre>

gil_bc: <p>Hi <a class="mention" href="/u/caruso">@Caruso</a>,<br>
thank you for you answer!<br>
I am new to pytorch and trying to use this code, which is a bit above my current level of understanding. I really appreciate your help.</p>
<p>This code below used to work until recently, with only a warning for the <span class="mention">@staticmethod</span> change. now it gives an error and doesn’t work anymore.</p>
<p>This is the original code that worked:</p>
<pre><code>class SparseMM(torch.autograd.Function):

 def __init__(self, sparse):
    super(SparseMM, self).__init__()
    self.sparse = sparse

 def forward(self, dense):
    return torch.mm(self.sparse, dense)

 def backward(self, grad_output):
    grad_input = None
    if self.needs_input_grad[0]:
        grad_input = torch.mm(self.sparse.t(), grad_output)
    return grad_input


x = SparseMM(D)(x.t()).t() 
</code></pre>
<p>I tried the way you implemented it, but I still get the same error- the autograd style error.<br>
I tried several other things I saw other people did… but I still can’t make it run</p>
<p>Looking at the original code, do you know how to adjust it to the new style?</p>
<p>thanks again</p>

Caruso: <p>Hi <a class="mention" href="/u/gil_bc">@gil_bc</a>,</p>
<p>your code looks good to me, maybe someone more experienced can help you! <img src="https://discuss.pytorch.org/images/emoji/apple/smiley.png?v=9" title=":smiley:" class="emoji" alt=":smiley:"><br>
Can you tell us which PyTorch version are you using?</p>

gil_bc: <p>Thanks again for your response<br>
I’m using 1.5.1</p>

gil_bc: <p>Well, I managed to make this run, though not by fixing the error I had.<br>
I just didn’t use the SparseMM function at all, instead I used this:<br>
torch.sparse.mm(D, x.t()).t()</p>
<p>from:<br>
</p><aside class="onebox allowlistedgeneric">
  <header class="source">
      <a href="https://pytorch.org/docs/stable/sparse.html#torch.sparse.mm" target="_blank" rel="noopener nofollow ugc">pytorch.org</a>
  </header>
  <article class="onebox-body">
    <img src="" class="thumbnail" width="" height="">

<h3><a href="https://pytorch.org/docs/stable/sparse.html#torch.sparse.mm" target="_blank" rel="noopener nofollow ugc">torch.sparse — PyTorch 1.6.0 documentation</a></h3>



  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>

<p><a class="mention" href="/u/caruso">@Caruso</a> thanks again for the help!</p>