Skip to content

pool Streams, fix Device inheritance - #472

Merged
davidkoski merged 3 commits into
mainfrom
stream-redo
Sep 17, 2026
Merged

davidkoski merged 3 commits into
mainfrom
stream-redo

Conversation

@davidkoski

@davidkoski davidkoski commented Sep 6, 2026

Copy link
Copy Markdown
Member

Proposed changes

  • see [BUG] crash while using new_stream mlx#2118

  • Streams are finite and seem to leak OS/Metal resources

  • implements a pool to reuse Streams -- withNewDefaultStream is fully usable

  • much more care is taken with GPU devices

  • using index != 0 now works in all cases

  • and inherits properly when creating new streams

  • Device.setDefaultDevice is documented as to how it works and fails -- use the task scoped calls instead

Checklist

Put an x in the boxes that apply.

  • I have read the CONTRIBUTING document
  • I have run pre-commit run --all-files to format my code / installed pre-commit prior to committing changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have updated the necessary documentation (if needed)

default: die(2, "unknown --device \(CommandLine.arguments[index + 1])")
}
}
Device.setDefault(device: device)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Use task scoped calls now

Comment thread Source/MLX/Device.swift
}

/// static CPU device
/// Current CPU device.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Previously there was no distinction between these. Now (in particular for GPU devices) the distinction is real and works. If the default device is gpu/7 the .gpu will return that. Previously it would always return gpu/0.

Comment thread Source/MLX/Device.swift
Comment on lines -108 to -113
// Ask the underlying MLX C++ core for its default device rather
// than hard-coding `.gpu`. On Apple platforms with Metal this
// still resolves to GPU; on a CPU-only host (Linux without
// CUDA / no Metal) it correctly resolves to CPU. Hard-coding GPU
// here meant `defaultDevice()` / `StreamOrDevice.default`
// returned an unavailable device on those hosts.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

See StreamPairPromise

Comment thread Source/MLX/Stream.swift
Comment on lines -101 to -102
public static let gpu = Stream(newStreamThreadUnsafe(.gpu))
public static let cpu = Stream(newStreamThreadUnsafe(.cpu))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Previously these were static streams, even if you were overriding the default stream. This now resolves to the default stream of the appropriate type

- see ml-explore/mlx#2118
- Streams are finite and seem to leak OS/Metal resources
- implements a pool to reuse Streams -- withNewDefaultStream is fully usable

- much more care is taken with GPU devices
- using index != 0 now works in all cases
- and inherits properly when creating new streams
@nwh
nwh self-requested a review September 16, 2026 19:57

@nwh nwh 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.

🚢

@davidkoski
davidkoski merged commit 84d9eae into main Sep 17, 2026
13 of 14 checks passed
@davidkoski
davidkoski deleted the stream-redo branch September 17, 2026 16:21
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.

2 participants