From b75662b900edeffea088a7adbcfa43b779f5ab4c Mon Sep 17 00:00:00 2001 From: James Nye Date: Mon, 30 Mar 2026 20:23:24 -0700 Subject: [PATCH] feat: MSVC auto-detection + C compiler check before torch.compile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit torch.compile needs a C compiler (cl.exe on Windows, gcc on Linux). On Windows, Visual Studio Build Tools installs cl.exe but doesn't add it to PATH — users get a cryptic compilation failure and fall back to eager mode (~30% slower) without knowing why. - Auto-detect MSVC in standard Visual Studio install locations - Check for C compiler before attempting compile - Show actionable message with install link if missing - Skip reasons are logged clearly instead of generic "compilation failed" --- CorridorKeyModule/inference_engine.py | 54 ++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/CorridorKeyModule/inference_engine.py b/CorridorKeyModule/inference_engine.py index 476ebffa..d0b98a11 100755 --- a/CorridorKeyModule/inference_engine.py +++ b/CorridorKeyModule/inference_engine.py @@ -24,6 +24,31 @@ logger = logging.getLogger(__name__) +def _try_activate_msvc() -> None: + """Find and activate MSVC (cl.exe) on Windows if installed but not in PATH. + + Searches common Visual Studio install locations for the latest cl.exe + and adds its directory to PATH. + """ + import glob + + patterns = [ + r"C:\Program Files\Microsoft Visual Studio\2022\*\VC\Tools\MSVC\*\bin\Hostx64\x64\cl.exe", + r"C:\Program Files (x86)\Microsoft Visual Studio\2022\*\VC\Tools\MSVC\*\bin\Hostx64\x64\cl.exe", + r"C:\Program Files\Microsoft Visual Studio\2019\*\VC\Tools\MSVC\*\bin\Hostx64\x64\cl.exe", + ] + + for pattern in patterns: + matches = sorted(glob.glob(pattern), reverse=True) # newest version first + if matches: + cl_dir = os.path.dirname(matches[0]) + os.environ["PATH"] = cl_dir + os.pathsep + os.environ.get("PATH", "") + logger.info("Auto-detected MSVC: %s", matches[0]) + return + + logger.debug("MSVC not found in standard locations") + + class CorridorKeyEngine: def __init__( self, @@ -58,12 +83,29 @@ def __init__( self._is_rocm = hasattr(torch.version, "hip") and torch.version.hip self.model = self._load_model() - # torch.compile is tested on CUDA (Windows + Linux) and ROCm (Linux). - # ROCm on Windows hangs during Triton kernel compilation — skip it. - # CORRIDORKEY_SKIP_COMPILE=1 forces eager mode (useful for testing). - skip_compile = (self._is_rocm and sys.platform == "win32") or os.environ.get("CORRIDORKEY_SKIP_COMPILE") == "1" - if skip_compile: - logger.info("Skipping torch.compile (eager mode)") + # torch.compile needs: cl.exe (Windows), gcc (Linux), and Triton. + # Check prerequisites and skip with a helpful message if missing. + import shutil + + # Auto-detect MSVC on Windows — it's installed but not in PATH by default + if sys.platform == "win32" and not shutil.which("cl"): + _try_activate_msvc() + + skip_reason = None + if self._is_rocm and sys.platform == "win32": + skip_reason = "ROCm on Windows — Triton compilation hangs" + elif os.environ.get("CORRIDORKEY_SKIP_COMPILE") == "1": + skip_reason = "CORRIDORKEY_SKIP_COMPILE=1" + elif sys.platform == "win32" and not shutil.which("cl"): + skip_reason = ( + "MSVC (cl.exe) not found. Install Visual Studio Build Tools " + "for ~30% faster inference: https://visualstudio.microsoft.com/visual-cpp-build-tools/" + ) + elif sys.platform == "linux" and not shutil.which("gcc") and not shutil.which("cc"): + skip_reason = "no C compiler found — install gcc for faster inference" + + if skip_reason: + logger.info("Skipping torch.compile (%s)", skip_reason) elif sys.platform == "linux" or sys.platform == "win32": self._compile()