ml-explore / mlx-swift

Swift API for MLX
https://ml-explore.github.io/mlx-swift/
MIT License
687 stars 54 forks source link

`MLX.loadArray` always give zeroed tensor #71

Closed tqtifnypmb closed 7 months ago

tqtifnypmb commented 7 months ago

Snippet to reproduce:

let src = MLX.full([1,2,3], values: MLXArray(100))
let url = URL.temporaryDirectory.appending(path: "xxx.npy")
try MLX.save(array: src, url: url)      

let dest = try MLX.loadArray(url: url)  // shape and dtype is good, but values are zeroed.
davidkoski commented 7 months ago

I wonder if you need to:

eval(src)

before writing it?

awni commented 7 months ago

try MLX.save(array: src, url: url)

@davidkoski that should do an eval under the hood, https://github.com/ml-explore/mlx/blob/main/mlx/io/load.cpp#L36

awni commented 7 months ago

E.g. in Python this works fine:

import mlx.core as mx

src = mx.full([1,2,3], 100)
mx.save("arr.npy", src)
print(mx.load("arr.npy"))

I wonder what's different about the Swift version 🤔

tqtifnypmb commented 7 months ago

I wonder if you need to:

eval(src)

before writing it?

Actually, I was reading npy written by mlx-python.

But I tried it, same.

davidkoski commented 7 months ago

aha:

public func loadArray(url: URL, stream: StreamOrDevice = .default) throws -> MLXArray {
    precondition(url.isFileURL)
    let path = url.path(percentEncoded: false)

    if let fp = fopen(path, "r") {
        defer { fclose(fp) }

        switch url.pathExtension {
        case "npy":
            return MLXArray(mlx_load_file(fp, stream.ctx))

This needs to switch to the filename version of the call. I swear we already ran into this ...

davidkoski commented 7 months ago

I will get this tomorrow