I have observed the following type instability when using reduce + hcat as follows (see examples below). Is this intended? Could it be related to issue#46331?
More context: I am using this syntax, as recommended here., when converting a Vector of scalar or arrays into a higher-dimensional array (e.g., a 128-long vector of 2x3-sized matrices is converted into a 2x3x128 array).
julia> reduce(hcat, ones(4))
1×4 Matrix{Float64}:
1.0 1.0 1.0 1.0
julia> reduce(hcat, ones(1))
1.0
julia> @code_warntype reduce(hcat, ones(4))
MethodInstance for reduce(::typeof(hcat), ::Vector{Float64})
from reduce(op, A::AbstractArray; kw...) @ Base reducedim.jl:406
Arguments
#self#::Core.Const(reduce)
op::Core.Const(hcat)
A::Vector{Float64}
Body::Union{Float64, Matrix{Float64}}
1 ─ %1 = Core.NamedTuple()::Core.Const(NamedTuple())
│ %2 = Base.pairs(%1)::Core.Const(Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}())
│ %3 = Base.:(var"#reduce#802")(%2, #self#, op, A)::Union{Float64, Matrix{Float64}}
└── return %3
Namely, it seems that reduce(hcat, v)
returns a Matrix
if v
has more than 1 element, but a scalar if v
has one element.
Note that, in contrast, using hcat
+ splatting yields a consistent behavior
julia> hcat(ones(4)...)
1×4 Matrix{Float64}:
1.0 1.0 1.0 1.0
julia> hcat(ones(1)...)
1×1 Matrix{Float64}:
1.0
julia> @code_warntype hcat(ones(1)...)
MethodInstance for hcat(::Float64)
from hcat(X::T...) where T<:Number @ Base abstractarray.jl:1609
Static Parameters
T = Float64
Arguments
#self#::Core.Const(hcat)
X::Tuple{Float64}
Locals
@_3::Union{Nothing, Tuple{Int64, Int64}}
@_4::Int64
@_5::Union{Nothing, Tuple{Int64, Int64}}
j::Int64
i::Int64
Body::Matrix{Float64}
#
# skipping rest of output
#