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

Support pointers as memory backend #61

Open
giordano opened this issue Jul 10, 2024 · 3 comments
Open

Support pointers as memory backend #61

giordano opened this issue Jul 10, 2024 · 3 comments
Labels
enhancement New feature or request

Comments

@giordano
Copy link
Collaborator

Today at JuliaCon I was talking with @MasonProtter about this package, and he brought up the idea of making the memory backend type a parameter, so that instead of Memory{T} one could use, say, Ptr{T}.

@giordano giordano added the enhancement New feature or request label Jul 10, 2024
@giordano
Copy link
Collaborator Author

Actually, that's probably going to work already with #52?

@nsajko
Copy link
Collaborator

nsajko commented Jul 10, 2024

Currently #52 has the constraint on the Mem type parameter: <:GenericMemory{<:Any,T}. At some point in-development I considered generalizing the constraint to <:DenseVector{T} (relevant for #35), but I guess I decided to leave that for later.

Perhaps Ptr could be supported, too, can't tell right away.

@nsajko nsajko changed the title Making memory backend a paramter Making memory backend a parameter Jul 10, 2024
@giordano
Copy link
Collaborator Author

With #52, a good chunk of the work to extend the memory backend to a Ptr is done. A minimal patch to allow creating fixed-size arrays backed by pointers can be something like (very unsafe, as is dealing with pointers directly)

diff --git a/src/FixedSizeArrays.jl b/src/FixedSizeArrays.jl
index 41c1394..8be5990 100644
--- a/src/FixedSizeArrays.jl
+++ b/src/FixedSizeArrays.jl
@@ -11,10 +11,10 @@ Implementation detail. Do not use.
 """
 struct Internal end
 
-struct FixedSizeArray{T,N,Mem<:GenericMemory{<:Any,T}} <: DenseArray{T,N}
+struct FixedSizeArray{T,N,Mem<:Union{GenericMemory{<:Any,T},Ptr{T}}} <: DenseArray{T,N}
     mem::Mem
     size::NTuple{N,Int}
-    function FixedSizeArray{T,N,M}(::Internal, mem::M, size::NTuple{N,Int}) where {T,N,M<:GenericMemory{<:Any,T}}
+    function FixedSizeArray{T,N,M}(::Internal, mem::M, size::NTuple{N,Int}) where {T,N,M<:Union{GenericMemory{<:Any,T},Ptr{T}}}
         new{T,N,M}(mem, size)
     end
 end
@@ -53,9 +53,19 @@ function FixedSizeArray{T}(::UndefInitializer, size::NTuple{N,Integer}) where {T
     FixedSizeArray{T,N}(undef, size)
 end
 
+function FixedSizeArray{T,N}(ptr::Ptr{T}, size::NTuple{N,Integer}) where {T,N}
+    FixedSizeArray{T,N,Ptr{T}}(Internal(), ptr, size)
+end
+function FixedSizeArray{T}(ptr::Ptr{T}, size::NTuple{N,Integer}) where {T,N}
+    FixedSizeArray{T,N}(ptr, size)
+end
+
+
 Base.IndexStyle(::Type{<:FixedSizeArray}) = IndexLinear()
 Base.@propagate_inbounds Base.getindex(A::FixedSizeArray, i::Int) = A.mem[i]
 Base.@propagate_inbounds Base.setindex!(A::FixedSizeArray, v, i::Int) = A.mem[i] = v
+Base.getindex(A::FixedSizeArray{T,N,Ptr{T}}, i::Int) where {T,N} = unsafe_load(A.mem, i)
+Base.setindex!(A::FixedSizeArray{T,N,Ptr{T}}, v, i::Int) where {T,N} = unsafe_store!(A.mem, v, i)
 
 Base.size(a::FixedSizeArray) = a.size

At least with this patch you can wrap a pointer into a FixedSizeArray, get and set its elements, but I'm not sure how to further extend this: for example displaying a pointer-backed fixed-size array fails due to isassigned not being defined for pointers, which is used internally by matrix-printing functions:

Error showing value of type FixedSizeVector{Float64, Ptr{Float64}}:
ERROR: MethodError: no method matching isassigned(::Ptr{Float64}, ::Int64)
The function `isassigned` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  isassigned(::Core.SimpleVector, ::Int64)
   @ Base essentials.jl:984
  isassigned(::Vector, ::Int64)
   @ Base array.jl:245
  isassigned(::Array, ::Int64...)
   @ Base array.jl:237
  ...

Stacktrace:
  [1] isassigned(a::FixedSizeVector{Float64, Ptr{Float64}}, i::Int64)
    @ FixedSizeArrays ~/.julia/dev/FixedSizeArrays/src/FixedSizeArrays.jl:76
  [2] isassigned(::FixedSizeVector{Float64, Ptr{Float64}}, ::Int64, ::Int64)
    @ Base ./multidimensional.jl:1642
  [3] alignment(io::IOContext{Base.TTY}, X::AbstractVecOrMat, rows::Vector{Int64}, cols::Vector{Int64}, cols_if_complete::Int64, cols_otherwise::Int64, sep::Int64, ncols::Int64)
    @ Base ./arrayshow.jl:68
  [4] _print_matrix(io::IOContext{…}, X::AbstractVecOrMat, pre::String, sep::String, post::String, hdots::String, vdots::String, ddots::String, hmod::Int64, vmod::Int64, rowsA::UnitRange{…}, colsA::UnitRange{…})
    @ Base ./arrayshow.jl:207

Memory plays much more nicely with all of this, but I don't think we want to go down the path of extending all these internal Base functions for pointer-backed fixed-size arrays.

@giordano giordano changed the title Making memory backend a parameter Support pointers as memory backend Aug 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants