Skip to content
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

RFC: use AbstractMatrix as the eltype of Symmetric for array of arrays #32041

Merged
merged 1 commit into from
Jun 7, 2019

Conversation

JeffBezanson
Copy link
Member

This fixes a crash in the StaticArrays tests on 1.2 and master. It can be reduced to this:

julia> using LinearAlgebra

julia> a = Hermitian([[rand(Complex{Int}) for i = 1 : 2, j = 1 : 2] for row = 1 : 3, col = 1 : 3]);

julia> transpose(a);

The functions symmetric_type and hermitian_type are involved; they are both recursive and call return_type and it seems we just cannot handle it. The eltype of a is currently Union{Array{Complex{Int64},2}, Adjoint{Complex{Int64},Array{Complex{Int64},2}}, Hermitian{Complex{Int64},Array{Complex{Int64},2}}}, which does not seem too useful to me. Here I switch it to AbstractMatrix instead, which works around the problem.

An alternate possible fix is to reduce the complexity of Symmetric and Hermitian getindex. They currently return three different types for diagonal, upper, and lower. I can also fix the crash by reducing this to two. My proposal is to materialize the recursive Symmetric/Hermitian array, removing the third type from Union{S, promote_op(transpose, S), symmetric_type(S)}. That gives a bit more precise type info, but would be more breaking since it changes what getindex returns, while this PR only changes the element type of the Symmetric/Hermitian wrapper.

Any way we can avoid promote_op would be even better, and would also fix it. For example I'd use typeof(transpose(a[1])), and Union{} for empty arrays. But that would break the symmetric_type API, which expects to be able to compute the eltype from just a type.

@JeffBezanson JeffBezanson added the linear algebra Linear algebra label May 15, 2019
@JeffBezanson
Copy link
Member Author

JeffBezanson commented May 17, 2019

I haven't yet figured out why this is crashing (on master, not with this PR). Looking at the exact called objects in gdb, transpose(a) is:

Core.CodeInfo(code=Array{Any, (2,)}[
  Expr(:invoke, (::Type{LinearAlgebra.Transpose{T, S} where S where T})(LinearAlgebra.Hermitian{Union{Array{Base.Complex{Int64}, 2}, LinearAlgebra.Hermitian{Base.Complex{Int64}, Array{Base.Complex{Int64}, 2}}}, Array{Array{Base.Complex{Int64}, 2}, 2}}), LinearAlgebra.Transpose, Core.SlotNumber(id=2)),
  Expr(:unreachable)]

and the MethodInstance/CodeInstance (there's only one inside) called by the invoke is:

  Expr(:new, LinearAlgebra.Transpose{Union{LinearAlgebra.Transpose{Base.Complex{Int64}, Array{Base.Complex{Int64}, 2}}, LinearAlgebra.Transpose{Base.Complex{Int64}, LinearAlgebra.Hermitian{Base.Complex{Int64}, Array{Base.Complex{Int64}, 2}}}}, LinearAlgebra.Hermitian{Union{Array{Base.Complex{Int64}, 2}, LinearAlgebra.Hermitian{Base.Complex{Int64}, Array{Base.Complex{Int64}, 2}}}, Array{Array{Base.Complex{Int64}, 2}, 2}}}, Core.SlotNumber(id=2)),
  Expr(:return, SSAValue(1))]

and it has the expected return type. The type of the invoke in the first function is Union{} though.

@c42f
Copy link
Member

c42f commented Jun 3, 2019

Thanks Jeff. Not knowing much about inference I don't immediately have a lot to add here. The workaround looks reasonable as far as it goes. It would be nice to know the root cause.

Just in case anyone is confused by StaticArrays now passing on 1.2, it's because I added a @skip_test for this case because I'd forgotten about this potential workaround.

@JeffBezanson JeffBezanson added this to the 1.2 milestone Jun 3, 2019
@JeffBezanson JeffBezanson added backport 1.2 and removed triage This should be discussed on a triage call labels Jun 7, 2019
@JeffBezanson JeffBezanson merged commit 7b34f1b into master Jun 7, 2019
@JeffBezanson JeffBezanson deleted the jb/symmetrictype branch June 7, 2019 21:14
KristofferC pushed a commit that referenced this pull request Jun 9, 2019
…#32041)

instead of a 3-element Union type

(cherry picked from commit 7b34f1b)
@KristofferC KristofferC mentioned this pull request Jun 9, 2019
32 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linear algebra Linear algebra
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants