FX codegen used complex.repr when rendering complex constants into generated Python source. CPython can print zero-component values such as (-0-1e-28j), -1e-28j, or (1-0j), and parsing that source can flip the sign of a zero component. Dynamo exposes this when it traces a tensor constant containing -1e-28j through FX: the generated GraphModule reconstructs a value with the wrong signed zero, changing tensor repr and the sign of the zero imaginary result from cos().
Render complex constants with a zero real or imaginary component as complex(real, imag) through the existing recursive argument printer. Float repr preserves -0.0, so those generated constants round-trip signed zero components. Nonzero complex constants keep the existing repr() path to avoid changing the common codegen case.
Fixes #153852
Generated by my agent
Benchmark Results:
-
FX GraphModule construction with 1000 zero-component complex constants, 80 iterations x 7 repeats, median: main 3.55 ms/graph; this diff 6.77 ms/graph. This is the affected correctness path that now emits complex(real, imag) to preserve signed zero.
-
FX GraphModule construction with 1000 nonzero complex constants, same command shape, median: main 4.29 ms/graph; this diff 3.90 ms/graph. Nonzero constants remain on the existing repr() path; the difference is measurement noise.
Test Plan:
-
python test/dynamo/test_repros.py ReproTests.test_compile_complex_tensor_constant_signed_zero
-
python test/test_fx.py TestFX.test_complex_constant_codegen_preserves_signed_zero (direct run blocked locally before target test by unrelated torchvision::nms registration failure)
-
targeted TestFX.test_complex_constant_codegen_preserves_signed_zero via a torchvision import stub
-
lintrunner -a
-
git diff --check
Pull Request resolved: #185550
Approved by: https://github.com/desertfire
SOCIAL SHARE CARD GENERATOR