Link with prebuilt OpenBLAS and fix shared libs build on Windows (#3036)
This commit is contained in:
@@ -9,5 +9,5 @@ runs:
|
||||
DEVICE: cpu
|
||||
run: |
|
||||
echo "::group::CPP tests - CPU"
|
||||
./build/tests/tests -tce="*gguf*,test random uniform"
|
||||
./build/tests.exe -tce="*gguf*,test random uniform"
|
||||
echo "::endgroup::"
|
||||
|
||||
+31
-18
@@ -40,7 +40,6 @@ option(MLX_METAL_DEBUG "Enhance metal debug workflow" OFF)
|
||||
option(MLX_ENABLE_X64_MAC "Enable building for x64 macOS" OFF)
|
||||
option(MLX_BUILD_GGUF "Include support for GGUF format" ON)
|
||||
option(MLX_BUILD_SAFETENSORS "Include support for safetensors format" ON)
|
||||
option(MLX_BUILD_BLAS_FROM_SOURCE "Build OpenBLAS from source code" OFF)
|
||||
option(MLX_BUILD_PYTHON_STUBS "Build stub files for python bindings" ON)
|
||||
option(MLX_METAL_JIT "Use JIT compilation for Metal kernels" OFF)
|
||||
option(MLX_USE_CCACHE "Use CCache for compilation cache when available" ON)
|
||||
@@ -219,14 +218,17 @@ if(WIN32)
|
||||
if(MSVC)
|
||||
# GGUF does not build with MSVC.
|
||||
set(MLX_BUILD_GGUF OFF)
|
||||
# There is no prebuilt OpenBLAS distribution for MSVC.
|
||||
set(MLX_BUILD_BLAS_FROM_SOURCE ON)
|
||||
endif()
|
||||
# Generate DLL and EXE in the same dir, otherwise EXE will not be able to run.
|
||||
# This is only done when MLX is built as the top project.
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
endif()
|
||||
# Windows implementation of dlfcn.h APIs.
|
||||
FetchContent_Declare(
|
||||
dlfcn-win32
|
||||
GIT_REPOSITORY https://github.com/dlfcn-win32/dlfcn-win32.git
|
||||
GIT_TAG v1.4.1
|
||||
GIT_TAG v1.4.2
|
||||
EXCLUDE_FROM_ALL)
|
||||
block()
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
@@ -250,23 +252,25 @@ if(MLX_BUILD_CPU)
|
||||
target_link_libraries(mlx PUBLIC ${ACCELERATE_LIBRARY})
|
||||
add_compile_definitions(MLX_USE_ACCELERATE)
|
||||
add_compile_definitions(ACCELERATE_NEW_LAPACK)
|
||||
elseif(MLX_BUILD_BLAS_FROM_SOURCE)
|
||||
# Download and build OpenBLAS from source code.
|
||||
elseif(WIN32)
|
||||
# Download and link prebuilt binaries of OpenBLAS. Note that we can only
|
||||
# link with the dynamic library, the prebuilt binaries were built with MinGW
|
||||
# so static-linking would require linking with MinGW's runtime.
|
||||
FetchContent_Declare(
|
||||
openblas
|
||||
GIT_REPOSITORY https://github.com/OpenMathLib/OpenBLAS.git
|
||||
GIT_TAG v0.3.28
|
||||
EXCLUDE_FROM_ALL)
|
||||
block(PROPAGATE openblas_SOURCE_DIR)
|
||||
set(BUILD_SHARED_LIBS OFF) # link statically
|
||||
set(BUILD_STATIC_LIBS ON)
|
||||
set(NOFORTRAN ON) # msvc has no fortran compiler
|
||||
URL "https://github.com/OpenMathLib/OpenBLAS/releases/download/v0.3.31/OpenBLAS-0.3.31-x64.zip"
|
||||
)
|
||||
FetchContent_MakeAvailable(openblas)
|
||||
endblock()
|
||||
target_link_libraries(mlx PRIVATE openblas)
|
||||
target_include_directories(
|
||||
mlx PRIVATE "${openblas_SOURCE_DIR}/lapack-netlib/LAPACKE/include"
|
||||
"${CMAKE_BINARY_DIR}/generated" "${CMAKE_BINARY_DIR}")
|
||||
target_link_libraries(mlx
|
||||
PRIVATE "${openblas_SOURCE_DIR}/lib/libopenblas.lib")
|
||||
target_include_directories(mlx PRIVATE "${openblas_SOURCE_DIR}/include")
|
||||
# Make sure the DLL file is placed in the same dir with executables.
|
||||
set(OPENBLAS_DLL_FILE "${openblas_SOURCE_DIR}/bin/libopenblas.dll")
|
||||
add_custom_command(
|
||||
TARGET mlx
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${OPENBLAS_DLL_FILE}
|
||||
${CMAKE_BINARY_DIR})
|
||||
else()
|
||||
if(${CMAKE_HOST_APPLE})
|
||||
# The blas shipped in macOS SDK is not supported, search homebrew for
|
||||
@@ -365,6 +369,15 @@ endif()
|
||||
# ----------------------------- Installation -----------------------------
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if(WIN32)
|
||||
# Install DLLs to the same dir with extension file (core.pyd) on Windows.
|
||||
set(CMAKE_INSTALL_BINDIR ".")
|
||||
if(MLX_BUILD_CPU)
|
||||
# Install OpenBLAS.
|
||||
install(FILES ${OPENBLAS_DLL_FILE} TYPE BIN)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Install library
|
||||
install(
|
||||
TARGETS mlx
|
||||
|
||||
@@ -3,14 +3,6 @@ function(build_benchmark SRCFILE)
|
||||
set(target "${src_name}")
|
||||
add_executable(${target} ${SRCFILE})
|
||||
target_link_libraries(${target} PRIVATE mlx)
|
||||
# On Windows, copy the mlx DLL to the executable directory for runtime loading
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:mlx>
|
||||
$<TARGET_FILE_DIR:${target}>)
|
||||
endif()
|
||||
endfunction(build_benchmark)
|
||||
|
||||
build_benchmark(single_ops.cpp)
|
||||
|
||||
@@ -3,14 +3,6 @@ function(build_example SRCFILE)
|
||||
set(target "${src_name}")
|
||||
add_executable(${target} ${SRCFILE})
|
||||
target_link_libraries(${target} PRIVATE mlx)
|
||||
# On Windows, copy the mlx DLL to the executable directory for runtime loading
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:mlx>
|
||||
$<TARGET_FILE_DIR:${target}>)
|
||||
endif()
|
||||
endfunction(build_example)
|
||||
|
||||
build_example(tutorial.cpp)
|
||||
|
||||
@@ -95,6 +95,7 @@ class CMakeBuild(build_ext):
|
||||
"-DMLX_BUILD_TESTS=OFF",
|
||||
"-DMLX_BUILD_BENCHMARKS=OFF",
|
||||
"-DMLX_BUILD_EXAMPLES=OFF",
|
||||
"-DBUILD_SHARED_LIBS=ON",
|
||||
]
|
||||
if build_stage == 2 and build_cuda:
|
||||
# Last arch is always real and virtual for forward-compatibility
|
||||
@@ -125,13 +126,6 @@ class CMakeBuild(build_ext):
|
||||
archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", ""))
|
||||
if archs:
|
||||
cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))]
|
||||
if platform.system() == "Windows":
|
||||
# On Windows DLLs must be put in the same dir with the extension
|
||||
# while cmake puts mlx.dll into the "bin" sub-dir. Link with mlx
|
||||
# statically to work around it.
|
||||
cmake_args += ["-DBUILD_SHARED_LIBS=OFF"]
|
||||
else:
|
||||
cmake_args += ["-DBUILD_SHARED_LIBS=ON"]
|
||||
|
||||
# Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
|
||||
# across all generators.
|
||||
|
||||
@@ -40,15 +40,5 @@ target_link_libraries(tests PRIVATE mlx doctest)
|
||||
target_compile_options(tests PRIVATE ${SANITIZER_COMPILE_FLAGS})
|
||||
target_link_options(tests PRIVATE ${SANITIZER_LINK_FLAGS})
|
||||
|
||||
# On Windows, copy the mlx DLL to the test executable directory for runtime
|
||||
# loading
|
||||
if(WIN32 AND BUILD_SHARED_LIBS)
|
||||
add_custom_command(
|
||||
TARGET tests
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:mlx>
|
||||
$<TARGET_FILE_DIR:tests>)
|
||||
endif()
|
||||
|
||||
doctest_discover_tests(tests)
|
||||
add_test(NAME tests COMMAND tests)
|
||||
|
||||
Reference in New Issue
Block a user