-
Notifications
You must be signed in to change notification settings - Fork 8
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
freeze/thaw
interface for StaticStrideArray
s
#37
Comments
I am in favor, please feel free to make a PR! @ChrisRackauckas and I have been talking for some time about making a I'm also in favor of making StrideArrays(Core) that library. It should perhaps also be updated to make use of the new Pkg extensions. |
Hm, it seems that julia is being a bit overly cautious about avoiding us mutating a region of stack memory that belonged to an immutable variable, so a julia> let v = StrideArray{Float64}(undef, static(1000)) .= 1
fv = freeze(v)
@btime freeze($(thaw(fv)))
end;
153.136 ns (0 allocations: 0 bytes)
julia> let v = StrideArray{Float64}(undef, static(1000)) .= 1
fv = freeze(v)
code_llvm(Tuple{typeof(fv)}) do fv
freeze(thaw(fv))
end
end;
; @ REPL[8]:4 within `#3`
define void @"julia_#3_2881"([1 x [1000 x double]]* noalias nocapture sret([1 x [1000 x double]]) %0, [1 x [1000 x double]]* nocapture nonnull readonly align 8 dereferenceable(8000) %1) #0 {
top:
; ┌ @ REPL[5]:2 within `freeze`
%.sroa.0.0..sroa_cast = bitcast [1 x [1000 x double]]* %1 to i8*
%2 = bitcast [1 x [1000 x double]]* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 8 dereferenceable(8000) %2, i8* noundef nonnull align 8 dereferenceable(8000) %.sroa.0.0..sroa_cast, i64 8000, i1 false)
; └
ret void
} Not a show-stopper, but having a cost to freezing and thawing does put a damper on things... |
Yes, we're aware of that problem. A few people looked at it and couldn't come up with simple fixes, but we think it's still worth it despite this cost (and eventually, compiler improvements should eliminate that copy). |
Okay, I'll see what I can do. What is your appetite here for a breaking version? I'm picturing replacing what is currently function StrideArray{T}(::UndefInitializer, sz::StaticInt...) where {T}
r = Ref{NTuple{Int(prod(sz)), T}}
p = Ptr{T}(pointer_from_objref(r))
pA = PtrArray(p, sz)
return StrideArray(pA, r)
end and then the name |
I'm okay with a breaking version, as there's only a handful of packages I maintain depending on this, and none use
I want the array passed as a pointer to memory, not a pointer to a pointer to memory. I had it closer to what you described before, but this caused a slight loss in performance. |
I think I made an issue for this in ArrayInterface a while ago |
How would this be different from a
Sorry, I don't remember. Could have been Zulip. |
It wouldn't be backed by a |
Ah right, of course. Thanks @MasonProtter |
Currently, a
StaticStrideArray
must be amutable struct
so that we can get reliable pointers to it's storage in order to avoid interacting with theNTuple
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 immutablestruct
, and then have aMutableStaticStrideArray
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:
I think having an immutable variant like this could make this a much more convincing replacement for StaticArrays.jl.
The text was updated successfully, but these errors were encountered: