Methods with keyword arguments are implemented to call hidden helper methods that have the written body, so @code_warntype
is really difficult to use with them. Well, I dug out the underlying call and am including the part where things get a little unstable, even though the internal arrays and the return value are inferred concretely.
julia> @code_warntype LinearAlgebra.:(var"#pinv#33")(0.0, (eps(real(float(1.1)))*min(3, 5))*iszero(0.0), pinv,rand(3, 5))
MethodInstance for LinearAlgebra.var"#pinv#33"(::Float64, ::Float64, ::typeof(pinv), ::Matrix{Float64})
from var"#pinv#33"(atol::Real, rtol::Real, ::typeof(pinv), A::AbstractMatrix{T}) where T in LinearAlgebra at /nix/store/4dkh426qldnal1n4m2czlhrmi4qf9ri5-julia-bin-1.8.3/share/julia/stdlib/v1.8/LinearAlgebra/src/dense.jl:1445
...
Locals
...
index::Any
...
tol@_14::Core.Box
...
tol@_21::Union{}
...
│ %40 = (rtol * maxabsA)::Float64
│ %41 = LinearAlgebra.max(%40, atol)::Float64
│ Core.setfield!(tol@_14, :contents, %41)
...
│ %55 = Base.getproperty(SVD, :S)::Vector{Float64}
│ %56 = LinearAlgebra.maximum(%55)::Float64
│ %57 = (rtol * %56)::Float64
│ %58 = LinearAlgebra.max(%57, atol)::Float64
│ Core.setfield!(tol@_14, :contents, %58)
...
│ %68 = Core.isdefined(tol@_14, :contents)::Bool
└─── goto #9 if not %68
8 ── goto #10
9 ── Core.NewvarNode(:(tol@_21))
└─── tol@_21
10 ┄ %73 = Core.getfield(tol@_14, :contents)::Any
│ %74 = Base.broadcasted(LinearAlgebra.:>, %67, %73)::Any
│ (index = Base.materialize(%74))
│ %76 = Base.dotview(Sinv, index)::Any
│ %77 = Base.getproperty(SVD, :S)::Vector{Float64}
│ %78 = LinearAlgebra.view(%77, index)::Any
│ %79 = Base.broadcasted(LinearAlgebra.pinv, %78)::Base.Broadcast.Broadcasted{_A, Nothing, typeof(pinv)} where _A<:Union{Nothing, Base.Broadcast.BroadcastStyle}
│ Base.materialize!(%76, %79)
...
The corresponding source code section is:
tol = max(rtol * maxabsA, atol)
...
tol = max(rtol*maximum(SVD.S), atol)
...
index = SVD.S .> tol
Sinv[index] .= pinv.(view(SVD.S, index))
It seems as if tol
is an uninferred boxed value (Core.Box
) and it’s not even certain if it is defined (%68: tol@_14
vs tol@_21
). I don’t really know why because in both lines (%41, %58) the final max
call is inferred concretely ::Float64
before being stored in the box.