Repository navigation
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
177 lines (149 loc) · 6.55 KB
/
Copy pathCMakeLists.txt
File metadata and controls
177 lines (149 loc) · 6.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
cmake_minimum_required(VERSION 3.16)
project(MLXSwift LANGUAGES C CXX Swift)
# ----------------------------- Setup -----------------------------
# note: 1:1 mirror of MLX configs
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INSTALL_MESSAGE NEVER)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# ----------------------------- Configuration -----------------------------
# note: mirrors a subset of MLX options exactly (1:1 mapping)
# 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)
# ----------------------------- Lib -----------------------------
include(FetchContent)
# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24:
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 "ebc88f10caa1b625e6b581437a8dea6df8a70085")
FetchContent_MakeAvailable(mlx-c)
# swift-numerics
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})
FetchContent_MakeAvailable(swift-numerics)
# MLX package
if(MLX_BUILD_CUDA)
find_package(CUDAToolkit REQUIRED)
include(${cudnn_frontend_SOURCE_DIR}/cmake/cuDNN.cmake)
message(STATUS "Patching 'mlxc' target to add public CUDA dependencies.")
target_link_libraries(
mlxc
PUBLIC CUDA::cudart
CUDA::cublasLt # Promoted from PRIVATE, required by mlx
CUDA::nvrtc # Promoted from PRIVATE, required by mlx
CUDA::cuda_driver # Promoted from PRIVATE, required by mlx
CUDNN::cudnn_all # Promoted from PRIVATE, required by mlx
)
endif()
# cLogSupport package small C shim that exposes os_log_type_enabled() to Swift
# (see #491)
set(cLogSupport_include ${CMAKE_CURRENT_LIST_DIR}/Source/cLogSupport/include)
set(cLogSupport_module_dir ${CMAKE_CURRENT_BINARY_DIR}/cLogSupport-module)
file(
WRITE ${cLogSupport_module_dir}/module.modulemap
"module cLogSupport {\n header \"${cLogSupport_include}/cLogSupport.h\"\n export *\n}\n"
)
add_library(cLogSupport STATIC
${CMAKE_CURRENT_LIST_DIR}/Source/cLogSupport/cLogSupport.c)
target_include_directories(cLogSupport PUBLIC ${cLogSupport_include}
${cLogSupport_module_dir})
file(GLOB MLX-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLX/*.swift)
if(NOT MLX_BUILD_METAL)
list(REMOVE_ITEM MLX-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLX/GPU+Metal.swift
${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)
# Note: mlxc is target name exported by mlx-c
target_link_libraries(MLX PUBLIC mlxc Numerics cLogSupport)
target_compile_options(MLX PRIVATE -package-name MLX)
# MLXRandom package
file(GLOB MLXRandom-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLXRandom/*.swift)
add_library(MLXRandom STATIC ${MLXRandom-src})
target_link_libraries(MLXRandom PRIVATE MLX)
# MLXFast package
file(GLOB MLXFast-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLXFast/*.swift)
add_library(MLXFast STATIC ${MLXFast-src})
target_link_libraries(MLXFast PRIVATE MLX)
# MLXNN package
file(GLOB MLXNN-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLXNN/*.swift)
add_library(MLXNN STATIC ${MLXNN-src})
target_link_libraries(MLXNN PRIVATE MLX MLXRandom MLXFast)
# MLXOptimizers package
file(GLOB MLXOptimizers-src
${CMAKE_CURRENT_LIST_DIR}/Source/MLXOptimizers/*.swift)
add_library(MLXOptimizers STATIC ${MLXOptimizers-src})
target_link_libraries(MLXOptimizers PRIVATE MLX MLXNN)
# MLXFFT package
file(GLOB MLXFFT-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLXFFT/*.swift)
add_library(MLXFFT STATIC ${MLXFFT-src})
target_link_libraries(MLXFFT PRIVATE MLX)
# MLXLinalg package
file(GLOB MLXLinalg-src ${CMAKE_CURRENT_LIST_DIR}/Source/MLXLinalg/*.swift)
add_library(MLXLinalg STATIC ${MLXLinalg-src})
target_link_libraries(MLXLinalg PRIVATE MLX)
# Examples
if(MLX_SWIFT_BUILD_EXAMPLES)
add_executable(example1
${CMAKE_CURRENT_LIST_DIR}/Source/Examples/Example1.swift)
target_link_libraries(example1 PRIVATE MLX)
target_compile_options(example1 PRIVATE -parse-as-library)
add_executable(tutorial
${CMAKE_CURRENT_LIST_DIR}/Source/Examples/Tutorial.swift)
target_link_libraries(tutorial PRIVATE MLX)
target_compile_options(tutorial PRIVATE -parse-as-library)
endif()