-
Notifications
You must be signed in to change notification settings - Fork 25.7k
preserve non-dense or overlapping tensor's layout in *_like functions #46046
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
[ghstack-poisoned]
💊 CI failures summary and remediationsAs of commit b844a54 (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 on the GitHub issue tracker or post in the (internal) Dr. CI Users group. This comment has been revised 67 times. |
This is to solve the non-dense tensor layout problem in #45505 This change will cover all kinds of non-dense tensor. [ghstack-poisoned]
This is to solve the non-dense tensor layout problem in #45505 This change will cover all kinds of non-dense tensor. [ghstack-poisoned]
This is to solve the non-dense tensor layout problem in #45505 TODO: Add test cases Fix all the BC broken test cases This change will cover all kinds of non-dense tensors. [ghstack-poisoned]
This is to solve the non-dense tensor layout problem in #45505 TODO: Fix all the BC broken test cases This change will cover all kinds of non-dense tensors. [ghstack-poisoned]
This is to solve the non-dense tensor layout problem in #45505 TODO: Fix all the BC broken test cases This change will cover all kinds of non-dense tensors. [ghstack-poisoned]
This is to solve the non-dense tensor layout problem in #45505 TODO: Fix all the BC broken test cases This change will cover all kinds of non-dense tensors. [ghstack-poisoned]
…*_like functions" *_like functions are used in pytorch to create a new tensor with the same shape of the input tensor. But we don’t always preserve the layout permutation of the tensor. Current behavior is that, for a dense and non-overlapping tensor, its layout permutation is preserved. For eg. passing a channel last contiguous tensor t with ‘shape/stride’ (2, 4, 3, 2)/(24, 1, 8, 4) to empty_like(t) function will create a new tensor with exactly the same ‘shape/stride’ as the input tensor t. However, if the input tensor is non-dense or has overlap, we simply create a contiguous tensor based on input tensor’s shape, so the tensor layout permutation is lost. This PR preserves the layout permutation for non-dense or overlapping tensor. The strides propagation rule that used in this PR is exactly the same as what is being used in TensorIterator. The behavior changes are listed below: | code | old | new | |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|------------------------------------------------------| | #strided tensors<br>a=torch.randn(2,3,8)[:,:,::2].permute(2,0,1)<br>print(a.stride())<br>print(a.exp().stride())<br>print((a+a).stride())<br>out = torch.empty(0)<br>torch.add(a,a,out=out)<br>print(out.stride()) | (2, 24, 8) <br>(6, 3, 1) <br>(1, 12, 4) <br>(6, 3, 1) | (2, 24, 8)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4) | | #memory dense tensors<br>a=torch.randn(3,1,1).as_strided((3,1,1), (1,3,3))<br>print(a.stride(), (a+torch.randn(1)).stride())<br>a=torch.randn(2,3,4).permute(2,0,1)<br>print(a.stride())<br>print(a.exp().stride())<br>print((a+a).stride())<br>out = torch.empty(0)<br>torch.add(a,a,out=out)<br>print(out.stride()) | (1, 3, 3) (1, 1, 1)<br>(1, 12, 4)<br>(6, 3, 1)<br>(1, 12, 4)<br>(6, 3, 1) | (1, 3, 3) (1, 3, 3)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4) | This is to solve the non-dense tensor layout problem in #45505 TODO: - [x] Fix all the BC broken test cases in pytorch - [ ] Investigate if any fb internal tests are broken This change will cover all kinds of non-dense tensors. [ghstack-poisoned]
…*_like functions" *_like functions are used in pytorch to create a new tensor with the same shape of the input tensor. But we don’t always preserve the layout permutation of the tensor. Current behavior is that, for a dense and non-overlapping tensor, its layout permutation is preserved. For eg. passing a channel last contiguous tensor t with ‘shape/stride’ (2, 4, 3, 2)/(24, 1, 8, 4) to empty_like(t) function will create a new tensor with exactly the same ‘shape/stride’ as the input tensor t. However, if the input tensor is non-dense or has overlap, we simply create a contiguous tensor based on input tensor’s shape, so the tensor layout permutation is lost. This PR preserves the layout permutation for non-dense or overlapping tensor. The strides propagation rule that used in this PR is exactly the same as what is being used in TensorIterator. The behavior changes are listed below: | code | old | new | |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|------------------------------------------------------| | #strided tensors<br>a=torch.randn(2,3,8)[:,:,::2].permute(2,0,1)<br>print(a.stride())<br>print(a.exp().stride())<br>print((a+a).stride())<br>out = torch.empty(0)<br>torch.add(a,a,out=out)<br>print(out.stride()) | (2, 24, 8) <br>(6, 3, 1) <br>(1, 12, 4) <br>(6, 3, 1) | (2, 24, 8)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4) | | #memory dense tensors<br>a=torch.randn(3,1,1).as_strided((3,1,1), (1,3,3))<br>print(a.stride(), (a+torch.randn(1)).stride())<br>a=torch.randn(2,3,4).permute(2,0,1)<br>print(a.stride())<br>print(a.exp().stride())<br>print((a+a).stride())<br>out = torch.empty(0)<br>torch.add(a,a,out=out)<br>print(out.stride()) | (1, 3, 3) (1, 1, 1)<br>(1, 12, 4)<br>(6, 3, 1)<br>(1, 12, 4)<br>(6, 3, 1) | (1, 3, 3) (1, 3, 3)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4) | This is to solve the non-dense tensor layout problem in #45505 TODO: - [x] Fix all the BC broken test cases in pytorch - [ ] Investigate if any fb internal tests are broken This change will cover all kinds of non-dense tensors. Differential Revision: [D24288970](https://our.internmc.facebook.com/intern/diff/D24288970) [ghstack-poisoned]
…*_like functions" *_like functions are used in pytorch to create a new tensor with the same shape of the input tensor. But we don’t always preserve the layout permutation of the tensor. Current behavior is that, for a dense and non-overlapping tensor, its layout permutation is preserved. For eg. passing a channel last contiguous tensor t with ‘shape/stride’ (2, 4, 3, 2)/(24, 1, 8, 4) to empty_like(t) function will create a new tensor with exactly the same ‘shape/stride’ as the input tensor t. However, if the input tensor is non-dense or has overlap, we simply create a contiguous tensor based on input tensor’s shape, so the tensor layout permutation is lost. This PR preserves the layout permutation for non-dense or overlapping tensor. The strides propagation rule that used in this PR is exactly the same as what is being used in TensorIterator. The behavior changes are listed below: | code | old | new | |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|------------------------------------------------------| | #strided tensors<br>a=torch.randn(2,3,8)[:,:,::2].permute(2,0,1)<br>print(a.stride())<br>print(a.exp().stride())<br>print((a+a).stride())<br>out = torch.empty(0)<br>torch.add(a,a,out=out)<br>print(out.stride()) | (2, 24, 8) <br>(6, 3, 1) <br>(1, 12, 4) <br>(6, 3, 1) | (2, 24, 8)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4) | | #memory dense tensors<br>a=torch.randn(3,1,1).as_strided((3,1,1), (1,3,3))<br>print(a.stride(), (a+torch.randn(1)).stride())<br>a=torch.randn(2,3,4).permute(2,0,1)<br>print(a.stride())<br>print(a.exp().stride())<br>print((a+a).stride())<br>out = torch.empty(0)<br>torch.add(a,a,out=out)<br>print(out.stride()) | (1, 3, 3) (1, 1, 1)<br>(1, 12, 4)<br>(6, 3, 1)<br>(1, 12, 4)<br>(6, 3, 1) | (1, 3, 3) (1, 3, 3)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4)<br>(1, 12, 4) | This is to solve the non-dense tensor layout problem in #45505 TODO: - [x] Fix all the BC broken test cases in pytorch - [ ] Investigate if any fb internal tests are broken This change will cover all kinds of non-dense tensors. Differential Revision: [D24288970](https://our.internmc.facebook.com/intern/diff/D24288970) [ghstack-poisoned]
…*_like functions" *_like functions are used in pytorch to create a new tensor with the same shape of the input tensor. But we don’t always preserve the layout permutation of the tensor. Current behavior is that, for a dense and non-overlapping tensor, its layout permutation is preserved. For eg. passing a channel last contiguous tensor t with ‘shape/stride’ (2, 4, 3, 2)/(24, 1, 8, 4) to empty_like(t) function will create a new tensor with exactly the same ‘shape/stride’ as the input tensor t. However, if the input tensor is non-dense or has overlap, we simply create a contiguous tensor based on input tensor’s shape, so the tensor layout permutation is lost. This PR preserves the layout permutation for non-dense or overlapping tensor. The strides propagation rule that used in this PR is exactly the same as what is being used in TensorIterator. The test is based on empty_like. We compare the output tensor's sizes/strides among the empty_like old code, empty_like new code, and TensorIterator based operator exp(). For each sizes/strides we create tensor from both empty_like() and exp() using the following code and record the output tensor's sizes/stride. ``` a = torch.empty_strided([sizes], [strides]) b = torch.empty_like(a) c = torch.exp(a) ``` The output strides changes are listed below: |sizes/strides |old |new |unary op |description | |--------------------|---------------------|--------------------|--------------------|------------------------------------| |(4,3,2)/(10,1,2) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense but overlap | |(4,3,2)/(10,0,3) |(4,3,2)/(6,2,1) |(4,3,2)/(6,2,1) |(4,3,2)/(6,2,1) |non-dense but overlap (0 strided) | |(4,3,2)/(12,2,6) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense non-overlap (sliced) | |(4,3,2)/(10,1,3) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense non-overlap (with gap) | |(4,1,1,2)/(10,0,0,2)|(4,1,1,2)/(2,2,2,1) |(4,1,1,2)/(2,2,2,1) |(4,1,1,2)/(2,2,2,1) |non-dense non-overlap (0 strided) | |(4,1,2)/(10,3,3) |(4,1,2)/(2,2,1) |(4,1,2)/(2,1,1) |(4,1,2)/(2,1,1) |overlap (with equal strides) | |(4,2,2,2)/(2,0,0,6) |(4,2,2,2)/(8,4,2,1) |(4,2,2,2)/(1,8,4,16)|(4,2,2,2)/(1,8,4,16)|overlap (0 strided with equal size) | This is to solve the non-dense tensor layout problem in #45505 TODO: - [x] Fix all the BC broken test cases in pytorch - [ ] Investigate if any fb internal tests are broken This change will cover all kinds of non-dense tensors. Differential Revision: [D24288970](https://our.internmc.facebook.com/intern/diff/D24288970) [ghstack-poisoned]
…e functions" *_like functions are used in pytorch to create a new tensor with the same shape of the input tensor. But we don’t always preserve the layout permutation of the tensor. Current behavior is that, for a dense and non-overlapping tensor, its layout permutation is preserved. For eg. passing a channel last contiguous tensor t with ‘shape/stride’ (2, 4, 3, 2)/(24, 1, 8, 4) to empty_like(t) function will create a new tensor with exactly the same ‘shape/stride’ as the input tensor t. However, if the input tensor is non-dense or has overlap, we simply create a contiguous tensor based on input tensor’s shape, so the tensor layout permutation is lost. This PR preserves the layout permutation for non-dense or overlapping tensor. The strides propagation rule that used in this PR is exactly the same as what is being used in TensorIterator. The test is based on empty_like. We compare the output tensor's sizes/strides among the empty_like old code, empty_like new code, and TensorIterator based operator exp(). For each sizes/strides we create tensor from both empty_like() and exp() using the following code and record the output tensor's sizes/stride. ``` a = torch.empty_strided([sizes], [strides]) b = torch.empty_like(a) c = torch.exp(a) // record the result of b (in both old and new code) and c to create the list below ``` The output strides changes are listed below: |sizes/strides |old |new |unary op |description | |--------------------|---------------------|--------------------|--------------------|------------------------------------| |(4,3,2)/(10,1,2) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense but overlap | |(4,3,2)/(10,0,3) |(4,3,2)/(6,2,1) |(4,3,2)/(6,2,1) |(4,3,2)/(6,2,1) |non-dense but overlap (0 strided) | |(4,3,2)/(12,2,6) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense non-overlap (sliced) | |(4,3,2)/(10,1,3) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense non-overlap (with gap) | |(4,1,1,2)/(10,0,0,2)|(4,1,1,2)/(2,2,2,1) |(4,1,1,2)/(2,2,2,1) |(4,1,1,2)/(2,2,2,1) |non-dense non-overlap (0 strided) | |(4,1,2)/(10,3,3) |(4,1,2)/(2,2,1) |(4,1,2)/(2,1,1) |(4,1,2)/(2,1,1) |overlap (with equal strides) | |(4,2,2,2)/(2,0,0,6) |(4,2,2,2)/(8,4,2,1) |(4,2,2,2)/(1,8,4,16)|(4,2,2,2)/(1,8,4,16)|overlap (0 strided with equal size) | This is to solve the non-dense tensor layout problem in #45505 TODO: - [x] Fix all the BC broken test cases in pytorch - [x] Investigate if any fb internal tests are broken (Update: None so far) This change will cover all kinds of non-dense tensors. Differential Revision: [D24288970](https://our.internmc.facebook.com/intern/diff/D24288970) [ghstack-poisoned]
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.
Looks good, thank you! Nice that all *like functions are handled by changing just empty_like.
…e functions" *_like functions are used in pytorch to create a new tensor with the same shape of the input tensor. But we don’t always preserve the layout permutation of the tensor. Current behavior is that, for a dense and non-overlapping tensor, its layout permutation is preserved. For eg. passing a channel last contiguous tensor t with ‘shape/stride’ (2, 4, 3, 2)/(24, 1, 8, 4) to empty_like(t) function will create a new tensor with exactly the same ‘shape/stride’ as the input tensor t. However, if the input tensor is non-dense or has overlap, we simply create a contiguous tensor based on input tensor’s shape, so the tensor layout permutation is lost. This PR preserves the layout permutation for non-dense or overlapping tensor. The strides propagation rule that used in this PR is exactly the same as what is being used in TensorIterator. The test is based on empty_like. We compare the output tensor's sizes/strides among the empty_like old code, empty_like new code, and TensorIterator based operator exp(). For each sizes/strides we create tensor from both empty_like() and exp() using the following code and record the output tensor's sizes/stride. ``` a = torch.empty_strided([sizes], [strides]) b = torch.empty_like(a) c = torch.exp(a) // record the result of b (in both old and new code) and c to create the list below ``` The output strides changes are listed below: |sizes/strides |old |new |unary op |description | |--------------------|---------------------|--------------------|--------------------|------------------------------------| |(4,3,2)/(10,1,2) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense but overlap | |(4,3,2)/(10,0,3) |(4,3,2)/(6,2,1) |(4,3,2)/(6,2,1) |(4,3,2)/(6,2,1) |non-dense but overlap (0 strided) | |(4,3,2)/(12,2,6) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense non-overlap (sliced) | |(4,3,2)/(10,1,3) |(4,3,2)/(6,2,1) |(4,3,2)/(6,1,3) |(4,3,2)/(6,1,3) |non-dense non-overlap (with gap) | |(4,1,1,2)/(10,0,0,2)|(4,1,1,2)/(2,2,2,1) |(4,1,1,2)/(2,2,2,1) |(4,1,1,2)/(2,2,2,1) |non-dense non-overlap (0 strided) | |(4,1,2)/(10,3,3) |(4,1,2)/(2,2,1) |(4,1,2)/(2,1,1) |(4,1,2)/(2,1,1) |overlap (with equal strides) | |(4,2,2,2)/(2,0,0,6) |(4,2,2,2)/(8,4,2,1) |(4,2,2,2)/(1,8,4,16)|(4,2,2,2)/(1,8,4,16)|overlap (0 strided with equal size) | This is to solve the non-dense tensor layout problem in #45505 TODO: - [x] Fix all the BC broken test cases in pytorch - [x] Investigate if any fb internal tests are broken (Update: None so far) This change will cover all kinds of non-dense tensors. Differential Revision: [D24288970](https://our.internmc.facebook.com/intern/diff/D24288970) [ghstack-poisoned]
|
@glaringlee merged this pull request in a651b87. |
1 similar comment
|
@glaringlee merged this pull request in a651b87. |
Stack from ghstack:
*_like functions are used in pytorch to create a new tensor with the same shape of the input tensor. But we don’t always preserve the layout permutation of the tensor. Current behavior is that, for a dense and non-overlapping tensor, its layout permutation is preserved. For eg. passing a channel last contiguous tensor t with ‘shape/stride’ (2, 4, 3, 2)/(24, 1, 8, 4) to empty_like(t) function will create a new tensor with exactly the same ‘shape/stride’ as the input tensor t. However, if the input tensor is non-dense or has overlap, we simply create a contiguous tensor based on input tensor’s shape, so the tensor layout permutation is lost.
This PR preserves the layout permutation for non-dense or overlapping tensor. The strides propagation rule that used in this PR is exactly the same as what is being used in TensorIterator.
The test is based on empty_like. We compare the output tensor's sizes/strides among the empty_like old code, empty_like new code, and TensorIterator based operator exp(). For each sizes/strides we create tensor from both empty_like() and exp() using the following code and record the output tensor's sizes/stride.
The output strides changes are listed below:
This is to solve the non-dense tensor layout problem in #45505
TODO:
This change will cover all kinds of non-dense tensors.
Differential Revision: D24288970