Skip to content

Get boolean masking to work with unbacked SymInts#94523

Closed
ezyang wants to merge 16 commits intogh/ezyang/1806/basefrom
gh/ezyang/1806/head
Closed

Get boolean masking to work with unbacked SymInts#94523
ezyang wants to merge 16 commits intogh/ezyang/1806/basefrom
gh/ezyang/1806/head

Conversation

@ezyang
Copy link
Copy Markdown
Contributor

@ezyang ezyang commented Feb 9, 2023

Stack from ghstack (oldest at bottom):

This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

  • Feature guard tracing through nonzero with capture_dynamic_output_shape_ops because Inductor generally can't handle it
  • Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
  • Refactor compute_elementwise_output_strides to return the output permutation. I then use this to rewrite the empty_like reference to avoid calling empty_strided; instead, it allocates calls empty_permuted.
  • Refactor _broadcast_shapes to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
  • Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
  • Don't record memory_format on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang ezyang@meta.com

cc @soumith @voznesenskym @yanboliang @penguinwu @anijain2305 @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @Xia-Weiwen @wenzhe-nrv @jiayisunx @desertfire

Signed-off-by: Edward Z. Yang <ezyang@meta.com>

[ghstack-poisoned]
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* When we allocate a contiguous tensor, hard code relevant fields (e.g., `is_contiguous_`) true, instead of keeping the complicated guardless implementation. As Horace notes, all guardless implementations really do is push off the evaluation problem until later. We do poke contiguity reasonably often, but we also typically allocate these with torch.empty so we know statically they are contiguous.
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Don't rewrap tensors in TensorMeta; it does nothing but hits `empty_strided` which is generally not unbacked SymInt friendly
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates a contiguous tensor and permutes it.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't remove leading 1s in setitem unless the value tensor is too big for the input tensor. Submitted separately at #94521
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

[ghstack-poisoned]
@pytorch-bot
Copy link
Copy Markdown

pytorch-bot bot commented Feb 9, 2023

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/94523

Note: Links to docs will display an error until the docs builds have been completed.

This comment was automatically generated by Dr. CI and updates every 15 minutes.

ezyang added a commit that referenced this pull request Feb 9, 2023
Signed-off-by: Edward Z. Yang <ezyangmeta.com>

ghstack-source-id: 894aec9
Pull Request resolved: #94523
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* When we allocate a contiguous tensor, hard code relevant fields (e.g., `is_contiguous_`) true, instead of keeping the complicated guardless implementation. As Horace notes, all guardless implementations really do is push off the evaluation problem until later. We do poke contiguity reasonably often, but we also typically allocate these with torch.empty so we know statically they are contiguous.
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Don't rewrap tensors in TensorMeta; it does nothing but hits `empty_strided` which is generally not unbacked SymInt friendly
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates a contiguous tensor and permutes it.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't remove leading 1s in setitem unless the value tensor is too big for the input tensor. Submitted separately at #94521
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

[ghstack-poisoned]
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* When we allocate a contiguous tensor, hard code relevant fields (e.g., `is_contiguous_`) true, instead of keeping the complicated guardless implementation. As Horace notes, all guardless implementations really do is push off the evaluation problem until later. We do poke contiguity reasonably often, but we also typically allocate these with torch.empty so we know statically they are contiguous.
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Don't rewrap tensors in TensorMeta; it does nothing but hits `empty_strided` which is generally not unbacked SymInt friendly
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates a contiguous tensor and permutes it.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't remove leading 1s in setitem unless the value tensor is too big for the input tensor. Submitted separately at #94521
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

[ghstack-poisoned]
ezyang added a commit that referenced this pull request Feb 10, 2023
Signed-off-by: Edward Z. Yang <ezyangmeta.com>

ghstack-source-id: 4f2cf74
Pull Request resolved: #94523
@albanD albanD removed their request for review February 10, 2023 18:21
ezyang added a commit that referenced this pull request Feb 16, 2023
Extracted from #94523

Signed-off-by: Edward Z. Yang <ezyang@meta.com>

[ghstack-poisoned]
ezyang added a commit that referenced this pull request Feb 16, 2023
Extracted from #94523

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

ghstack-source-id: 45a7e62
Pull Request resolved: #95004
ezyang added a commit that referenced this pull request Feb 16, 2023
…nts"

Extracted from #94523 which has E2E test

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

[ghstack-poisoned]
ezyang added a commit that referenced this pull request Feb 16, 2023
Extracted from #94523 which has E2E test

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

ghstack-source-id: ed0f8a0
Pull Request resolved: #95003
pytorchmergebot pushed a commit that referenced this pull request Feb 17, 2023
Extracted from #94523 which has E2E test

Signed-off-by: Edward Z. Yang <ezyang@meta.com>
Pull Request resolved: #95003
Approved by: https://github.com/voznesenskym, https://github.com/ngimel
pytorchmergebot pushed a commit that referenced this pull request Feb 17, 2023
Extracted from #94523

Signed-off-by: Edward Z. Yang <ezyang@meta.com>
Pull Request resolved: #95004
Approved by: https://github.com/voznesenskym, https://github.com/ngimel, https://github.com/Skylion007
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* When we allocate a contiguous tensor, hard code relevant fields (e.g., `is_contiguous_`) true, instead of keeping the complicated guardless implementation. As Horace notes, all guardless implementations really do is push off the evaluation problem until later. We do poke contiguity reasonably often, but we also typically allocate these with torch.empty so we know statically they are contiguous.
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Don't rewrap tensors in TensorMeta; it does nothing but hits `empty_strided` which is generally not unbacked SymInt friendly
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates a contiguous tensor and permutes it.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't remove leading 1s in setitem unless the value tensor is too big for the input tensor. Submitted separately at #94521
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

[ghstack-poisoned]
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* When we allocate a contiguous tensor, hard code relevant fields (e.g., `is_contiguous_`) true, instead of keeping the complicated guardless implementation. As Horace notes, all guardless implementations really do is push off the evaluation problem until later. We do poke contiguity reasonably often, but we also typically allocate these with torch.empty so we know statically they are contiguous.
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Don't rewrap tensors in TensorMeta; it does nothing but hits `empty_strided` which is generally not unbacked SymInt friendly
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates a contiguous tensor and permutes it.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't remove leading 1s in setitem unless the value tensor is too big for the input tensor. Submitted separately at #94521
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc soumith voznesenskym yanboliang penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx desertfire

[ghstack-poisoned]
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* Feature guard tracing through nonzero with capture_dynamic_output_shape_ops because Inductor generally can't handle it
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates calls `empty_permuted`.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc soumith voznesenskym yanboliang penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx desertfire

[ghstack-poisoned]
@ezyang ezyang mentioned this pull request Feb 20, 2023
@ezyang ezyang removed the keep-going Don't stop on first failure, keep running tests until the end label Feb 20, 2023
@soulitzer soulitzer removed their request for review February 20, 2023 23:58
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* Feature guard tracing through nonzero with capture_dynamic_output_shape_ops because Inductor generally can't handle it
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates calls `empty_permuted`.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc soumith voznesenskym yanboliang penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx desertfire

[ghstack-poisoned]
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* Feature guard tracing through nonzero with capture_dynamic_output_shape_ops because Inductor generally can't handle it
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates calls `empty_permuted`.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc soumith voznesenskym yanboliang penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx desertfire

[ghstack-poisoned]
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* Feature guard tracing through nonzero with capture_dynamic_output_shape_ops because Inductor generally can't handle it
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates calls `empty_permuted`.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc soumith voznesenskym yanboliang penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx desertfire

[ghstack-poisoned]
This adds support for unbacked SymInts from nonzero, and then gets this working end-to-end with advanced indexing and boolean masking. I needed to apply a variety of fixes to get this to work; these fixes are emblematic of the kind of enablement work we will need to do for unbacked SymInts as they are used more heavily.

* Feature guard tracing through nonzero with capture_dynamic_output_shape_ops because Inductor generally can't handle it
* Allow boolean tensors into the index.Tensor meta, and redirect fake tensor to call the meta function directly (so that when it calls nonzero, it decomposes to the fake tensor nonzero)
* Refactor `compute_elementwise_output_strides` to return the output permutation. I then use this to rewrite the `empty_like` reference to avoid calling `empty_strided`; instead, it allocates calls `empty_permuted`.
* Refactor `_broadcast_shapes` to test for more common cases (shapes are equal) before broadcasting case, which is enough to get the broadcasting in advanced indexing going without adding an unnecessary == 1 guard.
* Make nonzero return an unbacked symint in size, and put enough assumptions on it so that the boolean masking end to end works
* Don't record `memory_format` on TensorMeta if there are unbacked SymInts. Actually, we can probably do a bit better here; sometimes a tensor will have unbacked SymInt but is obviously contiguous and we ought to report that. Leaving that for future work.

Signed-off-by: Edward Z. Yang <ezyangmeta.com>

cc soumith voznesenskym yanboliang penguinwu anijain2305 EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng Xia-Weiwen wenzhe-nrv jiayisunx desertfire

[ghstack-poisoned]
@ezyang ezyang requested a review from suo February 21, 2023 15:39
@ezyang ezyang closed this Feb 23, 2023
@facebook-github-bot facebook-github-bot deleted the gh/ezyang/1806/head branch June 8, 2023 16:49
jhavukainen pushed a commit to kulinseth/pytorch that referenced this pull request Mar 15, 2024
…h#95003)

Extracted from pytorch#94523 which has E2E test

Signed-off-by: Edward Z. Yang <ezyang@meta.com>
Pull Request resolved: pytorch#95003
Approved by: https://github.com/voznesenskym, https://github.com/ngimel
jhavukainen pushed a commit to kulinseth/pytorch that referenced this pull request Mar 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/inductor ciflow/trunk Trigger trunk jobs on your pull request module: dynamo release notes: fx release notes category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant