KEMBAR78
(is_non_overlapping_and_dense) gso to guard_or_false in when checking length 1 by ColinPeppler · Pull Request #158894 · pytorch/pytorch · GitHub
Skip to content

Conversation

@ColinPeppler
Copy link
Contributor

@ColinPeppler ColinPeppler commented Jul 23, 2025

Switch from guard_size_oblivious to guard_or_false if you encounter a DDE, this would then fallback to computing elementwise strides.

# dtype conversion preserves dense strides
if torch._prims_common.is_non_overlapping_and_dense(a):
strides = a.stride()
else:
strides = utils.compute_elementwise_output_strides(a)

We think it's safe because Laith tested whether this fallback would fail any tests. It did not.
#158157

Data-dependent exceptions (DDE)

  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 494, in is_non_overlapping_and_dense
    if guard_size_oblivious(length == 1):
GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(u0 - 4, 1) (unhinted: Eq(u0 - 4, 1)).  (Size-like symbols: u0)

Stack from ghstack (oldest at bottom):

cc @ezyang @penguinwu @bobrenjc93 @voznesenskym @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @ipiszy @chenyang78 @kadeng @muchulee8 @amjames @chauhang @aakhundov @coconutruben

… length-1 & expected stride

[ghstack-poisoned]
@pytorch-bot
Copy link

pytorch-bot bot commented Jul 23, 2025

🔗 Helpful Links

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

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

✅ You can merge normally! (3 Unrelated Failures)

As of commit 79fb24c with merge base 255a04b (image):

BROKEN TRUNK - The following jobs failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

UNSTABLE - The following job is marked as unstable, possibly due to flakiness on trunk:

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

ColinPeppler added a commit that referenced this pull request Jul 23, 2025
… length-1 & expected stride

ghstack-source-id: d2cea01
Pull Request resolved: #158894
@ColinPeppler ColinPeppler added the topic: not user facing topic category label Jul 23, 2025
…en checking length-1 & expected stride"

Switch from `guard_size_oblivious` to `guard_or_false` if you encounter a DDE, this would then fallback to computing elementwise strides.

https://github.com/pytorch/pytorch/blob/2dccff7dcf56b0d168ebfd7ca08bdeca37273c56/torch/_prims/__init__.py#L1919-L1923

We think it's safe because Laith tested whether this fallback would fail any tests. It did not.
#158157

## Data-dependent exceptions (DDE)
```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 494, in is_non_overlapping_and_dense
    if guard_size_oblivious(length == 1):
GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(u0 - 4, 1) (unhinted: Eq(u0 - 4, 1)).  (Size-like symbols: u0)
```

```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 500, in is_non_overlapping_and_dense
    if guard_size_oblivious(stride != expected_stride):

Caused by: unbacked_size.int(),  # test/inductor/test_unbacked_symints.py:538 in fn (_prims_common/__init__.py:500 in is_non_overlapping_and_dense)
```




cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy chenyang78 kadeng muchulee8 amjames chauhang aakhundov coconutruben

[ghstack-poisoned]
ColinPeppler added a commit that referenced this pull request Jul 23, 2025
… length-1 & expected stride

ghstack-source-id: e0765d1
Pull Request resolved: #158894
…en checking length-1 & expected stride"

Switch from `guard_size_oblivious` to `guard_or_false` if you encounter a DDE, this would then fallback to computing elementwise strides.

https://github.com/pytorch/pytorch/blob/2dccff7dcf56b0d168ebfd7ca08bdeca37273c56/torch/_prims/__init__.py#L1919-L1923

We think it's safe because Laith tested whether this fallback would fail any tests. It did not.
#158157

## Data-dependent exceptions (DDE)
```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 494, in is_non_overlapping_and_dense
    if guard_size_oblivious(length == 1):
GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(u0 - 4, 1) (unhinted: Eq(u0 - 4, 1)).  (Size-like symbols: u0)
```

```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 500, in is_non_overlapping_and_dense
    if guard_size_oblivious(stride != expected_stride):

Caused by: unbacked_size.int(),  # test/inductor/test_unbacked_symints.py:538 in fn (_prims_common/__init__.py:500 in is_non_overlapping_and_dense)
```




cc voznesenskym penguinwu EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy chenyang78 kadeng muchulee8 amjames chauhang aakhundov coconutruben

[ghstack-poisoned]
ColinPeppler added a commit that referenced this pull request Jul 23, 2025
… length-1 & expected stride

ghstack-source-id: 06866e6
Pull Request resolved: #158894
…en checking length-1 & expected stride"

Switch from `guard_size_oblivious` to `guard_or_false` if you encounter a DDE, this would then fallback to computing elementwise strides.

https://github.com/pytorch/pytorch/blob/2dccff7dcf56b0d168ebfd7ca08bdeca37273c56/torch/_prims/__init__.py#L1919-L1923

We think it's safe because Laith tested whether this fallback would fail any tests. It did not.
#158157

## Data-dependent exceptions (DDE)
```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 494, in is_non_overlapping_and_dense
    if guard_size_oblivious(length == 1):
GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(u0 - 4, 1) (unhinted: Eq(u0 - 4, 1)).  (Size-like symbols: u0)
```

```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 500, in is_non_overlapping_and_dense
    if guard_size_oblivious(stride != expected_stride):

Caused by: unbacked_size.int(),  # test/inductor/test_unbacked_symints.py:538 in fn (_prims_common/__init__.py:500 in is_non_overlapping_and_dense)
```




cc ezyang penguinwu bobrenjc93 voznesenskym EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy chenyang78 kadeng muchulee8 amjames chauhang aakhundov coconutruben

[ghstack-poisoned]
ColinPeppler added a commit that referenced this pull request Jul 23, 2025
… length-1 & expected stride

ghstack-source-id: 13159fe
Pull Request resolved: #158894
continue

if guard_size_oblivious(stride != expected_stride):
if guard_or_false(stride != expected_stride):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NGL, this is pretty suspicious. Let's suppose I have a tensor with size (u0, u1) and stride (u2, u3). If we somehow get to this loop, we will never trigger any of the conditions here, and then we will return True (that it is non overlapping and dense). But... it's clearly NOT??? Like I can trivially fill in values of u0..u3 that would make it overlapping. It is MUCH safer to guard_or_true here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point! I originally did not see it this way. This will be a better test case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so I decided not to replace gso here. Otherwise, we'd go into the compute_elementwise_output_strides path which means we'd need to address sorting unbacked strides.

…en checking length-1 & expected stride"

Switch from `guard_size_oblivious` to `guard_or_false` if you encounter a DDE, this would then fallback to computing elementwise strides.

https://github.com/pytorch/pytorch/blob/2dccff7dcf56b0d168ebfd7ca08bdeca37273c56/torch/_prims/__init__.py#L1919-L1923

We think it's safe because Laith tested whether this fallback would fail any tests. It did not.
#158157

## Data-dependent exceptions (DDE)
```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 494, in is_non_overlapping_and_dense
    if guard_size_oblivious(length == 1):
GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(u0 - 4, 1) (unhinted: Eq(u0 - 4, 1)).  (Size-like symbols: u0)
```

```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 500, in is_non_overlapping_and_dense
    if guard_size_oblivious(stride != expected_stride):

Caused by: unbacked_size.int(),  # test/inductor/test_unbacked_symints.py:538 in fn (_prims_common/__init__.py:500 in is_non_overlapping_and_dense)
```




cc ezyang penguinwu bobrenjc93 voznesenskym EikanWang jgong5 Guobing-Chen XiaobingSuper zhuhaozhe blzheng wenzhe-nrv jiayisunx ipiszy chenyang78 kadeng muchulee8 amjames chauhang aakhundov coconutruben

[ghstack-poisoned]
ColinPeppler added a commit that referenced this pull request Jul 25, 2025
… length-1 & expected stride

ghstack-source-id: 1e869f9
Pull Request resolved: #158894
@ColinPeppler ColinPeppler changed the title (is_non_overlapping_and_dense) gso to guard_or_false in when checking length-1 & expected stride (is_non_overlapping_and_dense) gso to guard_or_false in when checking length 1 Jul 25, 2025
Copy link
Contributor

@pianpwk pianpwk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smaller change seems straightforward enough

@ColinPeppler
Copy link
Contributor Author

@pytorchbot merge

@pytorch-bot pytorch-bot bot added the ciflow/trunk Trigger trunk jobs on your pull request label Jul 25, 2025
@pytorchmergebot
Copy link
Collaborator

Merge started

Your change will be merged once all checks pass (ETA 0-4 Hours).

Learn more about merging in the wiki.

Questions? Feedback? Please reach out to the PyTorch DevX Team

Advanced Debugging
Check the merge workflow status
here

@laithsakka
Copy link
Contributor

laithsakka commented Jul 25, 2025

I will approve to unblock current usecase, but I would probably rewrite this by introducing is_non_overlapping_and_dense_or_false and use it in the _convert_element_type_meta, that would be the unbacked semantics of that part.

@laithsakka
Copy link
Contributor

laithsakka commented Jul 26, 2025

I think i have an idea how to get rid of the size oblivious here, the main idea is the following:
given unbacked strides whats the worse case that can happen if we do wrong sorting?

Answer : we would return False ! lol so not the end of the world if the function definitions is

# may return false for unbacked input instead of throwing DDE.

def is_non_overlapping_and_dense_or_false(a: Tensor) -> bool:

that said we should try to do correct sorting as much as we can using the Modulus idea.

pytorchmergebot pushed a commit that referenced this pull request Jul 30, 2025
…3d bmm into 2d mm (#159184)

Switch from guard_size_oblivious to guard_or_false if you encounter a DDE, this would then avoid folding this 3d bmm into a mm.

https://github.com/pytorch/pytorch/blob/806d9e3fe70ec250a1fb3823841d16c61b7d1b02/torch/_decomp/decompositions.py#L4506-L4512

## DDE
```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4506, in matmul
    elif should_fold(tensor1, tensor2, is_out):
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4472, in should_fold
    if guard_size_oblivious(t1.numel() == 0):
torch.fx.experimental.symbolic_shapes.GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(12*((u0//2)), 0) (unhinted: Eq(12*((u0//2)), 0)).  (Size-like symbols: none)

Caused by: (_decomp/decompositions.py:4472 in should_fold)
```

```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4506, in matmul
    elif should_fold(tensor1, tensor2, is_out):
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4483, in should_fold
    return all(
torch.fx.experimental.symbolic_shapes.GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(3*((u0//2)), 3) (unhinted: Eq(3*((u0//2)), 3)).  (Size-like symbols: none)

Caused by: (_decomp/decompositions.py:4483 in should_fold)
```

Pull Request resolved: #159184
Approved by: https://github.com/ezyang
ghstack dependencies: #158894
yangw-dev pushed a commit that referenced this pull request Aug 1, 2025
… length 1 (#158894)

Switch from `guard_size_oblivious` to `guard_or_false` if you encounter a DDE, this would then fallback to computing elementwise strides.

https://github.com/pytorch/pytorch/blob/2dccff7dcf56b0d168ebfd7ca08bdeca37273c56/torch/_prims/__init__.py#L1919-L1923

We think it's safe because Laith tested whether this fallback would fail any tests. It did not.
#158157

## Data-dependent exceptions (DDE)
```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 2139, in _to_copy
    x_tensor = torch._prims.convert_element_type(x_tensor, dtype)
  ...
  File "/data/users/colinpeppler/pytorch/torch/_prims/__init__.py", line 1920, in _convert_element_type_meta
    if torch._prims_common.is_non_overlapping_and_dense(a):
  File "/data/users/colinpeppler/pytorch/torch/_prims_common/__init__.py", line 494, in is_non_overlapping_and_dense
    if guard_size_oblivious(length == 1):
GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(u0 - 4, 1) (unhinted: Eq(u0 - 4, 1)).  (Size-like symbols: u0)
```

Pull Request resolved: #158894
Approved by: https://github.com/pianpwk, https://github.com/laithsakka
yangw-dev pushed a commit that referenced this pull request Aug 1, 2025
…3d bmm into 2d mm (#159184)

Switch from guard_size_oblivious to guard_or_false if you encounter a DDE, this would then avoid folding this 3d bmm into a mm.

https://github.com/pytorch/pytorch/blob/806d9e3fe70ec250a1fb3823841d16c61b7d1b02/torch/_decomp/decompositions.py#L4506-L4512

## DDE
```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4506, in matmul
    elif should_fold(tensor1, tensor2, is_out):
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4472, in should_fold
    if guard_size_oblivious(t1.numel() == 0):
torch.fx.experimental.symbolic_shapes.GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(12*((u0//2)), 0) (unhinted: Eq(12*((u0//2)), 0)).  (Size-like symbols: none)

Caused by: (_decomp/decompositions.py:4472 in should_fold)
```

```
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4506, in matmul
    elif should_fold(tensor1, tensor2, is_out):
  File "/data/users/colinpeppler/pytorch/torch/_decomp/decompositions.py", line 4483, in should_fold
    return all(
torch.fx.experimental.symbolic_shapes.GuardOnDataDependentSymNode: Could not guard on data-dependent expression Eq(3*((u0//2)), 3) (unhinted: Eq(3*((u0//2)), 3)).  (Size-like symbols: none)

Caused by: (_decomp/decompositions.py:4483 in should_fold)
```

Pull Request resolved: #159184
Approved by: https://github.com/ezyang
ghstack dependencies: #158894
@github-actions github-actions bot deleted the gh/ColinPeppler/77/head branch August 26, 2025 02:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants