-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add optimized implementations of reduce([hv]cat, A) #27188
Conversation
base/abstractarray.jl
Outdated
@@ -1188,7 +1188,9 @@ typed_hcat(::Type{T}, X::Number...) where {T} = hvcat_fill(Matrix{T}(undef, 1,le | |||
vcat(V::AbstractVector...) = typed_vcat(promote_eltype(V...), V...) | |||
vcat(V::AbstractVector{T}...) where {T} = typed_vcat(T, V...) | |||
|
|||
function typed_vcat(::Type{T}, V::AbstractVector...) where T | |||
AbstractVecOrTuple{T} = Union{AbstractVector{<:T}, Tuple{Vararg{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.
Whoa, crazy — this works? You can make a type covariant through an alias?
In any case, I think I'd prefer doing this the other way around — I saw A::AbstractVecOrTuple{AbstractVecOrMat}
and assumed it was an invariance bug. That is:
AbstractVecOrTuple{T} = Union{AbstractVector{T}, Tuple{Vararg{T}}}
# and
_typed_hcat(::Type{T}, A::AbstractVecOrTuple{<:AbstractVecOrMat}) where 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.
Good point. Unfortunately, I get a bootstrap error if I add <:
in the method signatures instead (whether I also change <:T
to T
in the type alias or not). That's weird since I cannot reproduce at the REPL. Maybe that's a dispatch bug.
REPL ────────────────── 17.461338 seconds
error during bootstrap:
LoadError("sysimg.jl", 213, LoadError("/home/milan/Dev/julia/usr/share/julia/stdlib/v0.7/Pkg3/src/Pkg3.jl", 32, LoadError("/home/milan/Dev/julia/usr/share/julia/stdlib/v0.7/Pkg3/src/Types.jl", 45, MethodError(Base._typed_vcat, (UInt8, (UInt8[0xc8, 0x30, 0xd4, 0x4f, 0xc0, 0x00, 0xb4, 0x80, 0xd1, 0x11, 0xad, 0x9d, 0x10, 0xb8, 0xa7, 0x6b], UInt8[0x6a, 0x75, 0x6c, 0x69, 0x61, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67])), 0x00000000000067bb))))
rec_backtrace at /home/milan/Dev/julia/src/stackwalk.c:94
record_backtrace at /home/milan/Dev/julia/src/task.c:246
jl_throw at /home/milan/Dev/julia/src/task.c:577
jl_method_error_bare at /home/milan/Dev/julia/src/gf.c:1608
jl_method_error at /home/milan/Dev/julia/src/gf.c:1626
jl_apply_generic at /home/milan/Dev/julia/src/gf.c:2117
typed_vcat at ./abstractarray.jl:1271
vcat at ./abstractarray.jl:1189 [inlined]
uuid5 at /home/milan/Dev/julia/usr/share/julia/stdlib/v0.7/Pkg3/src/Types.jl:36
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.
My hunch would be an ambiguity error?
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.
Yeah but as I said I can't reproduce when pasting the definitions directly at the REPL.
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.
Filed as #27224.
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
AbstractVecOrTuple{T} = Union{AbstractVector{<:T}, Tuple{Vararg{T}}}
be declared const
?
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.
If there is a parameter it doesn't matter. Personally I always put const for consistent.
These shouldn't really be being done to |
AFAIK these functions are associative and that's the only difference between |
Oh you are right, associativity is all that is required. With that said applying these to |
For triage: I'd like to get this into 0.7 since it's a very frequent issue, but I can't remove the weird type alias until #27224 is fixed. Is that such a big problem, given that it's internal? |
Seems fine to me. @JeffBezanson? |
The type alias doesn't bother me. But it seems it could also just be removed, since it's only used to restrict the argument type of an internal function. |
Yeah, Milan tried that but ran into #27188 (comment). I'm fine with this if you are — the only reason I've not merged this earlier is because I was unsure about the behaviors of that typealias. |
It seems like using a sketchy type alias for the signature of a purely internal function to avoid ambiguity is fine... if it breaks in the future, we can fix it then. Maybe leave a FIXME/TODO note? |
Fair enough, I've added a FIXME. |
That's not really what I meant; there are other solutions too. But it doesn't matter. |
It's great that this feature exists, but it's not very discoverable. The docs currently recommend |
Yes, the docs for The documentation is in https://github.com/JuliaLang/julia/blob/master/base/abstractarray.jl, so you can just click the edit button at upper right to add in an example and submit a PR. |
Fixes #21672.
This implements the minimal fix for
AbstractVector{<:Union{AbstractVector,AbstractMatrix}}
. It doesn't cover the case ofVector{Any}
list of vectors or matrices, which could be useful to support given that it is not uncommon to store expensive objects like arrays inVector{Any}
lists. For example, it appears that JSON.jl returns such objects. This could be done by passingmapreduce(typeof, typejoin, A)
to an internal function which can then dispatch on the argument type, with a fallback on the normalreduce
method. But it's more complex and can introduce ambiguities.