Skip to content

freeze/thaw interface for StaticStrideArrays #37

@MasonProtter

Description

@MasonProtter

Currently, a StaticStrideArray must be a mutable struct so that we can get reliable pointers to it's storage in order to avoid interacting with the NTuple data.

However, this causes problems with StaticStrideArrays if they cross non-inlined function boundaries because then the storage data will end up on the heap even if it doesn't need to be there, requiring us to deal with the scariness of PtrArrays @gc_preserve.

One possible solution to this problem would be to have StaticStrideArray be an immutable struct, and then have a MutableStaticStrideArray that can be created from it on-demand in order to get a pointer, and then converted right back to the immutable version as soon as we're done.

Here's a little demo of what I'm imagining:

using StrideArrays, StrideArraysCore
using StrideArraysCore: StaticStrideArray

macro new(T, args...)
    Expr(:new, T, args...) |> esc
end

struct FrozenStaticStrideArray{T, N, R, S, X, O, L} <: AbstractStrideArray{T, N, R, S, X, O}
    data::NTuple{L,T}
end
function freeze(sa::StaticStrideArray{T, N, R, S, X, O, L}) where {T, N, R, S, X, O, L}
    @new FrozenStaticStrideArray{T, N, R, S, X, O, L} getfield(sa, 1)
end
function thaw(fsa::FrozenStaticStrideArray{T, N, R, S, X, O, L}) where {T, N, R, S, X, O, L}
    @new StaticStrideArray{T, N, R, S, X, O, L} getfield(fsa, 1)
end

function Base.getindex(fsa::FrozenStaticStrideArray, i::Int...)
    thaw(fsa)[i...]
end
let
    sa = StaticStrideArray{Float64}(undef, (static(1000),)) .= 1
    fsa = freeze(sa)
    @btime $sa[1000]
    @btime $fsa[1000]
endl

#+RESULTS:
:   1.940 ns (0 allocations: 0 bytes)
:   1.939 ns (0 allocations: 0 bytes)

I think having an immutable variant like this could make this a much more convincing replacement for StaticArrays.jl.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions