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

BUG: `BlockVector * Adjoint{BlockVector}` crashes

Open ogauthe opened this issue 10 months ago • 1 comments

using BlockArrays: BlockArray, blockedrange
d = blockedrange([2,3])
v = ones(d)
v2 = BlockArray(v)
v3 = Array(v)

v * v' isa BlockedArray  # true
v3 * v3' isa Array  # true
v2 * v2' isa Any  # BoundsError
ERROR: BoundsError: attempt to access 2-blocked 5-element BlockVector{Float64} at index [BlockSlice(Block(1)[1:2],1:2), BlockSlice(Block(1)[1:2],Base.OneTo(2))]
Stacktrace:
  [1] throw_boundserror(A::BlockVector{Float64, Vector{…}, Tuple{…}}, I::Tuple{BlockArrays.BlockSlice{…}, BlockArrays.BlockSlice{…}})
    @ Base ./essentials.jl:14
  [2] checkbounds
    @ ./abstractarray.jl:699 [inlined]
  [3] view
    @ ./subarray.jl:214 [inlined]
  [4] _bview
    @ ~/.julia/packages/BlockArrays/tOOU0/src/blockbroadcast.jl:124 [inlined]
  [5] (::BlockArrays.var"#56#61"{Base.Broadcast.Broadcasted{…}, Tuple{…}})(i::Int64)
    @ BlockArrays ~/.julia/packages/BlockArrays/tOOU0/src/blockbroadcast.jl:156
  [6] ntuple
    @ ./ntuple.jl:19 [inlined]
  [7] _generic_blockbroadcast_copyto!(dest::BlockMatrix{…}, bc::Base.Broadcast.Broadcasted{…})
    @ BlockArrays ~/.julia/packages/BlockArrays/tOOU0/src/blockbroadcast.jl:156
  [8] copyto!(dest::BlockMatrix{…}, bc::Base.Broadcast.Broadcasted{…})
    @ BlockArrays ~/.julia/packages/BlockArrays/tOOU0/src/blockbroadcast.jl:163
  [9] copy
    @ ./broadcast.jl:897 [inlined]
 [10] materialize
    @ ./broadcast.jl:872 [inlined]
 [11] broadcast(::typeof(*), ::BlockVector{Float64, Vector{…}, Tuple{…}}, ::LinearAlgebra.Adjoint{Float64, BlockVector{…}})
    @ Base.Broadcast ./broadcast.jl:810
 [12] *(u::BlockVector{Float64, Vector{…}, Tuple{…}}, v::LinearAlgebra.Adjoint{Float64, BlockVector{…}})
    @ LinearAlgebra ~/.julia/juliaup/julia-1.11.3+0.x64.linux.gnu/share/julia/stdlib/v1.11/LinearAlgebra/src/adjtrans.jl:484
 [13] top-level scope
    @ REPL[55]:1
Some type information was truncated. Use `show(err)` to see complete types.

BlockArrays v1.4.0

ogauthe avatar Feb 26 '25 02:02 ogauthe

For BlockedVector, broadcast removes the blocking at some point and everything is fined.

For BlockVector, the issue is that dest and v2' are matrices and a broadcast with NDims=2 is called. It tries to index v2 with 2 indices, which fails because v2 is a vector. Basically, it assumes all broadcast arguments as well as dest to have ndims(a) == NDims, although this is not true here. One gets the same errors with e.g. v2' .+ v2.

This happens in _generic_blockbroadcast_copyto!(dest::BlockMatrix{…}, bc::Base.Broadcast.Broadcasted{…}), at BlockArrays.jl/src/blockbroadcast.jl:135

I see 2 possible ways to fix this: either convert both input to AbstractMatrix or fix t in this case to return correct indexing. The first solution looks simpler.

ogauthe avatar May 02 '25 19:05 ogauthe