Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to creating MtlArray using a memory allocated by Array #62

Closed
ronisbr opened this issue Nov 19, 2022 · 2 comments · Fixed by #320
Closed

Add support to creating MtlArray using a memory allocated by Array #62

ronisbr opened this issue Nov 19, 2022 · 2 comments · Fixed by #320
Labels
arrays Things about the array abstraction. enhancement New feature or request

Comments

@ronisbr
Copy link

ronisbr commented Nov 19, 2022

Hi!

The package has already the support to create an Array given the memory allocated by a MtlArray, but not the other way around. It is possible, but required that the allocated memory is page-aligned. The following code is a MWE of how this can be achieved (without worrying about object destruction):

using Metal

# Obtain the page size.
pagesize = ccall(:getpagesize, Cint, ())

# Dimensions and type of the desired array.
dims = (1000, 1000)
T = Float32

# Compute how many pages we need to store the array.
npages = ceil(Int, prod(dims) * sizeof(T) / pagesize)

# Compute the total number of bytes.
nbytes = npages * pagesize

# Allocate memory aligned with the page.
addr = Ref(C_NULL)
ccall(
    :posix_memalign,
    Cint,
    (Ptr{Ptr{Cvoid}}, Csize_t, Csize_t),
    addr,
    pagesize,
    prod(dims) * sizeof(T)
)

# Wrap the allocated memory to a Julia array.
array = unsafe_wrap(Array{T, length(dims)}, reinterpret(Ptr{T}, addr[]), dims, own = false)

# Create the MtlArray.
pbuf = Metal.MTL.mtDeviceNewBufferWithBytesNoCopy(
    current_device(),
    addr[],
    nbytes,
    Metal.Shared | Metal.MTL.DefaultTracking | Metal.MTL.DefaultCPUCache
)
buf = MtlBuffer(pbuf)
marray = MtlArray{T, length(dims)}(buf, dims)

julia> array[1, 1] = 100.0
100.0

julia> marray[1, 1]
100.0

julia> array[1000, 1000] = 1986
1968

julia> marray[1000, 1000]
1986.0

julia> marray[1000, 1000] = 1987
1987

julia> array[1000, 1000]
1987.0
@maleadt
Copy link
Member

maleadt commented Nov 21, 2022

@jpsamaroo also mentioned that a better way to allocate page-aligned memory is probably https://github.com/mkitti/ArrayAllocators.jl

@maleadt maleadt added the enhancement New feature or request label Feb 8, 2023
@maleadt maleadt added the arrays Things about the array abstraction. label May 22, 2023
@dlfivefifty
Copy link

Thanks for creating this issue. Not being an expert I was confused why this package wasn't taking advantage of the shared memory of M1/2 chips and this answered that question.

Perhaps a comment in the README would be worthwhile for others interested in this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arrays Things about the array abstraction. enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants