pytorch - 💡(How to fix) Fix [inductor] Upsample(mode='area') fails under torch.compile(dynamic=True) — "cannot determine truth value of Relational" in _adaptive_avg_pool2d lowering

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

torch._inductor.exc.InductorError: LoweringException: TypeError: cannot determine truth value of Relational: (((2TruncToInt(2.0ToFloat(s69)) + 13)//(TruncToInt(2.0ToFloat( s69)))))(((2TruncToInt(2.0ToFloat(s87)) + 17)//(TruncToInt(2.0ToFloat(s87))))) > 25 target: aten._adaptive_avg_pool2d.default args[0]: TensorBox(StorageBox( InputBuffer(name='arg3_1', layout=FixedLayout('cpu', torch.float32, size=[1, s50, s69, s87], stride=[s50s69s87, s69s87, s87, 1])) )) args[1]: [TruncToInt(2.0ToFloat(s69)), TruncToInt(2.0ToFloat(s87))]

File "torch/_inductor/lowering.py", line 5831, in _adaptive_avg_pool2d if window_size > 25: ^^^^^^^^^^^^^^^^ File "sympy/core/relational.py", line 519, in bool raise TypeError(...)

Root Cause

In torch/_inductor/lowering.py:5831 , _adaptive_avg_pool2d lowering uses a static Python if to choose between kernel implementations:

if window_size > 25:
    # one kernel path
else:
    # another kernel path

Upsample(mode='area') decomposes to aten._adaptive_avg_pool2d . When dynamic=True , window_size is a symbolic expression (SymInt / SymPy object), and window_size > 25 returns a Relational object instead of bool — causing SymPy to refuse evaluation.

Fix Action

Fix / Workaround

Possible fix

  1. Guard on concrete values: insert torch._check(window_size > 25) prior to the static if
  2. Use torch._sympy.definitely_true() / torch._sympy.could_be_true() to branch with symbolic awareness
  3. Emit a conditional kernel dispatch that resolves at runtime

Code Example

import torch
import torch.nn as nn

x = torch.randn(1, 3, 15, 19)
m = nn.Upsample(scale_factor=2, mode='area')
m = torch.compile(m, dynamic=True)
m(x)    #crash here!

---

torch._inductor.exc.InductorError: LoweringException: TypeError: cannot determine truth 
value of Relational: (((2*TruncToInt(2.0*ToFloat(s69)) + 13)//(TruncToInt(2.0*ToFloat(
s69)))))*(((2*TruncToInt(2.0*ToFloat(s87)) + 17)//(TruncToInt(2.0*ToFloat(s87))))) > 25
  target: aten._adaptive_avg_pool2d.default
  args[0]: TensorBox(StorageBox(
    InputBuffer(name='arg3_1', layout=FixedLayout('cpu', torch.float32, size=[1, s50, s69, s87],
    stride=[s50*s69*s87, s69*s87, s87, 1]))
  ))
  args[1]: [TruncToInt(2.0*ToFloat(s69)), TruncToInt(2.0*ToFloat(s87))]

  File "torch/_inductor/lowering.py", line 5831, in _adaptive_avg_pool2d
    if window_size > 25:
       ^^^^^^^^^^^^^^^^
  File "sympy/core/relational.py", line 519, in __bool__
    raise TypeError(...)

---

if window_size > 25:
    # one kernel path
else:
    # another kernel path

---

PyTorch version: 2.13.0.dev20260521+cu126
OS: Linux (Ubuntu 22.04)
Python: 3.12
CUDA: 12.6
RAW_BUFFERClick to expand / collapse

🐛 Describe the bug

nn.Upsample(scale_factor=2, mode='area') (which decomposes to aten._adaptive_avg_pool2d ) crashes under torch.compile(dynamic=True) . Inductor's _adaptive_avg_pool2d lowering contains a static if window_size > 25: branch that cannot be resolved when window_size is a symbolic expression under dynamic=True .

Eager mode works correctly.

Minimal repro

import torch
import torch.nn as nn

x = torch.randn(1, 3, 15, 19)
m = nn.Upsample(scale_factor=2, mode='area')
m = torch.compile(m, dynamic=True)
m(x)    #crash here!

Error logs

torch._inductor.exc.InductorError: LoweringException: TypeError: cannot determine truth 
value of Relational: (((2*TruncToInt(2.0*ToFloat(s69)) + 13)//(TruncToInt(2.0*ToFloat(
s69)))))*(((2*TruncToInt(2.0*ToFloat(s87)) + 17)//(TruncToInt(2.0*ToFloat(s87))))) > 25
  target: aten._adaptive_avg_pool2d.default
  args[0]: TensorBox(StorageBox(
    InputBuffer(name='arg3_1', layout=FixedLayout('cpu', torch.float32, size=[1, s50, s69, s87],
    stride=[s50*s69*s87, s69*s87, s87, 1]))
  ))
  args[1]: [TruncToInt(2.0*ToFloat(s69)), TruncToInt(2.0*ToFloat(s87))]

  File "torch/_inductor/lowering.py", line 5831, in _adaptive_avg_pool2d
    if window_size > 25:
       ^^^^^^^^^^^^^^^^
  File "sympy/core/relational.py", line 519, in __bool__
    raise TypeError(...)

Root cause

In torch/_inductor/lowering.py:5831 , _adaptive_avg_pool2d lowering uses a static Python if to choose between kernel implementations:

if window_size > 25:
    # one kernel path
else:
    # another kernel path

Upsample(mode='area') decomposes to aten._adaptive_avg_pool2d . When dynamic=True , window_size is a symbolic expression (SymInt / SymPy object), and window_size > 25 returns a Relational object instead of bool — causing SymPy to refuse evaluation.

Possible fix

  1. Guard on concrete values: insert torch._check(window_size > 25) prior to the static if
  2. Use torch._sympy.definitely_true() / torch._sympy.could_be_true() to branch with symbolic awareness
  3. Emit a conditional kernel dispatch that resolves at runtime

Versions

PyTorch version: 2.13.0.dev20260521+cu126
OS: Linux (Ubuntu 22.04)
Python: 3.12
CUDA: 12.6

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

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING