From 41e65c1eed3c0cdd956267da638987d07f7f05e1 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Fri, 11 Sep 2026 16:16:03 +0000 Subject: [PATCH] fix: repair four pre-existing main CI failures (#3135) Four independent failures on main block all open pull requests. macos-metal-mlx: SpeechEngine explicitly defaulted its copy and move special member functions, but a std::mutex member makes them implicitly deleted. Clang promoted -Wdefaulted-function-deleted to an error under -Werror. Changed all four to = delete. sanitize-cpu address: the elementwise GEMM scalar fallback dereferenced unaligned uint16_t pointers in ElemA::Cvt and F16ToF32 at 11 call sites across four files. Wrapped each dereference with vt::LoadUnaligned for a safe scalar load. sanitize-cpu thread: the gemma4_moe FP8-native branch at line 1637 matched on CPU, called EnsureGemma4Fp8NativeOnDevice which returns false on every non-ROCm build, then had no fallback. The output buffer y was never written. Under TSan the allocator zero-fills memory, exposing the use of uninitialized memory as all-zeros output. Added an else clause that falls back to the same host computation path the adjacent branch uses. windows-msvc: host_available_memory_bytes passed the glibc-only "e" (close-on-exec) flag to fopen. MSVC UCRT treats unknown mode flags as an invalid parameter and calls __fastfail, killing the process with 0xC0000409 before fopen returns. Changed the mode to "r" so fopen returns nullptr on Windows where /proc/meminfo does not exist, and the existing nullptr guard returns 0 as callers expect. The fopen fix exposed a latent second issue: the post-build CRT audit calls dumpbin directly, but dumpbin is not on PATH on windows-2022 runners (the VS cmake generator finds cl.exe internally without exporting the toolchain). Added a vswhere lookup that prepends the MSVC bin directory to PATH before the CRT audit runs. The vswhere lookup alone was not sufficient: dumpbin calls used 2>&1 to merge stderr into stdout, but under $ErrorActionPreference = "Stop" (line 13) PowerShell 7 wraps native command stderr as ErrorRecord objects and promotes them to terminating errors, swallowing dumpbin's stdout and leaving the directive output empty. Removed 2>&1 from all dumpbin and cl call sites, added /nologo to suppress the banner, and added a dumpbin availability check after the vswhere block. The cl banner call temporarily relaxes ErrorActionPreference to Continue since cl writes its banner to stderr. Closes #3135 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:regolo-glm5.2 [maki] --- include/vllm/multimodal/speech_engine.h | 8 ++--- scripts/build-windows-release.ps1 | 35 ++++++++++++++++--- src/vllm/model_executor/models/gemma4_moe.cpp | 9 +++++ src/vllm/v1/core/kv_cache_utils.cpp | 2 +- src/vt/cpu/cpu_matmul_elem.cpp | 10 +++--- src/vt/cpu/cpu_matmul_elem_avx2.cpp | 5 +-- src/vt/cpu/cpu_matmul_elem_avx512.cpp | 5 +-- src/vt/cpu/cpu_matmul_elem_f16c.cpp | 5 +-- 8 files changed, 59 insertions(+), 20 deletions(-) diff --git a/include/vllm/multimodal/speech_engine.h b/include/vllm/multimodal/speech_engine.h index c3ee44b5c4..6a4b2bf139 100644 --- a/include/vllm/multimodal/speech_engine.h +++ b/include/vllm/multimodal/speech_engine.h @@ -201,10 +201,10 @@ class SpeechEngine { // is held through a `unique_ptr` or a `shared_ptr` everywhere in this tree, and // a future copy would be a second engine sharing one lock's worth of nothing. // A compile error at the seam is the right place to learn that. - SpeechEngine(const SpeechEngine&) = default; - SpeechEngine& operator=(const SpeechEngine&) = default; - SpeechEngine(SpeechEngine&&) = default; - SpeechEngine& operator=(SpeechEngine&&) = default; + SpeechEngine(const SpeechEngine&) = delete; + SpeechEngine& operator=(const SpeechEngine&) = delete; + SpeechEngine(SpeechEngine&&) = delete; + SpeechEngine& operator=(SpeechEngine&&) = delete; private: std::mutex synthesize_mutex_; diff --git a/scripts/build-windows-release.ps1 b/scripts/build-windows-release.ps1 index 7a2c49cf80..73e7a16685 100644 --- a/scripts/build-windows-release.ps1 +++ b/scripts/build-windows-release.ps1 @@ -623,7 +623,7 @@ function Invoke-CrtAudit { [Parameter(Mandatory)][string]$Server, [scriptblock]$DumpbinRunner = { param([string]$Mode, [string]$Path) - $output = & dumpbin $Mode $Path 2>&1 + $output = & dumpbin /nologo $Mode $Path if ($LASTEXITCODE -ne 0) { throw "dumpbin $Mode failed for $Path with status $LASTEXITCODE" } @@ -749,6 +749,30 @@ foreach ($name in @("SOURCE_SHA", "VERSION", "EVIDENCE_URL", "SOURCE_DATE_EPOCH" } } +# The Visual Studio cmake generator finds cl.exe internally, but dumpbin +# is called directly by the CRT audit (line 845) and the PE inspection +# (line 935). It is not on PATH by default on windows-2022 runners, so +# locate it via vswhere and prepend its directory. +$vswhere = Join-Path ${env:ProgramFiles(x86)} "Microsoft Visual Studio\Installer\vswhere.exe" +if (Test-Path $vswhere) { + $vsInstall = & $vswhere -latest -property installationPath + if ($vsInstall) { + $msvcRoot = Join-Path $vsInstall "VC\Tools\MSVC" + if (Test-Path $msvcRoot) { + $dumpbinDir = Get-ChildItem -Path $msvcRoot -Directory | + Sort-Object Name -Descending | Select-Object -First 1 | + ForEach-Object { Join-Path $_.FullName "bin\Hostx64\x64" } + if ($dumpbinDir -and (Test-Path (Join-Path $dumpbinDir "dumpbin.exe"))) { + $env:PATH = "$dumpbinDir;$env:PATH" + } + } + } +} + +if (-not (Get-Command dumpbin -ErrorAction SilentlyContinue)) { + throw "dumpbin.exe not found on PATH; CRT audit and PE inspection cannot run" +} + if (-not (Test-Path (Join-Path $SmokeModel "config.json"))) { throw "Windows runtime smoke model is incomplete: $SmokeModel" } @@ -932,11 +956,11 @@ $absent = @{ } } | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $tierReport -Encoding utf8NoBOM -$headerOutput = @(& dumpbin /nologo /headers $server 2>&1) +$headerOutput = @(& dumpbin /nologo /headers $server) if ($LASTEXITCODE -ne 0) { throw "dumpbin /headers failed" } -$dependentOutput = @(& dumpbin /nologo /dependents $server 2>&1) +$dependentOutput = @(& dumpbin /nologo /dependents $server) if ($LASTEXITCODE -ne 0) { throw "dumpbin /dependents failed" } -$rawOutput = @(& dumpbin /nologo /rawdata $server 2>&1) +$rawOutput = @(& dumpbin /nologo /rawdata $server) if ($LASTEXITCODE -ne 0) { throw "dumpbin /rawdata failed" } $machine = if (($headerOutput -join "`n") -match '(?im)^\s*(8664)\s+machine') { $Matches[1] } else { "" } $imports = @( @@ -954,7 +978,10 @@ $debugPaths = @( imports = $imports; debug_paths = $debugPaths } | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $peReport -Encoding utf8NoBOM +$savedEAP = $ErrorActionPreference +$ErrorActionPreference = 'Continue' $compiler = (& cl 2>&1 | Select-Object -First 1) -join "" +$ErrorActionPreference = $savedEAP $toolsetVersion = if ($env:VCToolsVersion) { $env:VCToolsVersion.TrimEnd('\') } else { throw "VCToolsVersion is required" } $ucrtVersion = if ($env:UCRTVersion) { $env:UCRTVersion.TrimEnd('\') } else { throw "UCRTVersion is required" } $abiVersion = ($toolsetVersion -split '\.')[0..1] -join '.' diff --git a/src/vllm/model_executor/models/gemma4_moe.cpp b/src/vllm/model_executor/models/gemma4_moe.cpp index 221e571ee6..1b27944acc 100644 --- a/src/vllm/model_executor/models/gemma4_moe.cpp +++ b/src/vllm/model_executor/models/gemma4_moe.cpp @@ -1640,6 +1640,15 @@ Gemma4MoeScratch RunGemma4Moe(vt::Queue& q, const Gemma4MoeLayerWeights& moe, ExpertGeGLUFp8Native(d, ysum, xin.t(), fex.dev_fp8_gu, fex.dev_s_gu, fex.dev_fp8_dn, fex.dev_s_dn, I, H, esc, ww, beta); fused_mix = true; + } else { + EnsureGemma4Fp8ExpertCached(fex, I, H); + if (!fex.cached_gu.empty() && !fex.cached_dn.empty()) { + ExpertGeGLUHost(d, y, xin.t(), fex.cached_gu.data(), fex.cached_dn.data(), I, H, esc, + &fex); + } else { + DequantGemma4Fp8ExpertToBf16Ephemeral(fex, I, H, gu_tmp.data(), dn_tmp.data()); + ExpertGeGLUHost(d, y, xin.t(), gu_tmp.data(), dn_tmp.data(), I, H, esc, &fex); + } } } else if (need_peer_sc && gu_sc && dn_sc) { if (PeerCopyGemma4ExpertSlice(ex.dev_id, ex.gate_up_dev, ex.down_dev, e, I, H, diff --git a/src/vllm/v1/core/kv_cache_utils.cpp b/src/vllm/v1/core/kv_cache_utils.cpp index d241ca84df..925825d1bb 100644 --- a/src/vllm/v1/core/kv_cache_utils.cpp +++ b/src/vllm/v1/core/kv_cache_utils.cpp @@ -951,7 +951,7 @@ int64_t host_available_memory_bytes() { // // Returns 0 when unreadable; callers treat 0 as "unknown" and do not refuse, // because an unknown budget must not become a false refusal. - std::FILE* f = std::fopen("/proc/meminfo", "re"); + std::FILE* f = std::fopen("/proc/meminfo", "r"); if (f == nullptr) return 0; char line[256]; int64_t kb = 0; diff --git a/src/vt/cpu/cpu_matmul_elem.cpp b/src/vt/cpu/cpu_matmul_elem.cpp index 26dec85764..8e9bced8a0 100644 --- a/src/vt/cpu/cpu_matmul_elem.cpp +++ b/src/vt/cpu/cpu_matmul_elem.cpp @@ -60,7 +60,7 @@ void Bt16Portable(const float* af, const void* bv, int64_t k, float* acc) { for (int64_t p = 0; p < k; ++p) { const float av = af[p]; for (int l = 0; l < kElemLanes; ++l) { - s[l] += av * E::Cvt(b[static_cast(l) * k + p]); + s[l] += av * E::Cvt(vt::LoadUnaligned(b + static_cast(l) * k + p)); } } for (int l = 0; l < kElemLanes; ++l) acc[l] = s[l]; @@ -183,7 +183,7 @@ void Bt16Neon(const float* af, const void* bv, int64_t k, float* acc) { for (; p < k; ++p) { // K tail, still in p order per lane const float av = af[p]; for (int l = 0; l < kElemLanes; ++l) { - acc[l] += av * E::Cvt(b[static_cast(l) * k + p]); + acc[l] += av * E::Cvt(vt::LoadUnaligned(b + static_cast(l) * k + p)); } } } @@ -229,7 +229,7 @@ void BtM4Neon(const float* af, int64_t a_stride, const void* bv, int64_t k, floa for (int r = 0; r < kMrNeon; ++r) { const float av = af[r * a_stride + pt]; for (int l = 0; l < kElemLanes; ++l) { - acc[r * kElemLanes + l] += av * E::Cvt(b[static_cast(l) * k + pt]); + acc[r * kElemLanes + l] += av * E::Cvt(vt::LoadUnaligned(b + static_cast(l) * k + pt)); } } } @@ -328,7 +328,7 @@ void Bt16Sse2(const float* af, const void* bv, int64_t k, float* acc) { for (; p < k; ++p) { const float av = af[p]; for (int l = 0; l < kElemLanes; ++l) { - acc[l] += av * E::Cvt(b[static_cast(l) * k + p]); + acc[l] += av * E::Cvt(vt::LoadUnaligned(b + static_cast(l) * k + p)); } } } @@ -374,7 +374,7 @@ void BtM2Sse2(const float* af, int64_t a_stride, const void* bv, int64_t k, floa for (int r = 0; r < kMrSse2; ++r) { const float av = af[r * a_stride + pt]; for (int l = 0; l < kElemLanes; ++l) { - acc[r * kElemLanes + l] += av * E::Cvt(b[static_cast(l) * k + pt]); + acc[r * kElemLanes + l] += av * E::Cvt(vt::LoadUnaligned(b + static_cast(l) * k + pt)); } } } diff --git a/src/vt/cpu/cpu_matmul_elem_avx2.cpp b/src/vt/cpu/cpu_matmul_elem_avx2.cpp index 0e7a770708..f79397e0e8 100644 --- a/src/vt/cpu/cpu_matmul_elem_avx2.cpp +++ b/src/vt/cpu/cpu_matmul_elem_avx2.cpp @@ -34,6 +34,7 @@ #include #include "vt/dtype.h" +#include "vt/unaligned.h" #include "cpu_matmul_elem.h" namespace vt::cpu { @@ -154,7 +155,7 @@ void Bt16Avx2(const float* af, const void* bv, int64_t k, float* acc) { for (; p < k; ++p) { const float av = af[p]; for (int l = 0; l < kElemLanes; ++l) { - acc[l] += av * ElemA::Cvt(b[static_cast(l) * k + p]); + acc[l] += av * ElemA::Cvt(vt::LoadUnaligned::T>(b + static_cast(l) * k + p)); } } } @@ -228,7 +229,7 @@ void BtM4Avx2(const float* af, int64_t a_stride, const void* bv, int64_t k, floa const float av = af[r * a_stride + p]; for (int l = 0; l < kElemLanes; ++l) { acc[r * kElemLanes + l] += - av * ElemA::Cvt(b[static_cast(l) * k + p]); + av * ElemA::Cvt(vt::LoadUnaligned::T>(b + static_cast(l) * k + p)); } } } diff --git a/src/vt/cpu/cpu_matmul_elem_avx512.cpp b/src/vt/cpu/cpu_matmul_elem_avx512.cpp index 8f63229e27..7451e6fd17 100644 --- a/src/vt/cpu/cpu_matmul_elem_avx512.cpp +++ b/src/vt/cpu/cpu_matmul_elem_avx512.cpp @@ -20,6 +20,7 @@ #include #include "vt/dtype.h" +#include "vt/unaligned.h" #include "cpu_matmul_elem.h" namespace vt::cpu { @@ -118,7 +119,7 @@ void Bt16Avx512(const float* af, const void* bv, int64_t k, float* acc) { for (; p < k; ++p) { const float av = af[p]; for (int l = 0; l < kElemLanes; ++l) { - acc[l] += av * ElemZ::Cvt(b[static_cast(l) * k + p]); + acc[l] += av * ElemZ::Cvt(vt::LoadUnaligned::T>(b + static_cast(l) * k + p)); } } } @@ -174,7 +175,7 @@ void BtM6Avx512(const float* af, int64_t a_stride, const void* bv, int64_t k, fl for (int r0 = 0; r0 < kMrAvx512; ++r0) { const float av = af[r0 * a_stride + p]; for (int l = 0; l < kElemLanes; ++l) { - acc[r0 * kElemLanes + l] += av * ElemZ::Cvt(b[static_cast(l) * k + p]); + acc[r0 * kElemLanes + l] += av * ElemZ::Cvt(vt::LoadUnaligned::T>(b + static_cast(l) * k + p)); } } } diff --git a/src/vt/cpu/cpu_matmul_elem_f16c.cpp b/src/vt/cpu/cpu_matmul_elem_f16c.cpp index cac6e1ba2d..2fc627b415 100644 --- a/src/vt/cpu/cpu_matmul_elem_f16c.cpp +++ b/src/vt/cpu/cpu_matmul_elem_f16c.cpp @@ -1,6 +1,7 @@ #include "vt/cpu/cpu_matmul_elem_f16c.h" #include "vt/quant.h" +#include "vt/unaligned.h" #include @@ -49,7 +50,7 @@ void BtM2F16c(const float* af, int64_t a_stride, const void* bv, int64_t k, const float av = af[r * a_stride + pt]; for (int lane = 0; lane < kElemLanes; ++lane) { acc[r * kElemLanes + lane] += - av * F16ToF32(b[static_cast(lane) * k + pt]); + av * F16ToF32(vt::LoadUnaligned(b + static_cast(lane) * k + pt)); } } } @@ -81,7 +82,7 @@ void Bt16F16c(const float* af, const void* bv, int64_t k, float* acc) { for (; p < k; ++p) { const float av = af[p]; for (int lane = 0; lane < kElemLanes; ++lane) { - acc[lane] += av * F16ToF32(b[static_cast(lane) * k + p]); + acc[lane] += av * F16ToF32(vt::LoadUnaligned(b + static_cast(lane) * k + p)); } } }