Skip to content

Increase small fake tensor constant limit - #186263

Closed
jansel wants to merge 5 commits into
gh/jansel/1343/basefrom
gh/jansel/1343/head
Closed

jansel wants to merge 5 commits into
gh/jansel/1343/basefrom
gh/jansel/1343/head

Conversation

@jansel

@jansel jansel commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Stack from ghstack (oldest at bottom):

Fake tensor and proxy tensor tracing only kept tensor constants with one element. Shape tensors built from Python shape lists, such as torch.as_tensor([[64, 64], [32, 32]]), therefore lost their constant payload even though they are small. Later scalar uses of those values, including torch.linspace(..., steps=H), became data-dependent unbacked symbols and strict export failed with GuardOnDataDependentSymNode.

Raise the small tensor constant propagation limit from 1 to 8 in both fake tensor and proxy tensor tracing. This keeps common small shape tensors constant while preserving a conservative cap. I chose this root-cause change over adding linspace or slicing special cases because maintainers pointed at more aggressive constant propagation and the same lost constant payload affects multiple downstream scalar consumers.

Fixes #136642

Generated by my agent

Test Plan:

  • python test/export/test_export.py TestExport.test_strict_export_constant_props_small_shape_tensor
  • python test/test_fake_tensor.py FakeTensorConstHandling.test_fake_tensor_in_intlist_repro
  • python test/test_fake_tensor.py FakeTensorConstHandling
  • python - <<'PY' ... issue repro with torch.export.export(..., strict=True) ... PY
  • python - <<'PY' ... .item() variant of issue repro ... PY
  • git diff --check
  • lintrunner torch/_subclasses/fake_tensor.py torch/fx/experimental/proxy_tensor.py test/test_fake_tensor.py test/export/test_export.py

lintrunner -a was also run and failed on an unrelated CLANGTIDY include-cycle in torch/csrc/distributed/autograd/functions/recvrpc_backward.h.

Benchmark Results:
Synthetic FakeTensorMode benchmark, 1200 iterations creating a 4-element int64 tensor then add and multiply, 9 alternating reps with the limit toggled in-process. Old limit 1 median: 0.561588 s, 467.990 us/iter. New limit 8 median: 1.051484 s, 876.237 us/iter, 1.872x. This intentionally stresses the newly constant-propagated case; the change remains capped at tensors with at most 8 elements.

cc @voznesenskym @penguinwu @EikanWang @jgong5 @Guobing-Chen @XiaobingSuper @zhuhaozhe @blzheng @wenzhe-nrv @jiayisunx @kadeng @chauhang @amjames @jataylo @azahed98

[ghstack-poisoned]
@pytorch-bot

pytorch-bot Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

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

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

❗ 1 Active SEVs

There are 1 currently active SEVs. If your PR is affected, please view them below:

✅ You can merge normally! (5 Unrelated Failures)

As of commit 8fb6c8a with merge base 29dbb32 (image):

FLAKY - The following jobs failed but were likely due to flakiness present on trunk:

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.

@pytorch-bot pytorch-bot Bot added ciflow/inductor release notes: fx release notes category labels Jun 4, 2026
@jansel

jansel commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

@claude review these changes

@claude

claude Bot commented Jun 4, 2026 •

Copy link
Copy Markdown

Claude finished @jansel's task in 1m 37s —— View job


Reviewing PR #186263: Increase small fake tensor constant limit

  • Read the PR diff and changed files
  • Analyze the core logic changes
  • Review the test additions
  • Post review feedback

Review Summary

This is a clean, well-motivated fix. Raising CONSTANT_NUMEL_LIMIT from 1 to 8 is a minimal change that directly addresses the root cause of #136642 — shape tensors losing their constant payload and triggering GuardOnDataDependentSymNode in strict export.

Feedback

1. Duplicated constant — consider importing instead of syncing manually

CONSTANT_NUMEL_LIMIT is defined separately in both torch/_subclasses/fake_tensor.py:87 and torch/fx/experimental/proxy_tensor.py:125, with only a comment asking you to "keep this in sync." Since proxy_tensor.py already imports from torch._subclasses.fake_tensor (line 54), you could just add CONSTANT_NUMEL_LIMIT to that import list and eliminate the duplication:

from torch._subclasses.fake_tensor import (
    CONSTANT_NUMEL_LIMIT,
    FakeTensor,
    FakeTensorMode,
    ...
)

This avoids a future divergence if someone updates one but not the other. That said, if there's a deliberate reason for keeping them separate (e.g., historically different semantics or concern about coupling), the comment is acceptable — just flagging it as a potential maintenance hazard.

2. Performance regression acknowledged

The PR description documents a ~1.87x slowdown on a synthetic microbenchmark that specifically hammers the constant-propagation path. Since this only affects tensors with ≤8 elements being lifted as constants (not general tracing throughput), it seems acceptable. Good that this was measured and disclosed.

3. Test quality

  • The new export test (test_strict_export_constant_props_small_shape_tensor) directly reproduces the reported issue pattern — good end-to-end coverage.
  • test_aliased_const_write now uses CONSTANT_NUMEL_LIMIT + 1 instead of a hardcoded 4, making it resilient to future limit changes — nice.
  • test_fake_tensor_in_intlist_repro flipping from expecting an exception to expecting success clearly demonstrates the behavioral change.

4. Minor: no __all__ export needed?

The test at test/test_fake_tensor.py:1924 references torch._subclasses.fake_tensor.CONSTANT_NUMEL_LIMIT by its full module path. This works fine, just confirming it's intentionally private (no __all__ addition needed).

Verdict

Looks good overall. The only actionable suggestion is consolidating the duplicated constant (item 1 above). The rest is solid.


[ghstack-poisoned]
jansel added a commit that referenced this pull request Jun 7, 2026
Fake tensor and proxy tensor tracing only kept tensor constants with one element. Shape tensors built from Python shape lists, such as torch.as_tensor([[64, 64], [32, 32]]), therefore lost their constant payload even though they are small. Later scalar uses of those values, including torch.linspace(..., steps=H), became data-dependent unbacked symbols and strict export failed with GuardOnDataDependentSymNode.

Raise the small tensor constant propagation limit from 1 to 8 in both fake tensor and proxy tensor tracing. This keeps common small shape tensors constant while preserving a conservative cap. I chose this root-cause change over adding linspace or slicing special cases because maintainers pointed at more aggressive constant propagation and the same lost constant payload affects multiple downstream scalar consumers.

The higher limit also exposed two expected follow-ups: tests that intentionally need dynamic fake values now create non-constant inputs, and Dynamo recompilation-count expectations are updated for the improved constant propagation. To avoid a real distributed regression, runtime DeviceMesh coordinate computation is excluded from fake/proxy constant propagation so compile-on-one-rank graphs do not bake rank-local literals.

Fixes #136642

Generated by my agent

Test Plan:
- python test/export/test_export.py TestExport.test_strict_export_constant_props_small_shape_tensor
- python test/test_fake_tensor.py FakeTensorTest.test_sparse_spdiags_dynamic_nnz_bound
- python test/test_fake_tensor.py FakeTensorConstHandling
- python test/dynamo/test_repros.py ReproTests.test_convert_boxes_to_pooler_format
- python test/dynamo/test_dynamic_shapes.py DynamicShapesReproTests.test_convert_boxes_to_pooler_format_dynamic_shapes
- python test/distributed/tensor/test_compile_on_one_rank.py TestCompileOnOneRank.test_compiled_rowwise_embedding_graph_consistency
- git diff --check
- lintrunner -a

Benchmark Results:
Synthetic FakeTensorMode benchmark, 1200 iterations creating a 4-element int64 tensor then add and multiply, 9 alternating reps with the limit toggled in-process. Old limit 1 median: 0.561588 s, 467.990 us/iter. New limit 8 median: 1.051484 s, 876.237 us/iter, 1.872x. This intentionally stresses the newly constant-propagated case; the change remains capped at tensors with at most 8 elements.

ghstack-source-id: bc5dca5
Pull-Request: #186263
@jansel

jansel commented Jun 7, 2026

Copy link
Copy Markdown
Contributor Author

@claude review these changes

@jansel

jansel commented Jun 7, 2026

Copy link
Copy Markdown
Contributor Author

My agent says I fixed the CI regressions from the higher small-constant limit. The update keeps runtime DeviceMesh coordinate computation out of fake/proxy constant propagation so compile-on-one-rank graphs do not bake rank-local literals, updates the dynamic spdiags test to use non-constant offsets, updates the Dynamo frame-count expectations, and deduplicates CONSTANT_NUMEL_LIMIT through the fake_tensor import.

@claude

claude Bot commented Jun 7, 2026 •

Copy link
Copy Markdown

Claude finished @jansel's task in 1m 12s —— View job


Reviewing PR #186263: Increase small fake tensor constant limit

  • Read the PR diff and changed files
  • Analyze the core logic changes
  • Review the test additions
  • Post review feedback

Review Summary

This is a well-motivated fix addressing the root cause of #136642. The change from limit 1 → 8 is conservative and directly solves shape tensors (built via torch.as_tensor(...)) losing their constant payload, which cascaded into GuardOnDataDependentSymNode failures in strict export.

Feedback

1. Good: Consolidated CONSTANT_NUMEL_LIMIT (addresses previous review feedback)

The constant is now defined once in fake_tensor.py:87 and imported by proxy_tensor.py:55. This eliminates the previous duplication and sync hazard. Clean.

2. device_mesh exclusion: string-based matching is fragile

The exclusion at fake_tensor.py:2621-2623 and proxy_tensor.py:1332-1334 uses:

and not func.name().startswith(
    "device_mesh::_runtime_compute_coordinate_on_dim"
)

This works but has a couple of concerns:

  • Fragile to renames/new ops: If the device_mesh namespace adds more ops that shouldn't be constant-folded, each needs a new string check. A tag-based approach (e.g., a torch.Tag.no_constant_fold tag) would be more maintainable long-term.
  • Why this op specifically?: From reading torch/distributed/_ops/device_mesh.py, the op returns an unbacked SymInt (the per-rank mesh coordinate) — its result intentionally varies per rank, so constant-folding it during tracing would bake in a single rank's coordinate. The comment in _local_tensor/__init__.py:1327 confirms this. Adding a brief inline comment explaining why this exclusion exists (e.g., "result varies per rank, must not be constant-folded") would help future readers.

3. Test changes in test_sparse_spdiags_dynamic_nnz_bound (test_fake_tensor.py:208-216)

The original test relied on torch.tensor([-1, -2]) being automatically treated as non-constant (because limit was 1 and numel is 2). Now with limit 8, it would be constant-folded, defeating the test's purpose of verifying dynamic nnz bounds. The fix — explicitly using from_real_tensor(..., make_constant=False) — is the correct approach: it makes the test's intent explicit rather than depending on an implicit size limit.

4. test_convert_boxes_to_pooler_format assertion changes (test_repros.py:1177-1182)

Frame count drops from 4 → 2 and op count changes. This is expected: with repeat_interleave's tensor argument now constant-folded (it's 4-element), dynamo can trace through without graph breaks. The comment at line 1174 even notes this was a known limitation. Good that this improves the compilation quality.

5. test_fake_tensor_in_intlist_repro flip from exception → success

Previously this test asserted that a DataDependentOutputException was raised (because torch.tensor([800, 1216]) had numel=2 > limit=1, so it lost its constant and list(max_size) triggered a data-dependent guard). Now it succeeds cleanly. This is the exact user-facing improvement this PR delivers. The added shape assertion is a good sanity check.

6. Performance note

The 1.87x microbenchmark regression is acceptable given:

  • It only applies to the constant-propagation hot path (tensors ≤8 elements)
  • Real workloads don't consist solely of constant tensor creation
  • The threshold is still very conservative (8 elements = 64 bytes for int64)

Verdict

Looks good. The only minor suggestion is adding a brief comment at the device_mesh exclusion explaining why (rank-dependent result, must not fold). Everything else is solid — tests are well-designed, the constant deduplication is clean, and the existing test updates correctly reflect the improved tracing behavior.


[ghstack-poisoned]
jansel added a commit that referenced this pull request Jun 9, 2026
Fake tensor and proxy tensor tracing only kept tensor constants with one element. Shape tensors built from Python shape lists, such as torch.as_tensor([[64, 64], [32, 32]]), therefore lost their constant payload even though they are small. Later scalar uses of those values, including torch.linspace(..., steps=H), became data-dependent unbacked symbols and strict export failed with GuardOnDataDependentSymNode.

Raise the small tensor constant propagation limit from 1 to 8 in both fake tensor and proxy tensor tracing. This keeps common small shape tensors constant while preserving a conservative cap. I chose this root-cause change over adding linspace or slicing special cases because maintainers pointed at more aggressive constant propagation and the same lost constant payload affects multiple downstream scalar consumers.

The higher limit also exposed expected follow-ups: tests that intentionally need dynamic fake values now create non-constant inputs, cache tests that specifically exercise dispatch-cache behavior clear the constant payload, and Dynamo recompilation-count expectations are updated for the improved constant propagation. To avoid a real distributed regression, runtime DeviceMesh coordinate computation is excluded from fake/proxy constant propagation so compile-on-one-rank graphs do not bake rank-local literals.

Fixes #136642

Generated by my agent

Test Plan:
- python test/export/test_export.py TestExport.test_strict_export_constant_props_small_shape_tensor
- python test/test_fake_tensor.py FakeTensorTest.test_sparse_spdiags_dynamic_nnz_bound
- python test/test_fake_tensor.py FakeTensorConstHandling
- python test/test_fake_tensor.py FakeTensorDispatchCache.test_cache_aten_index
- python test/test_fake_tensor.py FakeTensorDispatchCache
- python test/dynamo/test_repros.py ReproTests.test_convert_boxes_to_pooler_format
- python test/dynamo/test_dynamic_shapes.py DynamicShapesReproTests.test_convert_boxes_to_pooler_format_dynamic_shapes
- python test/distributed/tensor/test_compile_on_one_rank.py TestCompileOnOneRank.test_compiled_rowwise_embedding_graph_consistency
- git diff --check
- lintrunner test/test_fake_tensor.py torch/_subclasses/fake_tensor.py torch/fx/experimental/proxy_tensor.py
- lintrunner -a

Benchmark Results:
Synthetic FakeTensorMode benchmark, 1200 iterations creating a 4-element int64 tensor then add and multiply, 9 alternating reps with the limit toggled in-process. Old limit 1 median: 0.561588 s, 467.990 us/iter. New limit 8 median: 1.051484 s, 876.237 us/iter, 1.872x. This intentionally stresses the newly constant-propagated case; the change remains capped at tensors with at most 8 elements.

ghstack-source-id: 3151b0b
Pull-Request: #186263
@jansel

jansel commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

My agent says I fixed the new FakeTensorDispatchCache CI failures by making the cache-specific tests opt out of small-constant propagation explicitly. I also added the requested comments explaining that DeviceMesh coordinate ops must not be folded because their values are rank-dependent.

@jansel jansel added the agentic Created by an AI agent label Jun 9, 2026
@jansel
jansel marked this pull request as ready for review June 10, 2026 10:38
@jansel
jansel requested review from eellison, ezyang and laithsakka June 10, 2026 10:38
@jansel
jansel requested a review from aorenste as a code owner June 10, 2026 10:38
Comment thread torch/fx/experimental/proxy_tensor.py Resolved
[ghstack-poisoned]
jansel added a commit that referenced this pull request Jun 11, 2026
Fake tensor and proxy tensor tracing only kept tensor constants with one element. Shape tensors built from Python shape lists, such as torch.as_tensor([[64, 64], [32, 32]]), therefore lost their constant payload even though they are small. Later scalar uses of those values, including torch.linspace(..., steps=H), became data-dependent unbacked symbols and strict export failed with GuardOnDataDependentSymNode.

Raise the small tensor constant propagation limit from 1 to 8 in both fake tensor and proxy tensor tracing. This keeps common small shape tensors constant while preserving a conservative cap. I chose this root-cause change over adding linspace or slicing special cases because maintainers pointed at more aggressive constant propagation and the same lost constant payload affects multiple downstream scalar consumers.

The higher limit also exposed expected follow-ups: tests that intentionally need dynamic fake values now create non-constant inputs, cache tests that specifically exercise dispatch-cache behavior clear the constant payload, and Dynamo recompilation-count expectations are updated for the improved constant propagation. To avoid a real distributed regression, runtime DeviceMesh coordinate computation is tagged as nondeterministic_seeded so existing fake/proxy constant propagation gates do not bake rank-local literals into compile-on-one-rank graphs.

Fixes #136642

Generated by my agent

Test Plan:
- python test/export/test_export.py TestExport.test_strict_export_constant_props_small_shape_tensor
- python test/test_fake_tensor.py FakeTensorTest.test_sparse_spdiags_dynamic_nnz_bound
- python test/test_fake_tensor.py FakeTensorConstHandling
- python test/test_fake_tensor.py FakeTensorDispatchCache.test_cache_aten_index
- python test/test_fake_tensor.py FakeTensorDispatchCache
- python test/dynamo/test_repros.py ReproTests.test_convert_boxes_to_pooler_format
- python test/dynamo/test_dynamic_shapes.py DynamicShapesReproTests.test_convert_boxes_to_pooler_format_dynamic_shapes
- python test/distributed/tensor/test_compile_on_one_rank.py TestCompileOnOneRank.test_compiled_rowwise_embedding_graph_consistency
- python test/distributed/test_local_tensor.py TestLocalTensorWorld4.test_runtime_compute_coordinate_on_dim_per_rank_call_style_positional TestLocalTensorWorld4.test_runtime_compute_coordinate_on_dim_per_rank_call_style_kwargs
- git diff --check
- lintrunner test/test_fake_tensor.py torch/_subclasses/fake_tensor.py torch/fx/experimental/proxy_tensor.py
- lintrunner -a

Benchmark Results:
Synthetic FakeTensorMode benchmark, 1200 iterations creating a 4-element int64 tensor then add and multiply, 9 alternating reps with the limit toggled in-process. Old limit 1 median: 0.561588 s, 467.990 us/iter. New limit 8 median: 1.051484 s, 876.237 us/iter, 1.872x. This intentionally stresses the newly constant-propagated case; the change remains capped at tensors with at most 8 elements.

ghstack-source-id: 604ba81
Pull-Request: #186263
@pytorch-bot pytorch-bot Bot added the ciflow/torchtitan Run TorchTitan integration tests label Jun 11, 2026
[ghstack-poisoned]
jansel added a commit that referenced this pull request Jun 14, 2026
Fake tensor and proxy tensor tracing only kept tensor constants with one element. Shape tensors built from Python shape lists, such as torch.as_tensor([[64, 64], [32, 32]]), therefore lost their constant payload even though they are small. Later scalar uses of those values, including torch.linspace(..., steps=H), became data-dependent unbacked symbols and strict export failed with GuardOnDataDependentSymNode.

Raise the small tensor constant propagation limit from 1 to 8 in both fake tensor and proxy tensor tracing. This keeps common small shape tensors constant while preserving a conservative cap. I chose this root-cause change over adding linspace or slicing special cases because maintainers pointed at more aggressive constant propagation and the same lost constant payload affects multiple downstream scalar consumers.

The higher limit also exposed expected follow-ups: tests that intentionally need dynamic fake values now create non-constant inputs, cache tests that specifically exercise dispatch-cache behavior clear the constant payload, and Dynamo recompilation-count expectations are updated for the improved constant propagation. To avoid a real distributed regression, fake/proxy constant propagation now excludes runtime DeviceMesh coordinate computation so compile-on-one-rank graphs do not bake rank-local literals.

Fixes #136642

Generated by my agent

Test Plan:
- python test/export/test_export.py TestExport.test_strict_export_constant_props_small_shape_tensor
- python test/test_fake_tensor.py FakeTensorTest.test_sparse_spdiags_dynamic_nnz_bound
- python test/test_fake_tensor.py FakeTensorConstHandling
- python test/test_fake_tensor.py FakeTensorDispatchCache.test_cache_aten_index
- python test/test_fake_tensor.py FakeTensorDispatchCache
- python test/dynamo/test_repros.py ReproTests.test_convert_boxes_to_pooler_format
- python test/dynamo/test_dynamic_shapes.py DynamicShapesReproTests.test_convert_boxes_to_pooler_format_dynamic_shapes
- python test/distributed/tensor/test_compile_on_one_rank.py TestCompileOnOneRank.test_compiled_rowwise_embedding_graph_consistency
- python test/distributed/test_local_tensor.py TestLocalTensorWorld4.test_runtime_compute_coordinate_on_dim_per_rank_call_style_positional TestLocalTensorWorld4.test_runtime_compute_coordinate_on_dim_per_rank_call_style_kwargs
- git diff --check
- lintrunner test/test_fake_tensor.py torch/_subclasses/fake_tensor.py torch/fx/experimental/proxy_tensor.py
- lintrunner -a

Rebase Update Test Plan:
- git diff --check
- lintrunner torch/_subclasses/fake_tensor.py torch/fx/experimental/proxy_tensor.py torch/distributed/_ops/device_mesh.py test/distributed/test_local_tensor.py
- lintrunner -a
- attempted targeted Python tests and import sanity check, but Python import hung in this workspace before executing test code

Benchmark Results:
Synthetic FakeTensorMode benchmark, 1200 iterations creating a 4-element int64 tensor then add and multiply, 9 alternating reps with the limit toggled in-process. Old limit 1 median: 0.561588 s, 467.990 us/iter. New limit 8 median: 1.051484 s, 876.237 us/iter, 1.872x. This intentionally stresses the newly constant-propagated case; the change remains capped at tensors with at most 8 elements.

ghstack-source-id: b365b85
Pull-Request: #186263
@jansel

jansel commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

@claude review these changes

@jansel

jansel commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

My agent says I rebased the PR onto current main and replaced the DeviceMesh handling with a narrow fake/proxy constant-folding exclusion instead of tagging the op as random. The torchbench failures Dr. CI highlighted are model load dependency failures on the old CI run rather than failures in this patch, so the updated CI should reclassify after the new head runs.

@claude

claude Bot commented Jun 14, 2026 •

Copy link
Copy Markdown

Claude finished @jansel's task in 2m 25s —— View job


Review: Increase small fake tensor constant limit

  • Read the PR diff against origin/gh/jansel/1343/base
  • Analyze can_constant_fold_through_op and the device_mesh exclusion
  • Check the op tag registration vs. the described fix
  • Review test changes
  • Post feedback

Main finding: the described tag-based fix is not in the current HEAD

In your last review reply you said the device_mesh special case was moved onto operator metadata — that _runtime_compute_coordinate_on_dim is now registered with torch.Tag.nondeterministic_seeded and the fake/proxy paths rely on the existing tag-based guard "instead of matching the op name string."

The diff at HEAD doesn't reflect that. The string match is still there:

# torch/_subclasses/fake_tensor.py:92-99
def can_constant_fold_through_op(func: torch._ops.OpOverload) -> bool:
    if torch.Tag.nondeterministic_seeded in func.tags:
        return False
    # This op's result depends on the current rank, so folding one rank's value
    # into a graph compiled for other ranks is incorrect.
    if func.name() == "device_mesh::_runtime_compute_coordinate_on_dim":
        return False
    return True

And the op is still registered with only pt2_compliant_tag, not nondeterministic_seeded:

# torch/distributed/_ops/device_mesh.py:10-14
torch.library.define(
    "device_mesh::_runtime_compute_coordinate_on_dim",
    "(Tensor full_mesh, int index) -> SymInt",
    tags=torch.Tag.pt2_compliant_tag,
)

The LocalTensor assertion you mentioned ("the op carries the tag") also isn't present — _local_tensor/__init__.py:1331-1334 still keys off func.namespace == "device_mesh" and the .default identity, with no tag check. So eellison's concern (the string-name special case in proxy_tensor.py) is not yet addressed in what's pushed. Either the commit didn't make it onto this branch, or the agent's summary is ahead of the actual changes. Worth confirming what's on the branch before considering this resolved.

If you do go with the nondeterministic_seeded tag, weigh the side effects

nondeterministic_seeded isn't just an input to constant-folding — other passes branch on it, and a rank-dependent (but otherwise deterministic) op doesn't really fit the tag's meaning ("random... controlled by a Generator which, if reseeded would give you the same result", aten/src/ATen/native/tags.yaml:34). Notably:

  • torch/_inductor/fx_passes/post_grad.py:116-133 chains every nondeterministic_seeded node with control_deps to preserve program order. Tagging this op would pull it into that random-op ordering machinery.
  • torch/_library/utils.py:689 treats _nondeterministic_seeded ops specially for functionalization/impure-random handling.

These may be benign for this op, but they're real behavioral couplings beyond "skip constant folding." If the intent is purely "never constant-fold this," a dedicated tag (e.g. a data_dependent_output-style or a new non_foldable tag) communicates intent without dragging in random-op semantics. The current string-match, while ad hoc, at least has no such side effects — so this is a genuine tradeoff, not a clear win for the tag.

Test changes

  • test_sparse_spdiags_dynamic_nnz_bound and test_cache_aten_index: switching to from_real_tensor(..., make_constant=False) is the right way to make the "this input is dynamic" intent explicit rather than relying on the old numel > 1 implicit cutoff. Good.
  • test_aliased_const_write: using CONSTANT_NUMEL_LIMIT + 1 instead of a hardcoded 4 makes it robust to future limit changes. Good.
  • test_fake_tensor_in_intlist_repro: the flip from "asserts DataDependentOutputException" to "succeeds + shape assert" is exactly the user-facing improvement, and the added assertEqual(ref.shape, ...) is a nice concrete check.
  • FakeTensorDispatchCache tests (x.constant = None at test_fake_tensor.py:3251, 3283, 3290, 3297): this works, but it's inconsistent with the cleaner from_real_tensor(make_constant=False) you used elsewhere in the same file. Mutating .constant after construction reaches into FakeTensor internals; using from_real_tensor(make_constant=False) here too would keep the opt-out mechanism uniform across the test file. Minor.
  • test_repros.py frame/op-count change (4→2 frames): expected — the 4-element repeat_interleave tensor is now folded so dynamo traces through the former graph break. Op count rising (10→12 / 14→16) is consistent with fewer breaks folding more into each graph.
  • test_strict_export_constant_props_small_shape_tensor: good end-to-end repro of Linespace does not support SymInt step. (but int) #136642.

Other

  • Constant dedup via the fake_tensor import is clean — resolves the earlier sync-hazard feedback.
  • The ~1.87x microbenchmark regression is on the constant-fold hot path only (≤8 elements) and disclosed; acceptable.

Verdict

The core limit change and test updates are solid. The one thing blocking "done" is the device_mesh discrepancy: the tag-based fix described in your reply to eellison isn't in HEAD (still string-match + pt2_compliant_tag-only registration, no LocalTensor tag assertion). Please confirm the intended commit is actually on the branch — and if the plan is the nondeterministic_seeded tag, double-check the inductor/functionalization side effects above are acceptable for a rank-dependent (non-random) op.
· branch gh/jansel/1343/head

@jansel
jansel requested a review from eellison June 17, 2026 05:07
@jansel
jansel requested review from choijon5 and frgossen July 2, 2026 01:15
@jansel
jansel requested review from angelayi, anijain2305 and oulgen July 9, 2026 09:03
@jansel
jansel requested a review from zou3519 July 27, 2026 06:27
@jansel

jansel commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

My agent says this PR is being closed as part of a cleanup of open agentic PRs to focus review bandwidth on a smaller set; the linked issue remains open.

@jansel jansel closed this Aug 18, 2026
@github-actions
github-actions Bot deleted the gh/jansel/1343/head branch September 19, 2026 01:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic Created by an AI agent ciflow/inductor ciflow/torchtitan Run TorchTitan integration tests module: dynamo release notes: fx release notes category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants