Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 8 additions & 0 deletions .github/scripts/build-linux-cuda-cmake.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ rm -rf build
mkdir -p build
pushd build
cmake -DMLX_BUILD_METAL=OFF -DMLX_BUILD_CUDA=ON -DMLX_C_BUILD_EXAMPLES=OFF .. -G Ninja

# Verify the local mlx patch is actually in place: without it the examples below
# crash on exit, which is easy to misread as an unrelated CUDA failure.
git -C _deps/mlx-src apply --reverse --check "$PWD/../cmake/mlx.patch" || {
echo "error: cmake/mlx.patch is not applied to _deps/mlx-src"
exit 1
}

ninja
./example1 --device gpu
./tutorial --device gpu
Expand Down
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "submodules/mlx"]
path = Source/Cmlx/mlx
url = https://github.com/ml-explore/mlx
[submodule "submodules/mlx-c"]
path = Source/Cmlx/mlx-c
url = https://github.com/ml-explore/mlx-c
58 changes: 52 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# ----------------------------- Configuration -----------------------------
# note: mirrors a subset of MLX options exactly (1:1 mapping)

option(MLX_BUILD_EXAMPLES "Build examples for mlx" ON)
# note: MLX_BUILD_EXAMPLES is owned by mlx itself (see below), so the Swift
# examples use their own option name to avoid colliding with mlx's C++ examples
option(MLX_SWIFT_BUILD_EXAMPLES "Build Swift examples for mlx-swift" ON)
option(MLX_BUILD_METAL "Build metal backend" ON)
option(MLX_BUILD_CUDA "Build cuda backend" OFF)

Expand All @@ -26,21 +28,61 @@ if(POLICY CMP0135)
cmake_policy(SET CMP0135 NEW)
endif()

# mlx

# note: patches are applied via cmake/apply-patch.cmake so that they are
# idempotent (the patch step re-runs on every update step) while still failing
# the build loudly if a patch does not apply -- a silently unpatched dependency
# is very hard to diagnose (it typically shows up as a runtime failure).
set(apply_patch ${CMAKE_COMMAND} -DREPO=<SOURCE_DIR>)
set(apply_patch_script -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/apply-patch.cmake)

# two local patches for CUDA:
#
# * https://github.com/ml-explore/mlx/pull/4480: leak the global command encoder
# map rather than synchronizing on process shutdown
# * make ~CudaHandle non-throwing: cu::Worker is detached and holds the last
# reference to itself, so ~Worker -> ~CudaEvent -> cudaEventDestroy runs on
# the worker thread at an arbitrary point during exit, racing the CUDA
# runtime's own teardown. A failing destroy there terminated the process.
set(mlx_patch
${apply_patch} -DPATCH=${CMAKE_CURRENT_SOURCE_DIR}/cmake/mlx.patch
${apply_patch_script})

# note: this must be declared (and named `mlx`) before mlx-c is made available
# so that our pinned/patched version wins over the one mlx-c declares. Because
# we now pull mlx in first, we are also responsible for the option defaults that
# mlx-c would normally set for us.
set(MLX_BUILD_TESTS OFF)
set(MLX_BUILD_EXAMPLES OFF)
set(MLX_BUILD_BENCHMARKS OFF)
set(MLX_BUILD_PYTHON_BINDINGS OFF)

FetchContent_Declare(
mlx
GIT_REPOSITORY "https://github.com/ml-explore/mlx.git"
GIT_TAG "v0.32.2"
PATCH_COMMAND ${mlx_patch})
FetchContent_MakeAvailable(mlx)

# mlx-c
set(MLX_C_BUILD_EXAMPLES OFF)
FetchContent_Declare(
mlx-c
GIT_REPOSITORY "https://github.com/ml-explore/mlx-c.git"
GIT_TAG "v0.6.0")
GIT_TAG "c74db5307cc8ce122f48d97ef951b30578674e7f")
FetchContent_MakeAvailable(mlx-c)

# swift-numerics
set(swift_numerics_patch git apply
${CMAKE_CURRENT_SOURCE_DIR}/cmake/swift-numerics.patch)
set(swift_numerics_patch
${apply_patch}
-DPATCH=${CMAKE_CURRENT_SOURCE_DIR}/cmake/swift-numerics.patch
${apply_patch_script})
FetchContent_Declare(
swift-numerics
GIT_REPOSITORY "https://github.com/apple/swift-numerics.git"
GIT_TAG "1.0.2"
PATCH_COMMAND ${swift_numerics_patch} || true)
PATCH_COMMAND ${swift_numerics_patch})
FetchContent_MakeAvailable(swift-numerics)

# MLX package
Expand All @@ -64,6 +106,10 @@ if(NOT MLX_BUILD_METAL)
${CMAKE_CURRENT_LIST_DIR}/Source/MLX/MLXArray+Metal.swift)
endif()

if(NOT MLX_BUILD_CUDA)
list(REMOVE_ITEM MLX-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLX/GPU+CUDA.swift)
endif()

add_library(MLX STATIC ${MLX-src})
target_include_directories(MLX
PUBLIC ${CMAKE_CURRENT_LIST_DIR}/Source/Cmlx/include)
Expand Down Expand Up @@ -103,7 +149,7 @@ add_library(MLXLinalg STATIC ${MLXLinalg-src})
target_link_libraries(MLXLinalg PRIVATE MLX)

# Examples
if(MLX_BUILD_EXAMPLES)
if(MLX_SWIFT_BUILD_EXAMPLES)
add_executable(example1
${CMAKE_CURRENT_LIST_DIR}/Source/Examples/Example1.swift)
target_link_libraries(example1 PRIVATE MLX)
Expand Down
7 changes: 1 addition & 6 deletions MAINTENANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,7 @@ dependencies: [.product(name: "MLX", package: "mlx-swift"),
.product(name: "MLXOptimizers", package: "mlx-swift")]
```

10. Update `tools/generate_integration_tests.py` as needed

```
import MLXNN
@testable import MLXOptimizers
```
10. Update `tools/integration_tests/cases.py` as needed, regenerate tests if needed

11. Update tests as needed

Expand Down
Loading