Found by the operator gate on #677. That PR fixed the POSIX stat defect (#664) and the Windows job got further — then hit this. Two independent Windows defects were stacked, both from the LTX-2.5 lane, and the second was invisible until the first was removed.
The failure
windows-msvc-cpu on PR #677, step "Build and execute the native Windows CPU focused gate", after 17m52s:
src\vllm\model_executor\models\ltx2.cpp(72,58): error C2065: 'M_PI': undeclared identifier
src\vllm\model_executor\models\ltx2.cpp(72,15): error C2737: 'kBeta': const object must be initialized
src\vllm\model_executor\models\ltx2.cpp(557,69): error C2065: 'M_PI': undeclared identifier
src\vllm\model_executor\models\ltx2.cpp(572,76): error C2065: 'M_PI': undeclared identifier
M_PI is a POSIX extension, not standard C++. MSVC's <cmath> only defines it when _USE_MATH_DEFINES is defined before the include.
Scope — three files, all in this lane, and ltx2.cpp only hides the rest
git grep -l M_PI origin/main -- src include returns exactly three, all LTX-2.5:
src/vllm/model_executor/models/ltx2.cpp — :72 std::sqrt(2.0 / M_PI) (the gelu-tanh constant), :557, :572 (M_PI / 2.0, the schedule)
src/vllm/model_executor/models/ltx2_audio_vae.cpp
src/vllm/model_executor/models/ltx2_video_vae.cpp
The job reports only ltx2.cpp because the build stops there. Fixing that file alone will move the error to the next TU. Re-derive the list at HEAD before acting — anchors in this tree go stale within a single PR — and use a positive control in the grep rather than trusting a null result.
Why the checker did not catch it
scripts/check-windows-portability.py is a source-pattern gate. It caught the unguarded <sys/stat.h> / ::stat shapes because those are greppable. M_PI is a compile error on one toolchain, not a pattern, so nothing static could have found it — only a native MSVC build. That is worth recording: the checker's green is not a claim that the tree builds on Windows.
It also compounds #584 — windows-msvc-* are skipped on main pushes, so main has no baseline and both defects landed unseen.
Preferred fix
Not a #define _USE_MATH_DEFINES. That is order-dependent (it must precede every <cmath>, including transitive ones) and it re-declares a POSIX extension rather than removing the dependency. Prefer a single portable constant — std::numbers::pi is available at the project's C++20 level (CMakeLists.txt:35 sets CMAKE_CXX_STANDARD 20), or one named constexpr in a shared header if a std::numbers include is unwelcome. One definition, three call sites, no macro ordering.
Whatever is chosen: the change must be value-identical. M_PI and std::numbers::pi_v<double> are both the nearest double to pi, so goldens should not move — assert that rather than assume it, and say so in the PR.
Gate
A green check-windows-portability.py is not sufficient evidence for this row; only the native windows-msvc-cpu / windows-msvc-vulkan jobs are. Note the runner pool is currently saturated (34 runs queued repo-wide), and a cancelled run prints as fail in gh pr checks without being one — read the job conclusion from the API.
Related: #664, #677 (must land first — this defect is only reachable once it does), #584, #680.
Found by the operator gate on #677. That PR fixed the POSIX
statdefect (#664) and the Windows job got further — then hit this. Two independent Windows defects were stacked, both from the LTX-2.5 lane, and the second was invisible until the first was removed.The failure
windows-msvc-cpuon PR #677, step "Build and execute the native Windows CPU focused gate", after 17m52s:M_PIis a POSIX extension, not standard C++. MSVC's<cmath>only defines it when_USE_MATH_DEFINESis defined before the include.Scope — three files, all in this lane, and
ltx2.cpponly hides the restgit grep -l M_PI origin/main -- src includereturns exactly three, all LTX-2.5:src/vllm/model_executor/models/ltx2.cpp—:72std::sqrt(2.0 / M_PI)(the gelu-tanh constant),:557,:572(M_PI / 2.0, the schedule)src/vllm/model_executor/models/ltx2_audio_vae.cppsrc/vllm/model_executor/models/ltx2_video_vae.cppThe job reports only
ltx2.cppbecause the build stops there. Fixing that file alone will move the error to the next TU. Re-derive the list at HEAD before acting — anchors in this tree go stale within a single PR — and use a positive control in the grep rather than trusting a null result.Why the checker did not catch it
scripts/check-windows-portability.pyis a source-pattern gate. It caught the unguarded<sys/stat.h>/::statshapes because those are greppable.M_PIis a compile error on one toolchain, not a pattern, so nothing static could have found it — only a native MSVC build. That is worth recording: the checker's green is not a claim that the tree builds on Windows.It also compounds #584 —
windows-msvc-*are skipped onmainpushes, somainhas no baseline and both defects landed unseen.Preferred fix
Not a
#define _USE_MATH_DEFINES. That is order-dependent (it must precede every<cmath>, including transitive ones) and it re-declares a POSIX extension rather than removing the dependency. Prefer a single portable constant —std::numbers::piis available at the project's C++20 level (CMakeLists.txt:35setsCMAKE_CXX_STANDARD 20), or one namedconstexprin a shared header if astd::numbersinclude is unwelcome. One definition, three call sites, no macro ordering.Whatever is chosen: the change must be value-identical.
M_PIandstd::numbers::pi_v<double>are both the nearestdoubleto pi, so goldens should not move — assert that rather than assume it, and say so in the PR.Gate
A green
check-windows-portability.pyis not sufficient evidence for this row; only the nativewindows-msvc-cpu/windows-msvc-vulkanjobs are. Note the runner pool is currently saturated (34 runs queued repo-wide), and a cancelled run prints asfailingh pr checkswithout being one — read the job conclusion from the API.Related: #664, #677 (must land first — this defect is only reachable once it does), #584, #680.