-
Notifications
You must be signed in to change notification settings - Fork 9
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
getindex(.) return type does not match eltype #2
Comments
Thanks! Yes, the I definitely want to solve that, but it's a bit tricky - just using the underlying array type as |
There's also this problem: If we just make |
Just to pitch in (as this was brought up in JuliaArrays/StructArrays.jl#84), I think that changing the eltype should be done not by adding a custom |
I fully agree, @piever. That's what makes it a bit more tricky - but I have an idea (like you said, via constructor), I'll try it out. |
Update: Haven't forgotten about this, just had to be put on hold for some other urgent work. Will get back on this soon. |
Sorry this is taking so long - it's not forgotten and definitely still on my to-do list! |
@oschulz no worries, I actually figured this out and have been using it in my own codebases: # For AbstractArray A and indices I, compute V = typeof(view(A, I...)) by:
# 1) Try to infer V from typeof(A) and typeof(I) by calling viewtype(typeof(A), typeof(I))
# 2) If !isconcretetype(V), fall back to typeof(view(A, I...))
# Custom subtypes of AbstractArray (e.g. UnsafeArray) could provide customized implementations
# of viewtype(A::AbstractArray, I::Tuple) or viewtype(::Type{<:AbstractArray}, ::Type{<:Tuple})
# if required.
function viewtype(A::AbstractArray, I::Tuple)
T = viewtype(typeof(A), typeof(I))
_viewtype(A, I, T, Val(isconcretetype(T)))
end
viewtype(A::AbstractArray, I...) = viewtype(A, I)
function viewtype(::Type{A}, ::Type{I}) where {A<:AbstractArray,I<:Tuple}
Core.Compiler.return_type(view, _view_signature(A, I))
end
Base.@pure _view_signature(::Type{A}, ::Type{I}) where {A,I<:Tuple} = Tuple{A, I.parameters...}
_viewtype(A, I, T, ::Val{true}) = T
function _viewtype(A, I, T, ::Val{false})
try
return typeof(view(A, I...))
catch e
Istring = join(map(string, I), ", ")
printstyled(stderr,
"""
Unable to infer typeof(view($(typeof(A)), $(join(map(i -> string(typeof(i)), I), ", "))))
Only other option is to try typeof(view(A, $Istring)) but that resulted in below error.
Try passing in valid indices or implement:
viewtype(::Type{$(typeof(A))}, ::Type{$(typeof(I))})
""", color=:light_red)
rethrow(e)
end
end I've got an in-works implementation something similar to Thanks again for keeping on top of this! :) |
Also, two other options for _viewtype(A, I, T, ::Val{false}) = @inbounds view(A, I...)
@propagate_inbounds _viewtype(A, I, T, ::Val{false}) = view(A, I...) The first has the benefit of working for empty arrays, but that seems unsafe. The second option |
Thanks, I really got to add this soon! |
As an alternate idea, you could use the I ended up needing the ability to slice along arbitrary dimensions instead just the inner function sliceinner(A::AbstractArray{<:Any,L}, ::Val{M}) where {L,M}
slice(A, ntuple(_ -> Colon(), Val(M))..., ntuple(_ -> *, Val(L-M))...)
end You could also use JuliennedArrays directly, As an aside, you might find some of the test utilities I wrote useful, given that you have a lot of packages providing various custom arrays. That test suite is what originally prompted the changes to ElasticArrays I made in JuliaArrays/ElasticArrays.jl#20. Perhaps factoring that out to something like |
Hm, since ArraysOfArrays is already registered, and since there would be conflicts with some exported functions (like
Yes, that might indeed be very useful! |
Makes sense to backport the changes In the meantime, I'll work on factoring out ArrayTestTools.jl. |
It makes me so happy when I find out people are reading my packages! Happy to accept PRs to JuliennedArrays |
@bramtayl, I just came across JuliennedArrays a while ago - from what I saw, it's quite similar to Would you possibly be interested in moving it into |
@colinxs having a @inline flatview(A::AbstractArray{<:AbstractArray}) = Base.Iterators.flatten(A) with something that actually returns an |
@oschultz I'd be thrilled to move it into ArraysOfArrays so I don't have to maintain the code anymore. I'd be curious to know more about performance differences |
hahah and I love when devs are super responsive and eager to accept PRs :). @bramtayl, when you have a moment want to look over SlicedArray and FlattenedArray. The major changes are:
|
Concerning the performance difference: there isn't any. All of the fancy indexing that allows slicing along arbitrary dimensions effectively compiles out. |
@colinxs those all sound like improvements to me. Earlier versions of JuliennedArrays used |
Haha, and here I thought we'd maintain it together. ;-)
Good point, we should definitely do some benchmarking! |
Regarding |
Oh, that would be nice to have here (ArraysOfArrays) too! |
@bramtayl julia> A=rand(2,3)
2×3 Array{Float64,2}:
0.307533 0.822543 0.530326
0.591914 0.782564 0.948809
julia> B=PermutedDimsArray(A, (2,1))
3×2 PermutedDimsArray(::Array{Float64,2}, (2, 1)) with eltype Float64:
0.307533 0.591914
0.822543 0.782564
0.530326 0.948809
julia> A[1,2] == B[2,1]
true So if you had |
Oh I see. Yes that makes sense to me. I'm not sure if there would be a performance penalty for |
I thought about doing the same thing, but you miss out on some optimizations with the extra layer of indirection. If we had: A = rand(2,3,4)
B = slice(A, :, *, *) Then doing If you rely on |
|
I like But in your example above - |
Thanks for writing the summary! |
I would strongly favor using the optimal return type for each case, as long as it can be done in a type-stable way. So if appropriate, |
Of course, done. I think you should now be able to add collaborators and manage all the things. |
Haven't gotten around to making the PRs yet as I'm cleaning things up in SpecialArrays.jl first, but I wanted to give an update on the replacement for |
Just commented there. Sorry, I don't check slack very often. |
No, sorry, missed it - I'm an intermittent slacker ... :-) |
@colinxs, looks like a bug in ArraysOfArrays, can you open an issue an repost your comment from slack? |
@oschulz done! Concerning the merging of SpecialArrays/JuliennedArrays: Given that we all appear to be fairly busy, I think it's easiest for everyone if SpecialArrays is merged into JuliennedArrays. ArraysOfArrays has many moving parts and is quite different, while SpecialArrays/JuliennedArrays are effectively the same thing, just implemented a bit differently. Given that @bramtayl has been working on the challenges of type stable "dimension surgery" (Brandon I think I've read damn near every issue you've commented on), he may also be able to better maintain/push forward the whole @oschulz, given that you have many packages depending on ArraysOfArrays, this may also make things easier for you. If everyone is alright with this I'll make a PR this weekend. There's two registered packages depending on JuliennedArrays, both of which have compat entries upper bounding it to |
Im sorry you had to suffer through them!
Sure! |
Sure, I guess that's maybe the fastest route for you
Not that many, but those do need it - I'd be fine to adapt to API changes, though. I just needed the statistics support, but I believe that's now fully compatible with Statistics/StatsBase, semantically. Maybe longer term, we can still converge? Until then, it would be nice if we could avoid conflicts between exported functions (e.g. |
@bramtayl no worries, it was educational! I'll go ahead and make one big PR then and we can disect from there. I definitely see things converging in the future! Right now there's a ton of packages with similar goals (RecursiveArrayTools, SliceMap, StarSlice, etc.) but I think the diversity has lead to better ideas (e.g. I may not have made SpecialArrays if both ArraysOfArrays and JuliennedArrays didn't already exist).
Sorry for all the trouble! |
"RecursiveArrayTools" is actually almost fully orthogonal - from what I understand, it's purpose access nested array with a flat-array-like API. So kinda the reverse from what he do, actually. |
Yup, it's purpose is definitely nested-->flat, but that's just the inverse of flat->nested. As the JuliaennedArrays/SpecialArrays code shows they share quite a bit in common. |
@colinxs , as a first step in that direction, how would you feel about publishing your |
@oschulz I think it's easiest to keep it with
Note that Zygote is loaded with Requires. Still haven't made the PR into JuliennedArrays, I've been cleaning things up on my end before :) |
Sure, sounds good. Maybe ArraysOfArray can depend on JuliennedArrays then for a while, until we come up with a plan to converge everything. |
Sounds good! I haven't yet made the PR to JuliennedArrays, but did just finish cleaning/simplifying a bunch of things in Lyceum/SpecialArrays.jl#2. I'll make the PR this weekend and we can chat specifics there :) cc: @bramtayl |
I think that efficient arrays-of-arrays data structure could become very relevant in the future, since with Julia v1.5, views become very cheap. Here are some benchmarks: JuliaArrays/UnsafeArrays.jl#8 |
bump, the future is now! Let's do Jim's (future) work for him |
I wrote to Jim last night, letting him know that we already have it :-) |
AK supports n-jaggedness so we're still some distance away, btw, I definitely reinvented StructArray in UnROOT.jl: |
Do you mean vectors of vectors of [...] of arrays? |
Do you think it would be possible to use |
let's see if we survive into longer-term... but yes that's definitely something worth trying |
First off, awesome idea/package! It's been quite useful in my own work.
I was really excited to use your package in conjunction with StructArrays but ran into an issue (that I attempted to fix with a PR to StructArrays) as explained here. The owner of that package pointed out, however, that the real issue is the following:
What are your thoughts on modifying eltype to be consistent with the true return type of getindex?
-Colin
The text was updated successfully, but these errors were encountered: