-
Notifications
You must be signed in to change notification settings - Fork 151
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
Conversion of SizedArray to Array reshapes #666
Conversion of SizedArray to Array reshapes #666
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do like the constructor changes because they increase consistency with Base
(and also with MArray
). I this is just a bug we are correcting.
I'm less sure about convert
; it looks like Base
doesn't necessarily make a copy here, so we would be justified in only unwrapping. But the fact that SizedArray
is a weird "wrap plus reshape" container (rather than just a wrapper which preserves shape) is kind of unfortunate and forces us to return a reshape
for consistency.
Hmm. Tentatively I think this might be fine to merge as it fixes some obscure bugs and removes what I think is unintended functionality. On the other hand it's technically a breaking change and is a bit of a compatibility trap without a clear way forward for a deprecation warning.
It's possible to get some idea of the usage of SizedArray
by using the code search for pkg.julialang.org: https://pkg.julialang.org/docs/search?q=%5CbSizedArray%5Cb (be sure to click on the "code" tab). From the look of this, there's really not a lot of people using SizedArray
systematically. But there's also the fact that Size
can be used as a constructor which I think might be a misfeature (even if convenient). It's much harder to get a feel for that without a type-inference-aware code search, though https://pkg.julialang.org/docs/search?q=%5CbSize%5C%28%5B%5E%29%5D%2a%5C%29%5C%28 could be an approximation.
src/SizedArray.jl
Outdated
@inline convert(::Type{Array{T,N}}, sa::SizedArray{S,T,N}) where {T,S,N} = sa.data | ||
@inline convert(::Type{Array}, sa::SizedArray{S}) where {S} = Array(reshape(sa.data, size_to_tuple(S))) | ||
@inline convert(::Type{Array{T}}, sa::SizedArray{S,T}) where {T,S} = Array(reshape(sa.data, size_to_tuple(S))) | ||
@inline convert(::Type{Array{T,N}}, sa::SizedArray{S,T,N}) where {T,S,N} = Array(reshape(sa.data, size_to_tuple(S))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that convert
doesn't copy in Base
:
julia> a = [1 2]
1×2 Array{Int64,2}:
1 2
julia> b = convert(Array, a)
1×2 Array{Int64,2}:
1 2
julia> b[1] = 0
0
julia> a
1×2 Array{Int64,2}:
0 2
I'm actually sort of using this feature in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, rather than just letting users discover the shape change "by surprise", how about we check whether size(sa.data) != size_to_tuple(S)
, and if so, emit a depwarn(...)
. Keep this around for one release and then remove it.
It's not a perfect solution (technically not a "full deprecation cycle") but might be ok given that this is relatively obscure functionality.
OK, that sounds reasonable. I doubt anyone actually uses this "functionality" intentionally. |
src/SizedArray.jl
Outdated
@@ -53,11 +61,11 @@ end | |||
@inline convert(::Type{SA}, sa::SA) where {SA<:SizedArray} = sa | |||
|
|||
# Back to Array (unfortunately need both convert and construct to overide other methods) | |||
@inline Array(sa::SizedArray) = sa.data | |||
@inline Array(sa::SizedArray{S}) where {S} = sa.data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should copy though? Also don't need the where {S}
now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll keep this change then. It should copy and Array{T}
should also change the element type, right? But not reshape for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot that these constructors don't change element type, nevermind.
I've changed them so that they make copies. Is this the right set of changes for the next version of StaticArrays.jl
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should also change the element type, right
Hmm, good question actually. I think we'll fail to do the right thing for convert
, because for non-matching eltype we will dispatch to the fallback convert(::Array, ::StaticArray)
? I guess this has been a bug for a while.
This is a subtle and tricky deprecation. I'd appreciate any thoughts from @andyferris who originally implemented Andy — to summarize, the way that So... what to do. One way forward (currently implemented here) is to remove the arbitrary (Side note: I just noticed that our |
I'm totally OK with ditching the ability to reshape an array. That was actually an over-ambitious attempt to step towards hybrid arrays at a time where I was also worried about reshaping and/or nesting things. I probably should have deleted it a while ago... |
I'm trying to port some improvements I've made in
HybridArrays
toSizedArray
here. Full support for wrapping arbitraryAbstractArray
s is a fairly large project and noticeable increase in complexity ofSizedArray
so I'm not sure if it's actually a good idea.Anyway, here is a small change that:
Array
retains given static shape,Array(::SizedArray)
so that it makes a copy (sinceArray(::Array)
also makes one).