-
-
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
Make transposes of StridedArrays strided #29135
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.
Would it be at all beneficial to use reverse(strides(parent(A)))
?
Sure enough: julia> t = transpose(rand(3,4));
julia> s1(A) = (stride(A.parent, 2), stride(A.parent, 1))
s2(A) = reverse(strides(A.parent))
s2 (generic function with 1 method)
julia> @btime s1($t)
7.056 ns (0 allocations: 0 bytes)
(3, 1)
julia> @btime s2($t)
2.032 ns (0 allocations: 0 bytes)
(3, 1) |
Oh wait, that won't quite do it because of transposed vectors… should have actually tested it more thoroughly locally. |
_adjoint_strides((a,)) = (a,1)
_adjoint_strides((a,b)) = (b,a)
strides(A::Adoint) = _adjoint_strides(strides(parent(A))) |
The answer for strided vectors is neither (I believe the correct answer is |
Let's re-run CI and get this in. |
Perhaps related, |
Yes, I think we could add |
Shouldn't it follow |
Ah, yes, I had forgotten I did that. That's perfect. |
5dc0bf3
to
ce847fd
Compare
@@ -186,6 +186,16 @@ IndexStyle(::Type{<:AdjOrTransAbsMat}) = IndexCartesian() | |||
convert(::Type{Adjoint{T,S}}, A::Adjoint) where {T,S} = Adjoint{T,S}(convert(S, A.parent)) | |||
convert(::Type{Transpose{T,S}}, A::Transpose) where {T,S} = Transpose{T,S}(convert(S, A.parent)) | |||
|
|||
# Strides and pointer for transposed strided arrays — but only if the elements are actually stored in memory | |||
Base.strides(A::Adjoint{<:Real, <:StridedVector}) = (stride(A.parent, 2), stride(A.parent, 1)) |
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 should not restrict to <: StridedVector
. The strided array interface means other array types should be supported.
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, I fully agree, but this is intended as a stopgap and not a full solution.
FYI In ArrayLayouts.jl I came up with the following way to deal with the complex adjoint pointer issue: introduce """
ConjPtr{T}
represents that the entry is the complex-conjugate of the pointed to entry.
"""
struct ConjPtr{T}
ptr::Ptr{T}
end
unsafe_convert(::Type{Ptr{T}}, A::Adjoint{<:Real}) where T<:Real = unsafe_convert(Ptr{T}, parent(A))
unsafe_convert(::Type{Ptr{T}}, A::Transpose) where T = unsafe_convert(Ptr{T}, parent(A))
# work-around issue with complex conjugation of pointer
unsafe_convert(::Type{Ptr{T}}, Ac::Adjoint{<:Complex}) where T<:Complex = unsafe_convert(ConjPtr{T}, parent(Ac))
unsafe_convert(::Type{ConjPtr{T}}, Ac::Adjoint{<:Complex}) where T<:Complex = unsafe_convert(Ptr{T}, parent(Ac))
function unsafe_convert(::Type{ConjPtr{T}}, V::SubArray{T,2}) where {T,N,P}
kr, jr = parentindices(V)
unsafe_convert(Ptr{T}, view(parent(V)', jr, kr))
end |
ce847fd
to
7d1cf61
Compare
but only in cases where the transpose is actually stored in memory.
8aa480a
to
9819783
Compare
Bump, for 1.5? |
So was this discussed on the triage call? I really don't think it should be all that controversial — the only controversial thing is how minimally I've scoped it in an effort to keep in uncontroversial. |
Your call, @mbauman. |
Let's do this then. Part of the reason it's scoped so narrowly is to ensure we have space to move towards traits or whatever the bigger solution turns out to be. |
but only in cases where the transpose is actually stored in memory.