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

Unreachable reached once again #31115

Closed
mortenpi opened this issue Feb 20, 2019 · 10 comments
Closed

Unreachable reached once again #31115

mortenpi opened this issue Feb 20, 2019 · 10 comments
Assignees
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@mortenpi
Copy link
Contributor

Getting the following "Unreachable reached" error on master (1.0, 1.1 are fine) with Atoms.jl:

Unreachable reached at 0x7fc5069158f2

signal (4): Illegal instruction
in expression starting at /home/mortenpi/Projects/atomicjulia/2019-02-17/bisect.jl:19
foo at /home/mortenpi/Projects/atomicjulia/2019-02-17/bisect.jl:17
jl_fptr_trampoline at /home/mortenpi/Julia/julia/src/gf.c:1892
jl_apply_generic at /home/mortenpi/Julia/julia/src/gf.c:2247
do_call at /home/mortenpi/Julia/julia/src/interpreter.c:323
...

Unfortunately, I was not able to reduce it down to a nice MWE, but instantiating the environment and running the bisect.jl file in this gist should reproduce it consistently.

Bisect blames e456a72 from #30577 (cc @JeffBezanson).

cc @jagot

@Keno Keno self-assigned this Feb 21, 2019
@Keno
Copy link
Member

Keno commented Feb 22, 2019

Having looked at this, I think the bisect is a red herring and just enabled a bit more type info that exposed the bug. I think the underlying issue is a type intersection bug. WIP:

julia> atype
Tuple{getfield(Core, Symbol("#kw#Type")),NamedTuple{(:w′,),_A} where _A,Type{CoulombIntegrals.PoissonProblem},Int64,ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s12} where #s12<:(LazyArrays.Mul{#s13,#s14} where #s14<:(Tuple{#s15,#s16} where #s16<:(AbstractArray{T,1} where T) where #s15<:B) where #s13<:Tuple) where B where T,ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s12} where #s12<:(LazyArrays.Mul{#s13,#s14} where #s14<:(Tuple{#s15,#s16} where #s16<:(AbstractArray{T,1} where T) where #s15<:B) where #s13<:Tuple) where B where T}

julia> min_valid = UInt[typemin(UInt)]
1-element Array{UInt64,1}:
 0x0000000000000000

julia> max_valid = UInt[typemax(UInt)]
1-element Array{UInt64,1}:
 0xffffffffffffffff

julia> Base._methods_by_ftype(atype, 4, typemax(UInt), min_valid, max_valid)
1-element Array{Any,1}:
 svec(Tuple{getfield(Core, Symbol("#kw#Type")),NamedTuple{(:w′,),_A} where _A,Type{CoulombIntegrals.PoissonProblem},Int64,RO₁,RO₁} where RO₁<:(ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s12} where #s12<:(LazyArrays.Mul{#s29,Union{}} where #s29<:Tuple)) where T, svec(T, B<:(ContinuumArrays.QuasiArrays.AbstractQuasiArray{T,2} where T), RO₁<:RO₁<:(ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s12} where #s12<:(LazyArrays.Mul{#s29,Union{}} where #s29<:Tuple))), (::getfield(Core, Symbol("#kw#Type")))(::Any, ::Type{CoulombIntegrals.PoissonProblem}, k::Int64, u::RO₁, v::RO₁) where {T, B<:(ContinuumArrays.QuasiArrays.AbstractQuasiArray{T,2} where T), RO₁<:(ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s30} where #s30<:(LazyArrays.Mul{#s29,#s28} where #s28<:(Tuple{B,#s27} where #s27<:(AbstractArray{T,1} where T)) where #s29<:Tuple))} in CoulombIntegrals)

I don't think those Union{}s in there are correct.

@Keno
Copy link
Member

Keno commented Feb 22, 2019

Reduction for that method match:

f(::Any, a::R) where {T, B<:CoulombIntegrals.AbstractQuasiMatrix, R<:CoulombIntegrals.RadialOrbital{T,B}} = 1
atype = Tuple{typeof(f), Type{Atoms.PoissonProblem}, Atoms.RadialOrbital{T,B} where T where B}
methds = Base._methods_by_ftype(atype, 1, typemax(UInt))

Interestingly, the Type argument is required for things to go haywire.

@vtjnash
Copy link
Sponsor Member

vtjnash commented Feb 22, 2019

I attempted to make this somewhat smaller:

julia> T = Tuple{Val{<:Val{<:Tuple{B,AbstractVector{T}}}} where B where T}
Tuple{Val{#s2} where #s2<:(Val{#s1} where #s1<:Tuple{B,AbstractArray{T,1}}) where B where T}

julia> S = Tuple{RO} where RO<:Val{<:Val{<:Tuple{B,<:AbstractArray}}} where B<:Matrix
Tuple{RO} where RO<:(Val{#s3} where #s3<:(Val{#s2} where #s2<:(Tuple{B,#s1} where #s1<:AbstractArray))) where B<:(Array{T,2} where T)

julia> typeintersect(T, S)
Tuple{RO} where RO<:(Val{#s2} where #s2<:Val{Union{}})

but I think that Union{} is correct, and is simply resulting from

typeintersect(Val{<:Vector}, Val{<:Matrix}) = Val{Union{}}

@Keno
Copy link
Member

Keno commented Feb 22, 2019

Ok, but the plain type intersection, doesn't show the Union{}, and it also doesn't show up when the first argument is omitted:

julia> typeintersect(first(methods(f)).sig, atype)
Tuple{typeof(f),Type{PoissonProblem},R} where R<:(ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s30} where #s30<:(LazyArrays.Mul{#s13,#s14} where #s14<:(Tuple{#s15,#s16} where #s16<:(AbstractArray{T,1} where T) where #s15<:(ContinuumArrays.QuasiArrays.AbstractQuasiArray{T,2} where T)) where #s13<:Tuple)) where T

so something is definitely strange.

@Keno
Copy link
Member

Keno commented Feb 22, 2019

And in particular, the thing that method matching returns is too small:

julia> Base._methods_by_ftype(atype, 1, typemax(UInt))[1][1] <: typeintersect(first(methods(f)).sig, atype)
true

julia> typeintersect(first(methods(f)).sig, atype) <: Base._methods_by_ftype(atype, 1, typemax(UInt))[1][1]
false

julia> Base._methods_by_ftype(atype, 1, typemax(UInt))[1][1]
Tuple{typeof(f),Type{PoissonProblem},R} where R<:(ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s12} where #s12<:(LazyArrays.Mul{#s29,Union{}} where #s29<:Tuple)) where T

@Keno
Copy link
Member

Keno commented Feb 22, 2019

@vtjnash points out that reversing the order of the arguments to the type intersect, gives the incorrect result we see from the method matcher:

julia> typeintersect(atype, first(methods(f)).sig)
Tuple{typeof(f),Type{PoissonProblem},R} where R<:(ContinuumArrays.QuasiArrays.MulQuasiArray{T,1,#s12} where #s12<:(LazyArrays.Mul{#s29,Union{}} where #s29<:Tuple)) where T

@Keno Keno added the types and dispatch Types, subtyping and method dispatch label Feb 22, 2019
@Keno
Copy link
Member

Keno commented Feb 22, 2019

Just noting as an FYI here that @JeffBezanson is currently on vacation, so resolution might take another week or so.

@JeffBezanson
Copy link
Sponsor Member

Interestingly, the Type argument is required for things to go haywire.

FYI, I believe this is because it makes one type not a subtype of the other, so we have to switch to the full intersection algorithm (if A<:B we just return A).

@JeffBezanson
Copy link
Sponsor Member

Possible reduced case that also happens going back to 0.6:

julia> A = Tuple{Ref{Z} where Z<:(Ref{Y} where Y<:Tuple{<:B}), Int} where B;

julia> B = Tuple{Ref{Z} where Z<:(Ref{Y} where Y<:Tuple{  B}), Any} where B<:AbstractMatrix;

julia> typeintersect(A,B)
Tuple{Ref{Z} where Z<:Ref{Union{}},Int64}

Changing <:B in A to just B works though.

@jagot
Copy link
Contributor

jagot commented Mar 5, 2019

Thanks for the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

5 participants