Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
bd196a9
Add AdamW bias correction parameter. (#400)
mattgallagher May 7, 2026
89cece7
fix: check mlx_detail_compile and mlx_closure_apply return values (#398)
vernonstinebaker May 7, 2026
058eda6
hold evalLock while computing tostring (#410)
davidkoski May 21, 2026
dc43e62
Expose nuclear norm order in linalg API (#411)
RNT56 May 26, 2026
1cd3ed5
fix(Device): resolve initial default from the MLX C++ core, not hard-…
tsushanth Jun 11, 2026
e23ae6b
Allowing SPM to compile on Linux with CUDA (#413)
gmondada Jun 17, 2026
683df31
Add MultiOptimizer (port from Python mlx.optimizers) (#431)
GoodOlClint Jun 30, 2026
bb0399d
Add MLXArray and DType extensions (#429)
ronaldmannak Jun 30, 2026
1a864ce
Add Muon optimizer (port from Python mlx.optimizers) (#432)
GoodOlClint Jun 30, 2026
eb889e0
Add learning-rate schedules (port from Python mlx.optimizers.schedule…
GoodOlClint Jun 30, 2026
041cc7c
Move .complex64 to .float32 (#434)
ronaldmannak Jun 30, 2026
0bb916c
guard use of Process (#437)
davidkoski Jul 2, 2026
7a8d05a
Add fp8 conversion utilities (#435)
lucasnewman Jul 7, 2026
de3342c
build iOS in CI (#440)
davidkoski Jul 7, 2026
09051ed
Add global scale support to quantized layers (#426)
aleroot Jul 13, 2026
9a09a03
Fix FinalizerCaptureState leak in MLXArray(rawPointer:_:dtype:finaliz…
agerjura Aug 4, 2026
da31870
Derive the jit-source lists in update-mlx.sh instead of hand-listing …
GoodOlClint Aug 10, 2026
2157852
Improve CUDA NVCC spawn performance (on Linux) (#451)
Joannis Aug 14, 2026
3a24fa3
Condition CUDA build plugin on Linux host (#447)
ThorFuchs Aug 14, 2026
7b745d2
Nested initializers (#456)
louen Aug 17, 2026
97cf19e
[CUDA] Build the CUDA argument lists in steps (#442)
GoodOlClint Aug 17, 2026
df9ae26
Fix a deadlock between `CompiledFunction.lock` and `evalLock`, and a …
DanielMercado60660 Aug 24, 2026
d737cd0
Fix StreamOrDevice.stream(_:) ignoring its argument (#463)
aleroot Aug 27, 2026
ac4ae9a
test Module parameters and compile (#465)
davidkoski Aug 31, 2026
ab924c8
update for mlx v0.32.2 (#450)
CharlieTLe Sep 1, 2026
ea8a179
Fix wired-memory ticket lifecycle during cancellation (#471)
aleroot Sep 11, 2026
a4c3b54
Fix condition typo (#473)
Silenterc Sep 14, 2026
555692a
fix(ops): fix convolve padRight for even-sized kernels in same mode (…
shubhransh-gupta Sep 14, 2026
2bebe4e
Add countNonzero to the Swift API (#479)
Silenterc Sep 14, 2026
8541c5c
Distributed support (#482)
ronaldmannak Sep 17, 2026
bac95f7
add thin logging shim (#484)
davidkoski Sep 17, 2026
9ba1545
patch for Cuda builds (#478)
davidkoski Sep 17, 2026
84d9eae
pool Streams, fix Device inheritance (#472)
davidkoski Sep 17, 2026
9019419
replace and improve integration tests (#477)
davidkoski Sep 17, 2026
cd36d17
pick up fix-custom-io from mlx-c (#476)
davidkoski Sep 28, 2026
2b5e877
package: exclude mlx/build (cmake artifacts) from Cmlx target (#402)
Nicolas-nwb Sep 28, 2026
1960120
fix MLXLogger (#493)
davidkoski Sep 30, 2026
b4f7684
Fix attention mask for `float16` (#496)
louen Oct 4, 2026
2c3c1c4
Merge upstream ml-explore/mlx-swift (0.32.3+, b4f7684) into SharpAI/m…
Oct 5, 2026
d7a5ec7
Remove stray mlx repository files from Source/
Oct 5, 2026
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
16 changes: 14 additions & 2 deletions .github/scripts/setup+build-linux-container-cmake.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
set -ex

# [Setup] Install dependencies inside the container.
# Note: mlx-c requires a C++20 toolchain with <format> support:
# - libstdc++ >= 13 (Ubuntu noble, Fedora 39+)
# - or libc++ >= 17
# Debian bookworm (libstdc++ 12) is *not* sufficient.
if command -v apt-get >/dev/null 2>&1; then
apt-get update -y
apt-get install -y \
Expand All @@ -12,6 +16,9 @@ if command -v apt-get >/dev/null 2>&1; then
liblapacke-dev \
libopenblas-dev

export CC=/usr/bin/gcc
export CXX=/usr/bin/g++

elif command -v dnf >/dev/null 2>&1; then
dnf update -y
dnf install -y \
Expand All @@ -23,6 +30,11 @@ elif command -v dnf >/dev/null 2>&1; then
clang \
ninja-build

# Fedora's default gcc (13+) has <format>; keep it as the compiler so this
# build keeps matching what has been passing in CI.
export CC=/usr/bin/gcc
export CXX=/usr/bin/g++

else
echo "No supported package manager found (apt-get, dnf)"
exit 1
Expand All @@ -31,8 +43,8 @@ fi
# [CMake] CI Build Sanity Check: Verifies code compilation, not for release.
export CMAKE_ARGS="-DCMAKE_COMPILE_WARNING_AS_ERROR=ON"
export DEBUG=1
export CMAKE_C_COMPILER=/usr/bin/clang
export CMAKE_CXX_COMPILER=/usr/bin/clang++

"$CXX" --version

rm -rf build
mkdir -p build
Expand Down
44 changes: 29 additions & 15 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ jobs:
run: |
pre-commit run --all || (echo "Style checks failed, please install pre-commit and run pre-commit run --all and push the change"; echo ""; git --no-pager diff; exit 1)


mac_build_and_test:
needs: lint
if: github.repository == 'ml-explore/mlx-swift'
Expand All @@ -82,46 +83,54 @@ jobs:
shell: bash
run: xcodebuild -showComponent MetalToolchain

- name: Verify SwiftPM manifest CUDA containment
run: scripts/verify-spm-manifest.py

- name: Setup cmake
shell: sh
run: |
brew install cmake ninja

- name: Verify documentation
run: scripts/verify-docs.sh

- name: Build SwiftPM (Xcode, iOS)
shell: sh
run: |
xcodebuild -version
swift --version
rm -rf ~/Library/Developer/Xcode/DerivedData/*
xcodebuild build -scheme mlx-swift-Package -destination 'generic/platform=iOS'

- name: Build SwiftPM (Xcode, macOS)
shell: sh
env:
# workaround for CI failure
DEVELOPER_DIR: /Applications/Xcode-latest.app
run: |
xcodebuild -version
xcrun --show-sdk-build-version
swift --version
rm -rf ~/Library/Developer/Xcode/DerivedData/*
xcodebuild build-for-testing -scheme mlx-swift-Package -destination 'platform=macOS'

- name: Run Tests SwiftPM (Xcode, macOS)
shell: sh
env:
# workaround for CI failure
DEVELOPER_DIR: /Applications/Xcode-latest.app
run: |
xcrun xctest ~/Library/Developer/Xcode/DerivedData/mlx-swift-*/Build/Products/Debug/CmlxTests.xctest
xcrun xctest ~/Library/Developer/Xcode/DerivedData/mlx-swift-*/Build/Products/Debug/MLXTests.xctest
xcrun xctest ~/Library/Developer/Xcode/DerivedData/mlx-swift-*/Build/Products/Debug/MLXIntegrationTests.xctest

- name: Run Distributed Tests SwiftPM (Xcode, macOS)
shell: sh
run: |
MLX_TEST_DISTRIBUTED=1 xcrun xctest -XCTest DistributedRingTests ~/Library/Developer/Xcode/DerivedData/mlx-swift-*/Build/Products/Debug/MLXTests.xctest
MLX_TEST_DISTRIBUTED=1 xcrun xctest -XCTest DistributedNNRingTests ~/Library/Developer/Xcode/DerivedData/mlx-swift-*/Build/Products/Debug/MLXTests.xctest

- name: Build xcodeproj (Xcode, macOS)
shell: sh
env:
# workaround for CI failure
DEVELOPER_DIR: /Applications/Xcode-latest.app
run: |
rm -rf ~/Library/Developer/Xcode/DerivedData/*
cd xcode
xcodebuild build-for-testing -scheme MLX -destination 'platform=macOS'

- name: Run Tests xcodeproj (Xcode, macOS)
env:
# workaround for CI failure
DEVELOPER_DIR: /Applications/Xcode-latest.app
working-directory: xcode
run: ../.github/scripts/run-xcode-tests.sh

Expand Down Expand Up @@ -153,15 +162,20 @@ jobs:
matrix:
include:
# See https://github.com/swiftlang/swift-docker/tree/main/
#
# Note: mlx-c uses std::format, which requires libstdc++ >= 13 (or
# libc++ >= 17). Debian bookworm only ships gcc/libstdc++ 12 (and
# gcc-13 is not available in bookworm-backports), so use Ubuntu
# noble (24.04, gcc/libstdc++ 13) for the Debian-family build.
- host: ubuntu-22.04
arch: x86_64
container: swift:bookworm
container: swift:noble
- host: ubuntu-22.04
arch: x86_64
container: swift:fedora39
- host: ubuntu-22.04-arm
arch: aarch64
container: swift:bookworm
container: swift:noble
- host: ubuntu-22.04-arm
arch: aarch64
container: swift:fedora39
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
shell: bash
run: xcodebuild -showComponent MetalToolchain

- name: Setup gh
shell: sh
run: |
brew install gh

- name: Build XCFrameworks
shell: bash
env:
Expand Down
75 changes: 68 additions & 7 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 "ebc88f10caa1b625e6b581437a8dea6df8a70085")
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 @@ -57,18 +99,37 @@ if(MLX_BUILD_CUDA)
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)
target_link_libraries(MLX PUBLIC mlxc Numerics cLogSupport)
target_compile_options(MLX PRIVATE -package-name MLX)

# MLXRandom package
Expand Down Expand Up @@ -103,7 +164,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
15 changes: 8 additions & 7 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 All @@ -120,9 +115,15 @@ pre-commit run --all-files

SwiftPM is able to fetch repositories from github and build them _if_ they have
a `Package.swift` at the top level. It is unable to do this for repositories
that do not have a `Package.swift`. For this reason `mlx-swift` uses
that do not have a `Package.swift`. For this reason upstream `mlx-swift` uses
git submodules to include the `mlx` and `mlx-c` repositories.

> **SharpAI fork:** this fork vendors `Source/Cmlx/mlx` and `Source/Cmlx/mlx-c` as plain tracked
> directories (upstream release + the SharpAI patch series) instead of submodules. Follow
> [UPSTREAM_MERGE_PLAN.md](UPSTREAM_MERGE_PLAN.md) for the fork's procedure; the steps below
> describe the upstream process, which the fork follows with step 1 replaced by "re-vendor the
> tag/commit upstream's submodules point to, then re-apply the carried patches".

When a new version of `mlx` and its equivalent `mlx-c` are to be used, there is a
process to go through to update `mlx-swift`.

Expand Down
Loading
Loading