-
-
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
Use parent for similar(::PermutedDimsArray) #35304
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.
This is the right thing to do. Re testing, in #35298 I moved some useful array types into test/testhelpers
; if that PR gets merged you could conceivably use TSlow
for testing, since it has a custom similar
method. It has the advantage of being guaranteed not to have any specialized methods written for it other than what's in the test file; the same cannot be said of sparse array types which tend to accumulate an ever-growing number of specializations.
Base.axes(A::PermutedDimsArray{T,N,perm}) where {T,N,perm} = genperm(axes(parent(A)), perm) | ||
|
||
Base.similar(A::PermutedDimsArray, T::Type, dims::Base.Dims) = similar(parent(A), T, dims) |
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.
Since Transpose
and Adjoint
are for linear algebra which we currently support only for arrays with indexing starting with 1, it's OK for those to only support Dims
. But PermutedDimsArray
supports more general array types, so we have to consider the case where similar
will receive axes
rather than dims
input. From
Lines 624 to 645 in 12acd69
similar(a::AbstractArray{T}) where {T} = similar(a, T) | |
similar(a::AbstractArray, ::Type{T}) where {T} = similar(a, T, to_shape(axes(a))) | |
similar(a::AbstractArray{T}, dims::Tuple) where {T} = similar(a, T, to_shape(dims)) | |
similar(a::AbstractArray{T}, dims::DimOrInd...) where {T} = similar(a, T, to_shape(dims)) | |
similar(a::AbstractArray, ::Type{T}, dims::DimOrInd...) where {T} = similar(a, T, to_shape(dims)) | |
# Similar supports specifying dims as either Integers or AbstractUnitRanges or any mixed combination | |
# thereof. Ideally, we'd just convert Integers to OneTos and then call a canonical method with the axes, | |
# but we don't want to require all AbstractArray subtypes to dispatch on Base.OneTo. So instead we | |
# define this method to convert supported axes to Ints, with the expectation that an offset array | |
# package will define a method with dims::Tuple{Union{Integer, UnitRange}, Vararg{Union{Integer, UnitRange}}} | |
similar(a::AbstractArray, ::Type{T}, dims::Tuple{Union{Integer, OneTo}, Vararg{Union{Integer, OneTo}}}) where {T} = similar(a, T, to_shape(dims)) | |
# similar creates an Array by default | |
similar(a::AbstractArray, ::Type{T}, dims::Dims{N}) where {T,N} = Array{T,N}(undef, dims) | |
to_shape(::Tuple{}) = () | |
to_shape(dims::Dims) = dims | |
to_shape(dims::DimsOrInds) = map(to_shape, dims)::DimsOrInds | |
# each dimension | |
to_shape(i::Int) = i | |
to_shape(i::Integer) = Int(i) | |
to_shape(r::OneTo) = Int(last(r)) | |
to_shape(r::AbstractUnitRange) = r |
similar(a::PermutedDimsArray, ::Type{T}, dims::Tuple{Union{Integer, OneTo}, Vararg{Union{Integer, OneTo}}}) where T
similar(a::PermutedDimsArray, ::Type{T}, dims::Dims{N}) where {T,N}
similar(a::PermutedDimsArray, ::Type{T}, axs::Tuple{Union{Integer, AbstractUnitRange}, Vararg{Union{Integer, AbstractUnitRange}}}) 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.
OK, thanks for looking up what's needed, I will add these methods.
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.
Here's what happens if I do add those methods:
using SparseArrays, OffsetArrays
sp = sparse(ones(3,3))
similar(transpose(sp), 3,3)
similar(transpose(sp), 0:2,0:2)
similar(PermutedDimsArray(sp, (2,1)), 3,3) # isa Array
similar(PermutedDimsArray(sp, (2,1)), 0:2,0:2) # OffsetArray(Array)
# initial PR:
Base.similar(A::PermutedDimsArray, T::Type, dims::Base.Dims) = similar(parent(A), T, dims)
similar(PermutedDimsArray(sp, (2,1)), 3,3) # isa SparseMatrixCSC
similar(PermutedDimsArray(sp, (2,1)), 0:2,0:2) # OffsetArray(SparseMatrixCSC)
# add extra methods:
Base.similar(A::PermutedDimsArray, ::Type{T}, dims::Tuple{Union{Integer, Base.OneTo}, Vararg{Union{Integer, Base.OneTo}}}) where T = similar(parent(A), T, dims)
Base.similar(A::PermutedDimsArray, ::Type{T}, axs::Tuple{Union{Integer, AbstractUnitRange}, Vararg{Union{Integer, AbstractUnitRange}}}) where T = similar(parent(A), T, axs)
similar(PermutedDimsArray(sp, (2,1)), 3,3) # isa SparseMatrixCSC
similar(PermutedDimsArray(sp, (2,1)), 0:2,0:2) # is ambiguous. Candidates:
# similar(A::PermutedDimsArray, ::Type{T}, axs::Tuple{Union{Integer, AbstractUnitRange},Vararg{Union{Integer, AbstractUnitRange},N} where N}) where T in Main at REPL[13]:1
# similar(A::AbstractArray, ::Type{T}, inds::Tuple{Union{Colon, Integer, Base.IdentityUnitRange, Base.OneTo, UnitRange, OffsetArrays.IdOffsetRange},Vararg{Union{Colon, Integer, Base.IdentityUnitRange, Base.OneTo, UnitRange, OffsetArrays.IdOffsetRange},N} where N}) where T in OffsetArrays at /Users/me/.julia/packages/OffsetArrays/WmVaB/src/OffsetArrays.jl:102
# Possible fix, define
# similar(::PermutedDimsArray, ::Type{T}, ::Tuple{Union{Integer, Base.IdentityUnitRange, Base.OneTo, UnitRange, OffsetArrays.IdOffsetRange},Vararg{Union{Integer, Base.IdentityUnitRange, Base.OneTo, UnitRange, OffsetArrays.IdOffsetRange},N} where N}) 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.
We need to solve this at the level of OffsetArrays, presumably. JuliaArrays/OffsetArrays.jl#87. I don't have a solution yet but I haven't had time to poke at it (and neither has anyone else, apparently).
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.
That doesn't look easy... but I guess until a larger change lands, this defn is OK?
OK, that looks perfect. I see this replaces a Edit: I see it's merged already. |
Codecov Report
@@ Coverage Diff @@
## master #35304 +/- ##
==========================================
+ Coverage 86.81% 86.83% +0.02%
==========================================
Files 344 344
Lines 63852 63832 -20
==========================================
- Hits 55430 55426 -4
+ Misses 8422 8406 -16
Continue to review full report at Codecov.
|
480a90e
to
753eba6
Compare
Puzzling CI failure. Can you rebase on latest master? |
Done, and mostly green ticks now. |
Thanks for sticking with it, @mcabbott! |
This ensures that
similar
matches the underlying storage of aPermutedDimsArray
wrapper, as happens e.g. forTranspose
, views:I'm not sure how to add a test for this, and don't see any in
test/subarray.jl
for views either. Can I load SparseArrays in the tests for Base?Fixes JuliaGPU/CuArrays.jl#658