-
Notifications
You must be signed in to change notification settings - Fork 26.3k
Port torch.copysign method_tests() to OpInfo #54945
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
💊 CI failures summary and remediationsAs of commit 27eb2e1 (more details on the Dr. CI page): 💚 💚 Looks good so far! There are no failures yet. 💚 💚 This comment was automatically generated by Dr. CI (expand for details).Follow this link to opt-out of these comments for your Pull Requests.Please report bugs/suggestions to the (internal) Dr. CI Users group. |
Codecov Report
@@ Coverage Diff @@
## master #54945 +/- ##
==========================================
- Coverage 77.44% 77.23% -0.21%
==========================================
Files 1893 1893
Lines 186472 186477 +5
==========================================
- Hits 144404 144033 -371
- Misses 42068 42444 +376 |
|
|
||
| - func: copysign.Scalar_out(Tensor self, Scalar other, *, Tensor(a!) out) -> Tensor(a!) | ||
| dispatch: | ||
| CPU, CUDA: copysign_out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation is
Tensor& copysign_out(const Tensor& self, const Scalar& other, Tensor& result) {
return at::copysign_out(result, self, wrapped_scalar_tensor(other));
}
which is fully dispatched so CPU, CUDA is overly conservative; CompositeImplicitAutograd would be OK. Even better, though, would be to make the kernel structured (not in this PR though https://github.com/pytorch/rfcs/blob/rfc-0005/RFC-0005-structured-kernel-definitions.md )--if you think you are interested in making it structured, no action necessary here, structured will fix this up later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for reviewing this PR, and I'm really interested in the structured kernel.
A new PR #55040 is created for porting torch.copysign to structured, please kindly take a look.
| low=None, high=None, | ||
| requires_grad=requires_grad) | ||
| else: | ||
| return case |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There isn't really any non-tuple case for you to hit in the examples below, right?
@mruberry is there a more well known function that's supposed to be used in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ezyang The non-tuple cases are hit when constructing args of SampleInput, please kindly refer to https://github.com/pytorch/pytorch/pull/54945/files#r605009953.
I think this branch of checking tuple causes this ambiguity.
It's nearly midnight in my timezone and it took some hours to build PyTorch from the source, I will try improving the readability of this PR tomorrow.
|
Overall this PR looks good but I am not an OpInfo expert so would like @mruberry to take a look |
|
|
||
| return [SampleInput(_make_case(lhs), args=(_make_case(rhs),)) | ||
| for lhs, rhs in cases] | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides using _make_case(lhs) to generate input tensor of SampleInput, the _make_case(rhs) is used for args as well.
The rhs corresponds to the second item of each tuple element.
Hence its values are 3.14, 0.0, and -0.0 for the corresponding scalar cases.
|
This PR is updated with the following changes.
I think this PR is ready for another look. |
Summary: Related #54945 This PR ports `copysign` to structured, and the `copysign.Scalar` overloads are re-dispatched to the structured kernel. Pull Request resolved: #55040 Reviewed By: glaringlee Differential Revision: D27465501 Pulled By: ezyang fbshipit-source-id: 5cbabfeaaaa7ca184ae0b701b9692a918a90b117
mruberry
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Nice simplification, @RockingJavaBean.
|
@mruberry has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
| # broadcast rhs | ||
| (_make_tensor(S, S, S), _make_tensor(S, S)), | ||
| # broadcast lhs | ||
| (_make_tensor(S, S), _make_tensor(S, S, S)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RockingJavaBean @mruberry Any idea how this is working. AFAIK this shouldn't work. Reference: #50747
Surprisingly, I haven't seen any related failed test in master.
But trying to run locally, I am getting error as expected.
============================================================================= FAILURES =============================================================================
________________________________________________ TestCommonCPU.test_variant_consistency_eager_copysign_cpu_float32 _________________________________________________
Traceback (most recent call last):
File "/home/kshiteej/Pytorch/pytorch_inplace_broadcast_test/test/test_ops.py", line 306, in test_variant_consistency_eager
_test_consistency_helper(inplace_samples, inplace_variants)
File "/home/kshiteej/Pytorch/pytorch_inplace_broadcast_test/test/test_ops.py", line 290, in _test_consistency_helper
variant_forward = variant(cloned,
RuntimeError: output with shape [5, 5] doesn't match the broadcast shape [5, 5, 5]
_______________________________________________ TestCommonCUDA.test_variant_consistency_eager_copysign_cuda_float32 ________________________________________________
Traceback (most recent call last):
File "/home/kshiteej/Pytorch/pytorch_inplace_broadcast_test/test/test_ops.py", line 306, in test_variant_consistency_eager
_test_consistency_helper(inplace_samples, inplace_variants)
File "/home/kshiteej/Pytorch/pytorch_inplace_broadcast_test/test/test_ops.py", line 290, in _test_consistency_helper
variant_forward = variant(cloned,
RuntimeError: output with shape [5, 5] doesn't match the broadcast shape [5, 5, 5]
========================================================================= warnings summary =========================================================================
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While trying to see the CI build log, I noticed something odd.
Looking at the CI run for pytorch_linux_xenial_cuda10_2_cudnn7_py3_gcc7_test1.
There is no result for test_variant_consistency_eager_copysign_cpu_float32.
Relevant lines from the log linked below
Details
Apr 01 17:21:54 test_variant_consistency_eager_broadcast_to_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_broadcast_to_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_ceil_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_cholesky_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.006s)
Apr 01 17:21:54 test_variant_consistency_eager_cholesky_cpu_float32 (__main__.TestCommonCPU) ... ok (0.005s)
Apr 01 17:21:54 test_variant_consistency_eager_cholesky_inverse_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.003s)
Apr 01 17:21:54 test_variant_consistency_eager_cholesky_inverse_cpu_float32 (__main__.TestCommonCPU) ... ok (0.005s)
Apr 01 17:21:54 test_variant_consistency_eager_clamp_cpu_float32 (__main__.TestCommonCPU) ... ok (0.006s)
Apr 01 17:21:54 test_variant_consistency_eager_conj_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_conj_cpu_float32 (__main__.TestCommonCPU) ... ok (0.003s)
Apr 01 17:21:54 test_variant_consistency_eager_cos_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_cos_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_cosh_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_cosh_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_cummax_cpu_float32 (__main__.TestCommonCPU) ... ok (0.003s)
Apr 01 17:21:54 test_variant_consistency_eager_cummin_cpu_float32 (__main__.TestCommonCPU) ... ok (0.003s)
Apr 01 17:21:54 test_variant_consistency_eager_cumprod_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.007s)
Apr 01 17:21:54 test_variant_consistency_eager_cumprod_cpu_float32 (__main__.TestCommonCPU) ... ok (0.006s)
Apr 01 17:21:54 test_variant_consistency_eager_cumsum_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.005s)
Apr 01 17:21:54 test_variant_consistency_eager_cumsum_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_deg2rad_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_diag_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.005s)
Apr 01 17:21:54 test_variant_consistency_eager_diag_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 17:21:54 test_variant_consistency_eager_diff_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.005s)
Apr 01 17:21:54 test_variant_consistency_eager_diff_cpu_float32 (__main__.TestCommonCPU) ... ok (0.005s)
Apr 01 17:21:54 test_variant_consistency_eager_digamma_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
@mruberry Did I miss something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line causes the issue.
Line 238 in c821b83
| variants = (v for v in (method, inplace) + aliases if v is not None) |
variants is a generator so it is exhausted in the first run (refer python snippet below)
Thus the following loop does not run except for the first sample
Lines 268 to 286 in c821b83
| # Test eager consistency | |
| for variant in variants: | |
| # Skips inplace ops | |
| if variant in inplace_ops and skip_inplace: | |
| continue | |
| # Compares variant's forward | |
| # Note: copies the to-be-modified input when testing the inplace variant | |
| tensor.grad = None | |
| cloned = clone_input_helper(sample.input) if variant in inplace_ops else sample.input | |
| variant_forward = variant(cloned, | |
| *sample.args, | |
| **sample.kwargs) | |
| self.assertEqual(expected_forward, variant_forward) | |
| # Compares variant's backward | |
| if expected_grad is not None and (variant not in inplace_ops or op.supports_inplace_autograd): | |
| variant_forward.sum().backward() | |
| self.assertEqual(expected_grad, tensor.grad) |
Example
>>> def print_iterable(iterable):
... for x in iterable:
... print(x)
...
>>> l = [x for x in range(3)] # list comprehension
>>> print_iterable(l)
0
1
2
>>> print_iterable(l)
0
1
2
>>> l = (x for x in range(3)) # generator expression
>>> print_iterable(l)
0
1
2
>>> print_iterable(l)
>>>There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While trying to see the CI build log, I noticed something odd.
Looking at the CI run for
pytorch_linux_xenial_cuda10_2_cudnn7_py3_gcc7_test1.There is no result for
test_variant_consistency_eager_copysign_cpu_float32.Relevant lines from the log linked below
@mruberry Did I miss something?
@kshitij12345 Thank you so much for pointing this out.
According to pytorch_linux_xenial_cuda10_2_cudnn7_py3_gcc7_test1 triggered by the last commit of this PR 27eb2e1, the test_variant_consistency_eager_copysign_cpu did run and pass.
Apr 01 06:48:33 test_variant_consistency_eager_conj_cpu_float32 (__main__.TestCommonCPU) ... ok (0.003s)
Apr 01 06:48:33 test_variant_consistency_eager_copysign_cpu_float32 (__main__.TestCommonCPU) ... ok (0.004s)
Apr 01 06:48:33 test_variant_consistency_eager_cos_cpu_complex64 (__main__.TestCommonCPU) ... ok (0.004s)
And after checking the test_variant_consistency_eager in test_ops.py, I agree with you that the exhausted generator for variants leads to the skipping of SampleInputs and it is why cases for broadcasted self tensor pass without resolving issue 50747.
I'm really appreciated your PR #53014 for fixing this issue, I think it will enable testing broadcasted self tensor with OpInfo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RockingJavaBean
Right. My bad. I wonder why the log I checked did not have it.
But I can confirm it is running.
Apologies for the false alarm.
Thanks for looking into it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But this exposes a horrible problem with the use of generator expressions like this in sample inputs; many tests are "running" but not actually performing the test properly.
@kshitij12345, @vfdev-5, what's the best way to fix this and validate the fix so the behavior isn't regressed later? One simple approach might be to validate that len(sample_inputs) > 0 in all the tests that enumerate them for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't do len on generators. So I think right now we can just do variants=tuple(genearator expression). But how to detect so that this doesn't happen in general case is worth some thought 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... maybe we'll just have to be vigilant to detect it. But it'd be nice if we could not only detect that a test ran but that it actually did something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think looking at answers for this question at Stack Overflow might give us a nice idea.
Related #54261
This PR ports the method_tests() entries of
torch.copysignto OpInfo.While porting the tests, the
test_outcases fromtest_ops.pywould fail as the out variant oftorch.copysigndoes not support scalar inputs.This PR fixes the tests by adding an overload
native_functionsentry and re-dispatching scalar inputs to the existingcopysign_outfunction.