BlockArrays.jl icon indicating copy to clipboard operation
BlockArrays.jl copied to clipboard

Handle empty blocks upon `motar`

Open lassepe opened this issue 2 years ago • 3 comments

I just ran into the following behavior (due to another bug in my own code):

julia> a = mortar(Bool[], Bool[], [true, false])
julia> a .|| a
ERROR: BoundsError: attempt to access 0-element UnitRange{Int64} at index [1:2]
Full Stacktrace
Stacktrace:
  [1] throw_boundserror(A::UnitRange{Int64}, I::Tuple{UnitRange{Int64}})
    @ Base ./abstractarray.jl:691
  [2] checkbounds
    @ ./abstractarray.jl:656 [inlined]
  [3] getindex
    @ ./range.jl:918 [inlined]
  [4] getindex
    @ ~/.julia/packages/BlockArrays/tr499/src/blockaxis.jl:10 [inlined]
  [5] unblock
    @ ~/.julia/packages/BlockArrays/tr499/src/views.jl:10 [inlined]
  [6] to_indices
    @ ~/.julia/packages/BlockArrays/tr499/src/views.jl:28 [inlined]
  [7] to_indices
    @ ~/.julia/packages/BlockArrays/tr499/src/views.jl:43 [inlined]
  [8] view(A::BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}, I::BlockArrays.BlockIndexRange{1, Tuple{UnitRange{Int64}}})
    @ Base ./subarray.jl:176
  [9] _bview
    @ ~/.julia/packages/BlockArrays/tr499/src/blockbroadcast.jl:145 [inlined]
 [10] macro expansion
    @ ~/.julia/packages/BlockArrays/tr499/src/blockbroadcast.jl:175 [inlined]
 [11] _generic_blockbroadcast_copyto!(dest::BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}, bc::Base.Broadcast.Broadcasted{BlockArrays.BlockStyle{1}, Tuple{BlockedUnitRange{Vector{Int64}}}, Base.Broadcast.var"#5#6", Tuple{BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}, BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}}})
    @ BlockArrays ~/.julia/packages/BlockArrays/tr499/src/blockbroadcast.jl:151
 [12] copyto!(dest::BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}, bc::Base.Broadcast.Broadcasted{BlockArrays.BlockStyle{1}, Tuple{BlockedUnitRange{Vector{Int64}}}, Base.Broadcast.var"#5#6", Tuple{BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}, BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}}})
    @ BlockArrays ~/.julia/packages/BlockArrays/tr499/src/blockbroadcast.jl:219
 [13] copy
    @ ./broadcast.jl:885 [inlined]
 [14] materialize(bc::Base.Broadcast.Broadcasted{BlockArrays.BlockStyle{1}, Nothing, Base.Broadcast.var"#5#6", Tuple{BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}, BlockVector{Bool, Vector{Vector{Bool}}, Tuple{BlockedUnitRange{Vector{Int64}}}}}})
    @ Base.Broadcast ./broadcast.jl:860
 [15] top-level scope
    @ REPL[137]:1
 [16] top-level scope
    @ ~/.julia/packages/Infiltrator/WQe1n/src/Infiltrator.jl:508
 [17] top-level scope

It was surprisingly annoying to find where this was coming from since the faulty a::BlockVector{Bool} in many ways behaves normally but broadcasting then fails. It may be a good idea to just throw an error upon mortar with empty blocks or eliminate them silently (though that may cause other surprises, and, in my case, would have hidden the actual error that I had).

lassepe avatar Mar 05 '22 21:03 lassepe

I think empty blocks are probably useful… so would probably be best to figure out how to fix broadcasting

dlfivefifty avatar Mar 05 '22 22:03 dlfivefifty

That's fine with me as well. Just thought that the current behavior is probably a bug.

lassepe avatar Mar 05 '22 22:03 lassepe

I should probably add that his does not happen for arbitrary broadcasting. a .+ 1 for the vector above is fine, for example. Similarly, a = mortar(Bool[], [true, false]) (with only a single empty block) does not fail upon a .|| a.

lassepe avatar Mar 05 '22 22:03 lassepe