Skip to content

Add JIT compiler support for Windows#3556

Open
dhiltgen wants to merge 2 commits into
ml-explore:mainfrom
dhiltgen:pr/jit-windows
Open

Add JIT compiler support for Windows#3556
dhiltgen wants to merge 2 commits into
ml-explore:mainfrom
dhiltgen:pr/jit-windows

Conversation

@dhiltgen
Copy link
Copy Markdown
Contributor

Proposed changes

Split out from #3019

Enable CPU mx.compile() on Windows by detecting and using clang-cl bundled with Visual Studio, or MSVC cl.exe, for JIT compilation.

Keep GPU compile availability independent from the CPU compiler probe so CPU+GPU builds do not disable GPU mx.compile() when a host C++ compiler is unavailable.

Changes:

  • Add clang-cl detection via vswhere and prefer a compiler matching the build toolchain
  • Add JitCompiler::available() to probe CPU JIT availability
  • Emit and load .dll JIT libraries on Windows
  • Support both MSVC and GCC/Clang preamble generation scripts, including optional SIMD flags
  • Use WIN32 shell detection and pass preamble SIMD flags through CMake
  • Define NOMINMAX/WIN32_LEAN_AND_MEAN on all WIN32 compilers

Checklist

Put an x in the boxes that apply.

  • I have read the CONTRIBUTING document
  • I have run pre-commit run --all-files to format my code / installed pre-commit prior to committing changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the necessary documentation (if needed)

Enable CPU mx.compile() on Windows by detecting and using clang-cl bundled with Visual Studio, or MSVC cl.exe, for JIT compilation.

Keep GPU compile availability independent from the CPU compiler probe so CPU+GPU builds do not disable GPU mx.compile() when a host C++ compiler is unavailable.

Changes:
- Add clang-cl detection via vswhere and prefer a compiler matching the build toolchain
- Add JitCompiler::available() to probe CPU JIT availability
- Emit and load .dll JIT libraries on Windows
- Support both MSVC and GCC/Clang preamble generation scripts, including optional SIMD flags
- Use WIN32 shell detection and pass preamble SIMD flags through CMake
- Define NOMINMAX/WIN32_LEAN_AND_MEAN on all WIN32 compilers
Comment thread mlx/backend/cpu/jit_compiler.cpp Outdated
"{0}\\VC\\Tools\\Llvm\\{1}\\bin\\clang-cl.exe", vs_path, arch);
{
std::ifstream f(clang_cl_path);
if (f.good()) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We usually use std::filesystem::exists.

Comment thread mlx/backend/cpu/jit_compiler.cpp Outdated
}
return result == 1;
#else
static int result = -1;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
static int result = -1;
static int result = std::system("...");
return result == 0;

Comment thread mlx/backend/cpu/jit_compiler.cpp Outdated
// Select the JIT compiler. The preamble was preprocessed at build time
// by whichever compiler built the library -- it contains compiler-specific
// builtins (e.g. __builtin_fpclassify for Clang, __is_same for MSVC) that
// are only valid for the same compiler family. Prefer the matching one.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should ship the preamble headers along with your binary, which we do in python and can root out this problem completely (#3463).

if (!info.clang_cl.empty() && info.cl_exe == info.clang_cl) {
compiler_flags += " -Wno-everything";
}
#ifdef __AVX2__
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AVX2 should be checked at run time, you can't ensure binary built with AVX2 enabled would always run on machines with it.

Comment thread mlx/backend/cpu/jit_compiler.cpp Outdated
"\"{}\" /LD /EHsc /MD /Ox /nologo /std:c++17 {} \"{}\" "
"/link /out:\"{}\" 2>&1"
"cd /D \"{0}\" && "
"\"{1}\" /LD /EHsc /MD /Ox /nologo /std:c++17{5} \"{2}\" "
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer listing the args in increasing order otherwise I have to count the index of the args to know where they would be inserted.

Also fixed Visual Studio compiler selection conservative for the embedded prebuilt preamble fallback while preferring cl.exe when installed headers are available.

Pass Visual Studio INCLUDE paths from vcvarsall into runtime JIT compilations so normal Python processes can find VC and Windows SDK headers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants