Skip to content

Unreachable reached #30122

@alyst

Description

@alyst

I hit "Unreachable reached" error with Julia 1.0.2 on Archlinux, then I tried backports-1.0.3 branch, assuming that #29986 will fix the problem, but it's still there.
Unfortunately, I don't have a small reproducible test case: it happens when I try to run the ]test BlackBoxOptim using pareto_rtree branch, which requires SpatialIndexing master (not yet in Julia registry).

Here's the log:

              _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.0.3-pre.29 (2018-11-19)
 _/ |\__'_|_|_|\__'_|  |  makepkg/33a5d6a2d9* (fork: 316 commits, 105 days)
|__/                   |

julia> versioninfo()
Julia Version 1.0.3-pre.29
Commit 33a5d6a2d9* (2018-11-19 15:19 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-6.0.0 (ORCJIT, skylake)

(v1.0) pkg> test BlackBoxOptim
   Testing BlackBoxOptim
 Resolving package versions...
    Status `/tmp/tmpZWmfd8/Manifest.toml`
....

[ Info: subtract!(): region=BlackBoxOptim.DominanceCone{Int64,2,true}((22, 11))
[ Info: subtract!(): region=BlackBoxOptim.DominanceCone{Int64,2,true}((32, 11))
[ Info: _subtract!(): lev=0 i=0 len=1
[ Info: _subtract!(): delete subtree lev=0 i=0 len=1
[ Info: delete_subtree(): lev=0
[ Info: _delete_subtree(): empty children (1 objs) of node lev=0 parent=false
[ Info: _delete_subtree(): done node lev=0 parent=false
[ Info: _subtract!(): delete subtree done lev=0 i=0 len=0, returning 1
Unreachable reached at 0x7f8e4dabf335

signal (4): Illegal instruction
in expression starting at /home/ge68wan/.julia/dev/BlackBoxOptim/test/test_epsbox_archive.jl:1
subtract! at /home/ge68wan/.julia/dev/SpatialIndexing/src/rtree/delete.jl:65
add_candidate! at /home/ge68wan/.julia/dev/BlackBoxOptim/src/archives/epsbox_archive.jl:235
add_candidate! at /home/ge68wan/.julia/dev/BlackBoxOptim/src/archives/epsbox_archive.jl:262 [inlined]
add_candidate! at /home/ge68wan/.julia/dev/BlackBoxOptim/src/archives/epsbox_archive.jl:262
unknown function (ip: 0x7f8e4dad9d35)
jl_fptr_trampoline at /usr/bin/../lib/libjulia.so.1 (unknown line)
jl_apply_generic at /usr/bin/../lib/libjulia.so.1 (unknown line)
macro expansion at /home/ge68wan/.julia/dev/BlackBoxOptim/test/test_epsbox_archive.jl:50 [inlined]
macro expansion at /home/ge68wan/aur/julia-git/src/julia/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:1083 [inlined]
macro expansion at /home/ge68wan/.julia/dev/BlackBoxOptim/test/test_epsbox_archive.jl:32 [inlined]
macro expansion at /home/ge68wan/aur/julia-git/src/julia/usr/share/julia/stdlib/v1.0/Test/src/Test.jl:1083 [inlined]
top-level scope at /home/ge68wan/.julia/dev/BlackBoxOptim/test/test_epsbox_archive.jl:4
jl_fptr_trampoline at /usr/bin/../lib/libjulia.so.1 (unknown line)
....

Here's the code in question:

function subtract!(tree::RTree{T,N}, reg::Region{T,N}) where {T,N}
    @info "subtract!(): region=$(reg)"
    isempty(tree) && return tree

    tmpdetached = Vector{nodetype(tree)}()
    status = _subtract!(tree.root, 0, reg, tree, tmpdetached)
    @info "_subtract!(root) done"
    @show status
    @show typeof(tmpdetached) length(tmpdetached)
    @info "subtract!(): status=$(status) tmpdetached=$(length(tmpdetached))"
    if status == 1 # tree changed, but not removed
        _condense!(tree.root, tree, tmpdetached) # try to condense the root
    elseif status == 2 # whole tree removed
        @assert isempty(tree)
        @assert isempty(tmpdetached)
    end
    _reinsert!(tree, tmpdetached)
    return tree
end

function _subtract!(node::Node, node_ix::Int, reg::Region, tree::RTree,
                    tmpdetached::AbstractVector{<:Node})
    nodembr = mbr(node)
    @info "_subtract!(): lev=$(level(node)) i=$node_ix len=$(length(node))"
    # FIXME juxtaposition() method that combines in() and intersects()?
    if in(nodembr, reg)
        @info "_subtract!(): delete subtree lev=$(level(node)) i=$node_ix len=$(length(node))"
        delete_subtree!(tree, node)
        @info "_subtract!(): delete subtree done lev=$(level(node)) i=$node_ix len=$(length(node)), returning 1"
        return 2 # node removed
    elseif intersects(nodembr, reg)
        mbr_dirty = false
        i = 1
        while i <= length(node)
            #@debug "1: lev=$(level(node)) i=$i len=$(length(node))"
            child = node[i]
            oldmbr = mbr(child)
            if node isa Branch
                child_res = _subtract!(child, i, reg, tree, tmpdetached)
            else
                @assert node isa Leaf
                if in(oldmbr, reg)
                    @info "_subtract!(): detach elem lev=$(level(node)) i=$i len=$(length(node))"
                    _detach!(node, i, tree, updatembr = false) # don't update MBR, we do it later
                    tree.nelems -= 1
                    tree.nelem_deletions += 1
                    child_res = 2
                    # FIXME intersect is not considered (would be important if elem mbr is not a point), should be handled by `filter`
                else
                    child_res = 0
                end
            end
            if !mbr_dirty && (child_res != 0) && tree.tight_mbrs
                mbr_dirty = touches(nodembr, oldmbr)
            end
            if child_res != 2 # don't increment if i-th node removed
                i += 1
            end
        end
        if hasparent(node) && length(node) < floor(Int, tree.reinsert_factor * capacity(node, tree))
            _detach!(parent(node), node_ix, tree)
            tree.nnodes_perlevel[level(node)+1] -= 1
            push!(tmpdetached, node)
            return 2 # node removed
        elseif mbr_dirty
            syncmbr!(node)
            return 1 # mbr changed
        else
            return 0 # no mbr change
        end
    else
        return 0 # no change
    end
end

It looks like the error happens immediately before/after _subtract!() returns to subtract!().

I think it's related to the concrete types of the RTree and Node, because this code runs fine in SpatialIndexing tests (nodetype(tree) = SpatialIndexing.Node{Float64,3,SpatialElem{Float64,3,Int64,String}}), but fails when (nodetype(tree) = SpatialIndexing.Node{Int64,2,BlackBoxOptim.FrontierIndividual{BlackBoxOptim.IndexedTupleFitness{2,Float64}}}).
Since it looks like it's type-related, I thought that it might be similar to #30067.

Metadata

Metadata

Assignees

Labels

bugIndicates an unexpected problem or unintended behaviortypes and dispatchTypes, subtyping and method dispatch

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions