Skip to content

Add arange#302

Merged
davidkoski merged 2 commits intoml-explore:mainfrom
DePasqualeOrg:add-arange
Dec 1, 2025
Merged

Add arange#302
davidkoski merged 2 commits intoml-explore:mainfrom
DePasqualeOrg:add-arange

Conversation

@DePasqualeOrg
Copy link
Contributor

@DePasqualeOrg DePasqualeOrg commented Nov 26, 2025

Proposed changes

Do you think it would make sense to add arange to mlx-swift? This is probably the most common piece of missing syntax that I've encountered when porting models from Python to Swift. There are enough existing examples that in practice it's easy enough to find a workaround, but having a direct equivalent would reduce friction. Is there a reason this was not included in mix-swift?

Checklist

  • 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)

@davidkoski
Copy link
Collaborator

There are enough existing examples that in practice it's easy enough to find a workaround, but having a direct equivalent would reduce friction. Is there a reason this was not included in mix-swift?

It wasn't added because there is an idiomatic swift way of doing it (since Range and friends implement Collection):

let a = MLXArray(0 ..< 12)

There are range variants for open, closed and strides -- all of the arange calls can be expressed with these.

Do you think arange gives something compelling over these?

@DePasqualeOrg
Copy link
Contributor Author

The main motivation would be discoverability, especially since models are now commonly ported with automated tools. This came to mind as I was cleaning up the mlx-audio repo, which contained some workarounds for arange in Swift.

Perhaps there's also a performance benefit of using the MLX C API directly, which uses lazy computation?

The syntax with step is also more concise:

// Current workarounds
let a = MLXArray(stride(from: 0, to: 12, by: 2))
let b = MLXArray(stride(from: 0.0, to: 5.0, by: 0.5))
let a = MLXArray.arange(0, 12, step: 2)
let b = MLXArray.arange(0.0, 5.0, step: 0.5)

@davidkoski
Copy link
Collaborator

That seems reasonable -- we can cross link the documentation between the two styles. Using mlx_arange may actually be a performance gain as it will probably initialize the array on the GPU.

@DePasqualeOrg DePasqualeOrg marked this pull request as ready for review November 28, 2025 21:09
@rudrankriyam
Copy link

Agreed; we did a bit of workaround for mlx-audio swift port

@DePasqualeOrg DePasqualeOrg marked this pull request as ready for review November 30, 2025 09:03
/// - ``arange(_:_:step:stream:)``
static public func arange(_ stop: Int, stream: StreamOrDevice = .default) -> MLXArray {
MLX.arange(0, stop, stream: stream)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if all of these could be done with one function?

func arange<T: HasDType>(_ start: T? = nil, _ stop: T, step: T? = nil, dtype:DType? = nil, stream: StreamOrDevice = .default) -> MLXArray 

under the hood the values are doubles (in mlx_arange). It looks like it would require something on either DType or HasDType to produce a Double.

I think this might be cleaner if it works -- the unlabeled optional start might cause trouble. The python side has two for this reason (I think).

See what you think -- I think this looks good overall!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I went through several iterations of this and landed on this design by trying to follow the patterns of existing methods in this repo as well as the Python API. Feel free to take it in any direction you want if you prefer a different approach.

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK, sounds good -- I can play around with variants after it merges to see if any make sense.

@davidkoski
Copy link
Collaborator

@DePasqualeOrg looks like a swift-format failure.

@DePasqualeOrg
Copy link
Contributor Author

Sorry about that. I ran the formatting again.

Copy link
Collaborator

@davidkoski davidkoski left a comment

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 9adb436 into ml-explore:main Dec 1, 2025
1 of 2 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.

3 participants