I am seeing some odd type instability issues when broadcasting.
Simple functions seem to become type-unstable when broadcasting over multiple views:
f1(x::AbstractVector{T}) where T = 1
f2(x::AbstractVector{T}) where T = x .+ 1
#@code_warntype f1(rand(2)) # Type Stable
#@code_warntype f1.(eachcol(rand(2,2))) # Type Stable
#@code_warntype f2(rand(2)) # Type Stable
@code_warntype f2.(eachcol(rand(2,2))) # Not Type Stable
Output:
MethodInstance for (::var"##dotfunction#358#54")(::Base.Generator{Base.OneTo{Int64}, Base.var"#242#243"{Matrix{Float64}}})
from (::var"##dotfunction#358#54")(x1) in Main
Arguments
#self#::Core.Const(var"##dotfunction#358#54"())
x1::Base.Generator{Base.OneTo{Int64}, Base.var"#242#243"{Matrix{Float64}}}
Body::Any
1 β %1 = Base.broadcasted(Main.f2, x1)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(f2), Tuple{Vector{SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true}}}}
β %2 = Base.materialize(%1)::Any
βββ return %2
Broadcasting also appears to be type-unstable for any function that is called as member of a struct, even when the struct is parametrically typed to the function
struct MyStruct{F<:Function}
f::F
end
f3(x) = 1
s3 = MyStruct(f3)
#@code_warntype s3.f(1) # Type Stable
@code_warntype s3.f.([1,2,3]) # Not type Stable
Output
MethodInstance for (::var"##dotfunction#357#53")(::Vector{Int64})
from (::var"##dotfunction#357#53")(x1) in Main
Arguments
#self#::Core.Const(var"##dotfunction#357#53"())
x1::Vector{Int64}
Body::Any
1 β %1 = Base.getproperty(Main.s, :f)::Any
β %2 = Base.broadcasted(%1, x1)::Any
β %3 = Base.materialize(%2)::Any
βββ return %3
Not sure if these two examples are related or reflect separate issues.