Make MLX build on x64 macOS (#901)

The arm64 macbook pros are heavy and I usually care my intel one for
mobile, it would be nice if I can play with MLX on it.

To build with x64, user must pass `MLX_ENABLE_X64_MAC` to cmake:
CMAKE_ARGS='-DMLX_ENABLE_X64_MAC=ON' python setup.py
This commit is contained in:
Cheng 2024-03-27 22:14:29 +09:00 committed by GitHub
parent 90dfa43ff1
commit f30b659291
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 40 additions and 30 deletions

View File

@ -15,6 +15,7 @@ option(MLX_BUILD_EXAMPLES "Build examples for mlx" ON)
option(MLX_BUILD_BENCHMARKS "Build benchmarks for mlx" OFF) option(MLX_BUILD_BENCHMARKS "Build benchmarks for mlx" OFF)
option(MLX_BUILD_PYTHON_BINDINGS "Build python bindings for mlx" OFF) option(MLX_BUILD_PYTHON_BINDINGS "Build python bindings for mlx" OFF)
option(MLX_BUILD_METAL "Build metal backend" ON) option(MLX_BUILD_METAL "Build metal backend" ON)
option(MLX_ENABLE_X64_MAC "Enable building for x64 macOS" OFF)
option(BUILD_SHARED_LIBS "Build mlx as a shared library" OFF) option(BUILD_SHARED_LIBS "Build mlx as a shared library" OFF)
if(NOT MLX_VERSION) if(NOT MLX_VERSION)
@ -23,23 +24,23 @@ endif()
# --------------------- Processor tests ------------------------- # --------------------- Processor tests -------------------------
message(STATUS "Building MLX for ${CMAKE_HOST_SYSTEM_PROCESSOR} processor on ${CMAKE_SYSTEM_NAME}") message(STATUS "Building MLX for ${CMAKE_SYSTEM_PROCESSOR} processor on ${CMAKE_SYSTEM_NAME}")
set(MLX_BUILD_ARM OFF) set(MLX_BUILD_ARM OFF)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
if (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64" AND ${CMAKE_HOST_APPLE}) if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
message(FATAL_ERROR if(NOT MLX_ENABLE_X64_MAC)
"Building for x86_64 on macOS is not supported." message(FATAL_ERROR
" If you are on an Apple silicon system, check the build" "Building for x86_64 on macOS is not supported."
" documentation for possible fixes: " " If you are on an Apple silicon system, check the build"
"https://ml-explore.github.io/mlx/build/html/install.html#build-from-source") " documentation for possible fixes: "
elseif (${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "x86_64") "https://ml-explore.github.io/mlx/build/html/install.html#build-from-source")
message(WARNING else()
"Building for x86_64 on macOS is not supported." message(WARNING "Building for x86_64 arch is not officially supported.")
" If you are on an Apple silicon system, " endif()
" make sure you are building for arm64.") set(MLX_BUILD_METAL OFF)
elseif(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm64") elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64")
set(MLX_BUILD_ARM ON) set(MLX_BUILD_ARM ON)
endif() endif()
@ -108,7 +109,27 @@ if (MLX_BUILD_ARM AND ACCELERATE_LIBRARY)
else() else()
message(STATUS "Accelerate or arm neon not found, using default backend.") message(STATUS "Accelerate or arm neon not found, using default backend.")
set(MLX_BUILD_ACCELERATE OFF) set(MLX_BUILD_ACCELERATE OFF)
#set(BLA_VENDOR Generic) if(${CMAKE_HOST_APPLE})
# The blas shipped in macOS SDK is not supported, search homebrew for
# openblas instead.
set(BLA_VENDOR OpenBLAS)
set(LAPACK_ROOT "${LAPACK_ROOT};$ENV{LAPACK_ROOT};/usr/local/opt/openblas")
endif()
# Search and link with lapack.
find_package(LAPACK REQUIRED)
if (NOT LAPACK_FOUND)
message(FATAL_ERROR "Must have LAPACK installed")
endif()
find_path(LAPACK_INCLUDE_DIRS lapacke.h
/usr/include
/usr/local/include
/usr/local/opt/openblas/include)
message(STATUS "Lapack lib " ${LAPACK_LIBRARIES})
message(STATUS "Lapack include " ${LAPACK_INCLUDE_DIRS})
target_include_directories(mlx PRIVATE ${LAPACK_INCLUDE_DIRS})
target_link_libraries(mlx ${LAPACK_LIBRARIES})
# List blas after lapack otherwise we may accidentally incldue an old version
# of lapack.h from the include dirs of blas.
find_package(BLAS REQUIRED) find_package(BLAS REQUIRED)
if (NOT BLAS_FOUND) if (NOT BLAS_FOUND)
message(FATAL_ERROR "Must have BLAS installed") message(FATAL_ERROR "Must have BLAS installed")
@ -122,17 +143,6 @@ else()
message(STATUS "Blas include " ${BLAS_INCLUDE_DIRS}) message(STATUS "Blas include " ${BLAS_INCLUDE_DIRS})
target_include_directories(mlx PRIVATE ${BLAS_INCLUDE_DIRS}) target_include_directories(mlx PRIVATE ${BLAS_INCLUDE_DIRS})
target_link_libraries(mlx ${BLAS_LIBRARIES}) target_link_libraries(mlx ${BLAS_LIBRARIES})
find_package(LAPACK REQUIRED)
if (NOT LAPACK_FOUND)
message(FATAL_ERROR "Must have LAPACK installed")
endif()
find_path(LAPACK_INCLUDE_DIRS lapacke.h
/usr/include
/usr/local/include)
message(STATUS "Lapack lib " ${LAPACK_LIBRARIES})
message(STATUS "Lapack include " ${LAPACK_INCLUDE_DIRS})
target_include_directories(mlx PRIVATE ${LAPACK_INCLUDE_DIRS})
target_link_libraries(mlx ${LAPACK_LIBRARIES})
endif() endif()
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/mlx) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/mlx)

View File

@ -11,8 +11,8 @@ import numpy as np
class MLXTestCase(unittest.TestCase): class MLXTestCase(unittest.TestCase):
@property @property
def is_linux(self): def is_apple_silicon(self):
return platform.system() == "Linux" return platform.machine() == "arm64" and platform.system() == "Darwin"
def setUp(self): def setUp(self):
self.default = mx.default_device() self.default = mx.default_device()

View File

@ -62,7 +62,7 @@ class TestFastSDPA(mlx_tests.MLXTestCase):
B = 1 B = 1
H = 32 H = 32
dtypes = [np.float32] dtypes = [np.float32]
if not self.is_linux: if self.is_apple_silicon:
dtypes.append(np.half) dtypes.append(np.half)
for SEQUENCE_LENGTH in [1, 7, 9, 32, 63, 67, 129, 400, 2000]: for SEQUENCE_LENGTH in [1, 7, 9, 32, 63, 67, 129, 400, 2000]:

View File

@ -1772,8 +1772,8 @@ class TestOps(mlx_tests.MLXTestCase):
) )
def test_tensordot(self): def test_tensordot(self):
# No fp16 matmuls on linux # No fp16 matmuls on common cpu backend
if self.is_linux: if not self.is_apple_silicon:
dtypes = [mx.float32] dtypes = [mx.float32]
else: else:
dtypes = [mx.float16, mx.float32] dtypes = [mx.float16, mx.float32]