aviatesk / JET.jl

An experimental code analyzer for Julia. No need for additional type annotations.

Home Page:https://aviatesk.github.io/JET.jl/dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Possible LinearAlgebra false positive

jmulcahy opened this issue · comments

On Julia v1.9.2 and JET v0.8.11, I'm seeing what I think is a false positive.

MWE:

using JET, LinearAlgebra

function f(W, x)
    y = W' * x
    W * y
end

W = randn(3, 5)
x = randn(3)

f(W, x) # works

@report_opt f(W, x)

The last line returns:

═════ 3 possible errors found ═════
┌ f(W::Matrix{Float64}, x::Vector{Float64}) @ Main ./REPL[16]:2
│┌ *(adjA::Adjoint{Float64, Matrix{Float64}}, x::Vector{Float64}) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:101
││┌ mul!(C::Vector{Float64}, A::Adjoint{Float64, Matrix{Float64}}, B::Vector{Float64}) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:276
│││┌ mul!(y::Vector{Float64}, adjA::Adjoint{Float64, Matrix{Float64}}, x::Vector{Float64}, alpha::Bool, beta::Bool) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:109
││││┌ mul!(y::Vector{Float64}, tA::Transpose{Float64, Matrix{Float64}}, x::Vector{Float64}, alpha::Bool, beta::Bool) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:93
│││││┌ gemv!(y::Vector{Float64}, tA::Char, A::Matrix{Float64}, x::Vector{Float64}, α::Bool, β::Bool) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:493
││││││┌ DimensionMismatch(msg::LazyString) @ Base ./array.jl:12
│││││││┌ convert(::Type{String}, s::LazyString) @ Base ./strings/basic.jl:232
││││││││┌ String(l::LazyString) @ Base ./strings/lazy.jl:83
│││││││││┌ sprint(::Base.var"#102#103"{LazyString}) @ Base ./strings/io.jl:107
││││││││││┌ sprint(::Base.var"#102#103"{LazyString}; context::Nothing, sizehint::Int64) @ Base ./strings/io.jl:114
│││││││││││┌ (::Base.var"#102#103"{LazyString})(io::IOBuffer) @ Base ./strings/lazy.jl:85
││││││││││││ runtime dispatch detected: print(io::IOBuffer, %15::Any)::Any
│││││││││││└────────────────────
│││││┌ gemv!(y::Vector{Float64}, tA::Char, A::Matrix{Float64}, x::Vector{Float64}, α::Bool, β::Bool) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:505
││││││┌ generic_matvecmul!(C::Vector{Float64}, tA::Char, A::Matrix{Float64}, B::Vector{Float64}, _add::LinearAlgebra.MulAddMul{ais1, bis0, Bool, Bool} where {ais1, bis0}) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:780
│││││││┌ _modify!(p::LinearAlgebra.MulAddMul{ais1, bis0, Bool, Bool} where {ais1, bis0}, x::Float64, C::Vector{Float64}, idx′::Int64) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\generic.jl:93
││││││││┌ setindex!(::Vector{Float64}, ::Any, ::CartesianIndex{1}) @ Base ./multidimensional.jl:670
│││││││││ runtime dispatch detected: ((A::Vector{Float64})[%2::Int64] = v::Any::Any)
││││││││└────────────────────
│││││┌ gemv!(y::Vector{Float64}, tA::Char, A::Matrix{Float64}, x::Vector{Float64}, α::Bool, β::Bool) @ LinearAlgebra C:\workdir\usr\share\julia\stdlib\v1.9\LinearAlgebra\src\matmul.jl:505
││││││ runtime dispatch detected: LinearAlgebra.generic_matvecmul!(y::Vector{Float64}, tA::Char, A::Matrix{Float64}, x::Vector{Float64}, %160::LinearAlgebra.MulAddMul{ais1, bis0, Bool, Bool} where {ais1, bis0})::Vector{Float64}
│││││└────────────────────

@code_warntype and Cthulhu.@descend looked clean to me, although I'm a novice.

julia> @code_warntype f(W, x)
MethodInstance for f(::Matrix{Float64}, ::Vector{Float64})
  from f(W, x) @ Main REPL[16]:1
Arguments
  #self#::Core.Const(f)
  W::Matrix{Float64}
  x::Vector{Float64}
Locals
  y::Vector{Float64}
Body::Vector{Float64}
1 ─ %1 = Main.:var"'"(W)::Adjoint{Float64, Matrix{Float64}}
│        (y = %1 * x)
│   %3 = (W * y)::Vector{Float64}
└──      return %3

It looks to me like JET is finding some dynamic dispatch deep in LinearAlgebra related to creating a string for a DimensionMismatch that for whatever reason @code_warntype and Cthulhu.@descend aren't flagging.