-
Notifications
You must be signed in to change notification settings - Fork 152
RFC: Unify SArray,SMatrix,SVector #127
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
Conversation
After the recent refactor something that used to be an SMatrix became a two dimensional SArray (or vice versa - who can keep track). That situation seems unfortunate and unnecessary, so this is an attempt to unify them. This is decently breaking, because it requires the SArray dimension tuple to be e.g. `Tuple{1,2}` rather than `(1,2)`, but should allow us to avoid quite a bit of duplication. These are just the minimal changes to get this running. I would imagine, we could remove some further duplication in follow up patches.
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.
Thanks @Keno for your efforts here.
We've been talking about this approach a lot, in the past and more recently. Before proceeding, I'd appreciate feedback from @JeffBezanson on whether using uninstantiable Tuple
types like Tuple{3,4}
as type parameters is a feature we will continue to support going forward? (In the past I've been bitten by abusing corner cases that happen to work in the current compiler get killed off in the future, e.g. GeneratedTypes comes to mind...). For context, the principle advantage (as I see it) of Tuple{3,4}
over (3,4)
as a type parameter is that you can do subtyping such that SVector{L} <: SArray{Tuple{L}}
(and Tuple
is the only type that has varargs type parameters - it would be sweeter to do this with the Size
trait...). Also, FYI @StefanKarpinski @ararslan - this is the PR discussed on Slack/types.
Also, it seems reasonable to do the same thing for MArray
/MVector
/MMatrix
, as well as incorporating Scalar
into the party. Going forward, we could think about attaching these sizes to StaticArray
also. (I've been rather enjoying the Size
trait - but that would be more workable if we had trait-based dispatch inbuilt into the language).
Any opinions from the rest of the team? @c42f @SimonDanisch @timholy
src/SArray.jl
Outdated
if !(isa(Size, Tuple{Vararg{Int}})) | ||
error("SArray parameter Size must be a tuple of Ints (e.g. `SArray{(3,3)}`)") | ||
@pure tuple_length(T) = length(T.parameters) | ||
@pure tuple_prod(T) = *(T.parameters...) |
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.
Doesn't work for zero-d arrays (I think SArray
was previously broken in this case anyway, but it would ideally be nice to fix and make Scalar
a zero-d SArray
).
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.
Sounds good.
src/SArray.jl
Outdated
error("Internal error. Please file a bug") | ||
end | ||
|
||
@generated function check_sarray_parameters{Size,T,N,L}(::Type{Size}, ::Type{T}, ::Type{Val{N}}, ::Type{Val{L}}) |
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've been moving to where
syntax for parameterized functions (this is of course optional for this PR).
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.
Shoul we parameterize {Size <: Tuple, ...}
here?
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.
Yes, seems reasonable.
@@ -19,56 +19,82 @@ immutable SArray{Size, T, N, L} <: StaticArray{T, N} | |||
data::NTuple{L,T} | |||
|
|||
function (::Type{SArray{Size,T,N,L}}){Size,T,N,L}(x::NTuple{L,T}) |
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.
Ideally, I'd love to remove Size
as a type parameter - there is a trait type called Size
already so this seems a little ambiguous. I'd meant to get around to it earlier. (This is optional w.r.t. this PR).
src/SArray.jl
Outdated
end | ||
end | ||
|
||
@generated function (::Type{SArray{Size}}){Size, T <: Tuple}(x::T) | ||
function SArray{Size,T,N}(x::Tuple) where {Size, T, N} | ||
Base.depwarn("SArray{(dim1,dim2,...),...} is deprecated, use SArray{Tuple{dim1, dim2, ...}, ...}", :SArray) |
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.
Would it be safer to check that Size
is indeed an instance of Tuple{Vararg{Int}}
before this depwarn, and error instead if not?
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.
Maybe. Arguably, this should just be an error immediately. The only concern here would be something that the type system doesn't let you put in Tuples. Happy to go with whatever you prefer.
Yeah, I "simplified" |
@Keno, yesterday you mentioned a type stability issue in some work you were doing. Was this caused by |
No, that's separate, will be a later PR. It's just a bit tricky, so I wanted to get some more experience with that change, so it's not a PR yet. |
Well, let me know if you want some help |
It's worth pointing out that we had a discussion with @JeffBezanson about I feel we can reasonably trust that this will continue working (or else be superseded by something better, like varargs type parameters in user defined types). |
+1 for this change if Jeff thinks the ability to (ab)use In all, it's amusing to see this design quirk of FixedSizeArrays come back again :-) |
Cool. Sounds good then. Just to confirm - @SimonDanisch you also have experience with this approach. A good idea, in your opinion? |
I never regretted it, besides the occasional fights with @JeffBezanson :) |
40f748a
to
ae1772d
Compare
Updated to include MArray/Scalar as well |
Sorry I pushed some other things that are WIP, will back them out and re-push. |
ae1772d
to
594150d
Compare
OK, thanks @Keno - awesome work. One question - would it be beneficial to overload |
end | ||
end | ||
|
||
@inline MArray(a::StaticArray) = MArray{size(typeof(a))}(Tuple(a)) | ||
@inline MArray(a::StaticArray) = MArray{size_tuple(typeof(a))}(Tuple(a)) |
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 think we lost size_tuple
somehow...
After the recent refactor something that used to be an SMatrix became a
two dimensional SArray (or vice versa - who can keep track). That situation
seems unfortunate and unnecessary, so this is an attempt to unify them.
This is decently breaking, because it requires the SArray dimension tuple
to be e.g.
Tuple{1,2}
rather than(1,2)
, but should allow us to avoidquite a bit of duplication. These are just the minimal changes to get this
running. I would imagine, we could remove some further duplication in follow
up patches.