Skip to content

Conversation

@yf225
Copy link
Contributor

@yf225 yf225 commented Aug 2, 2019

Running apply() on a legacy autograd function can also cause the non-static forward() to be called. In order to deprecate legacy autograd functions in 1.3, we should also print warning when the user tries to use legacy autograd function by calling apply() on it.

@yf225 yf225 requested a review from gchanan August 2, 2019 04:37
@pytorchbot pytorchbot added module: autograd Related to torch.autograd, and the autograd engine in general module: pybind Related to our Python bindings / interactions with other Python libraries labels Aug 2, 2019
@gchanan
Copy link
Contributor

gchanan commented Aug 2, 2019

I don't think I fully understand what's going on here. There are a bunch of checks in the engine for if we are invoking legacy autograd functions -- it's looking for stuff like are there staticmethod forwards/backwards, etc. Is it "fine" to have non-staticmethods as long as you call apply? Does it invoke the legacy path in that case?

@yf225
Copy link
Contributor Author

yf225 commented Aug 2, 2019

@gchanan I think the biggest concern about legacy autograd function is clobbering between different function calls: #22983 (comment). I adapt the test case that shows clobbering to use apply(), and got the following result:

# `test_call_legacy_twice` is currently in test_autograd.py
def test_call_legacy_twice(self):
    class Id(Function):
        def forward(self, x):
            self.save_for_backward(x)
            return x

        def backward(self, grad_x):
            x = self.saved_tensors
            return x

    x1 = torch.zeros(1, requires_grad=True)
    x2 = torch.ones(1, requires_grad=True)
    y = Id.apply(x1)
    z = Id.apply(x2)
    y.backward()
    self.assertEqual(x2.grad, x2)
    self.assertNotEqual(x1.grad, x2)  # If clobbering happens, x1.grad == x2

Running this code gives error:

Traceback (most recent call last):
  File "test_autograd.py", line 1745, in test_call_legacy_twice
    y.backward()
  File "/data/miniconda3/envs/working2/lib/python3.7/site-packages/torch/tensor.py", line 118, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "/data/miniconda3/envs/working2/lib/python3.7/site-packages/torch/autograd/__init__.py", line 93, in backward
    allow_unreachable=True)  # allow_unreachable flag
  File "/data/miniconda3/envs/working2/lib/python3.7/site-packages/torch/autograd/function.py", line 77, in apply
    return self._forward_cls.backward(self, *args)
  File "/data/miniconda3/envs/working2/lib/python3.7/site-packages/torch/autograd/function.py", line 181, in backward
    raise NotImplementedError
NotImplementedError

Based on this result, I think calling apply() on legacy autograd function doesn't actually work (because calling backward() on the output gives error). So I think it's okay to not print a warning in this case and close this PR.

@yf225
Copy link
Contributor Author

yf225 commented Aug 2, 2019

I tested all versions from 0.4.0 to 1.1.0, and can confirm that calling backward() on the output of legacy autograd function apply() always gives NotImplementedError.

@yf225 yf225 closed this Aug 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module: autograd Related to torch.autograd, and the autograd engine in general module: pybind Related to our Python bindings / interactions with other Python libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants