Skip to content

fix(Device): resolve initial default from MLX core, not hard-coded GPU#422

Merged
davidkoski merged 1 commit into
ml-explore:mainfrom
tsushanth:fix/default-device-from-mlx-core
Jun 11, 2026
Merged

fix(Device): resolve initial default from MLX core, not hard-coded GPU#422
davidkoski merged 1 commit into
ml-explore:mainfrom
tsushanth:fix/default-device-from-mlx-core

Conversation

@tsushanth

Copy link
Copy Markdown
Contributor

Closes #395.

_resolveGlobalDefaultDevice() returned .gpu whenever no explicit setDefault(...) had been called, so on a CPU-only host (Linux with no Metal / no CUDA) Device.defaultDevice() and StreamOrDevice.default both returned a device that doesn't actually exist on that machine — every subsequent op routed to the default stream then failed.

The deprecated Device.init() already encodes the right pattern: ask the underlying C++ core with mlx_get_default_device(...) and let it pick the device its build supports. Switch _resolveGlobalDefaultDevice to that path.

 private static func _resolveGlobalDefaultDevice() -> Device {
     _lock.withLock {
-        _defaultDevice ?? .gpu
+        if let device = _defaultDevice {
+            return device
+        }
+        var ctx = mlx_device_new()
+        mlx_get_default_device(&ctx)
+        return Device(ctx)
     }
 }

On Apple platforms with Metal this still resolves to GPU — testUsingDevice already covers that and continues to pass — and setDefault / withDefaultDevice overrides still win through the same _defaultDevice check above the fall-through.

Matches the fix proposed in the issue.

…coded GPU

Closes ml-explore#395.

`_resolveGlobalDefaultDevice()` returned `.gpu` whenever no explicit
`setDefault(...)` had been called, so on a CPU-only host (Linux with no
Metal / no CUDA) `Device.defaultDevice()` and `StreamOrDevice.default`
both returned a device that simply doesn't exist, causing every
subsequent op routed to the default stream to fail.

The deprecated `Device.init()` already shows the right pattern: call
`mlx_get_default_device()` and let the C++ core pick the device its
build supports. Use that path instead of the hard-coded `.gpu`.

On Apple platforms with Metal this still resolves to GPU — existing
tests (`testUsingDevice`) cover that — and `setDefault` / `withDefaultDevice`
overrides continue to win through the same `_defaultDevice` check above
the new fall-through.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@davidkoski davidkoski left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you.

@davidkoski davidkoski merged commit 1cd3ed5 into ml-explore:main Jun 11, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Default device is gpu on cpu-only Linux.

2 participants