-
Notifications
You must be signed in to change notification settings - Fork 26.3k
Clarified difference in behavior of empty_strided and as_strided
#64568
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
Fix: #64389 [ghstack-poisoned]
🔗 Helpful links
💊 CI failures summary and remediationsAs of commit 8e11f36 (more details on the Dr. CI page):
🕵️ 1 new failure recognized by patternsThe following CI failures do not appear to be due to upstream breakages:
|
Codecov Report
@@ Coverage Diff @@
## gh/ysiraichi/28/base #64568 +/- ##
========================================================
+ Coverage 66.64% 66.72% +0.07%
========================================================
Files 707 707
Lines 92346 92346
========================================================
+ Hits 61546 61619 +73
+ Misses 30800 30727 -73 |
|
@mruberry this is a friendly reminder. Do you have some time to take a look at this PR? |
torch/_torch_docs.py
Outdated
| :meth:`torch.Tensor.expand`, are easier to read and are therefore more | ||
| advisable to use. | ||
| .. warning:: |
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.
Hey @ysiraichi, thanks for the ping and sorry to make you wait for a review. Now let's talk about as_strided and empty_strided and use this opportunity to correct and modernize their documentation.
First, I don't think the documentation for this function is correct, and that's part of what has made this PR hard to review. Let's look at an example program:
t = torch.tensor((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))[::2]
# t = tensor([1, 3, 5, 7, 9])
v = torch.as_strided(t, size=[2], stride=[1])
# v = tensor([1, 2])
In what sense is v a view of t? It contains a value not found in t!
And when we look at the implementation of as_strided this makes sense:
pytorch/aten/src/ATen/native/TensorShape.cpp
Line 769 in 0a3cf88
| Tensor as_strided_tensorimpl(const Tensor& self, IntArrayRef size, IntArrayRef stride, optional<int64_t> storage_offset_) { |
because it seems like as_strided creates a view of :attr:`input`'s storage, not a view of :attr:`input`. So first we need to explain that.
Now let's talk about warning. It's trying to tell us two things:
- creating an "overlapped" tensor where multiple indices refer to the same element is a bad idea
- you probably shouldn't use this function
This seems like a strange warning to me, so let's dig into its history: #22842 (comment). Seems like there were concerns about exposing as_strided at all, which is reasonable, but I think we can do a better job with this warning.
What would you think of changing the warning to this, instead:
"Prefer using other view functions, like :meth:`torch.Tensor.expand`, to setting a view's strides manually with `as_strided`, as this function's behavior depends on the implementation of a tensor's storage. The constructed view of the storage must only refer to elements within the storage or a runtime error will be thrown, and if the view is "overlapped" (with multiple indices referring to the same element in memory) its behavior is undefined."
This more clearly communicates why this function shouldn't be used -- because storage is an implementation detail and relying on it is inherently risky and strange for users. This also simplifies the other warnings.
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.
That sounds way better! Thanks, @mruberry. I will change it right away!
torch/_torch_docs.py
Outdated
| r""" | ||
| empty_strided(size, stride, *, dtype=None, layout=None, device=None, requires_grad=False, pin_memory=False) -> Tensor | ||
| Returns a tensor filled with uninitialized data. The shape and strides of the tensor is |
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.
In light of the above discussion we should carefully update the documentation of empty_strided, too.
Let's start with the first paragraph:
"Creates a tensor with the specified :attr:`size` and :attr:`stride` and filled with undefined data."
This modernizes the language, preserves this PR's fix, and doesn't include implementation details like how much memory is allocated.
I don't know if a note about about how much memory an implementation of this function could use is interesting to users. So maybe we could drop it?
Now let's talk about the warning for this function. This warning is intended to say "don't create an overlapped tensor", and we can do that more easily (following the above):
"If the constructed tensor is "overlapped" (with multiple indices referring to the same element in memory) its behavior is undefined."
We don't declare "overlapped" behaviors as having undefined behavior in a note (yet), but we probably should.
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 agree. The amount of allocated memory doesn't sound that useful here.
…s_strided`" Fix: #64389 [ghstack-poisoned]
…s_strided`" Fix: #64389 [ghstack-poisoned]
|
@mruberry I have addressed your changes and rebased this PR. Do you have some time to take a look at this it? |
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.
Cool! Thanks @ysiraichi!
|
@mruberry has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
Stack from ghstack:
empty_stridedandas_strided#64568 Clarified difference in behavior ofempty_stridedandas_stridedFix: #64389
Differential Revision: D31299999