I have created an MWE that can readily executed by copy-pasting to the REPL, provided package DispatchDoctor.jl is installed.
What follows below is:
-
A variable
Z
is created in global scope (see end of script below). -
A function
mwe
that, according to DispatchDoctor.jl, exhibits type instability when called withmwe(Z)
. The instability comes from an inner function calledlowerbound
. Functionlowerbound
defines in its body two anonymous functions that are never called. -
A function
mwe_2
that is identical tomwe
, but where the first anonymous function that is never called is now commented out. When called withmwe_2(Z)
, no type instability is detected. -
A function
mwe_3
that is identical tomwe
, but where the second anonymous function that is never called is now commented out. When called withmwe_3(Z)
, no type instability is detected.
My question: why do the two redundant anonymous function influence the type instability?
using DispatchDoctor
function mwe(Z)
local kernel(xᵢ, xⱼ, σf, ℓ) = σf * exp( - abs2(xᵢ - xⱼ) * ℓ)
@stable function lowerbound(σf, ℓ)
local k(x, z) = kernel(x, z, σf, ℓ) # this is never called
local k(x) = kernel.(x, Z, σf, ℓ)
local s(x) = dot(k(x), k(x)) # this is never called
return k(1.0)
end
lowerbound(1.0, 1.0)
end
# same as mwe but line "local s(x) = dot(k(x), k(x))" is commented out
function mwe_2(Z)
local kernel(xᵢ, xⱼ, σf, ℓ) = σf * exp( - abs2(xᵢ - xⱼ) * ℓ)
@stable function lowerbound(σf, ℓ)
local k(x, z) = kernel(x, z, σf, ℓ) # this is never called
local k(x) = kernel.(x, Z, σf, ℓ)
# local s(x) = dot(k(x), k(x)) # this is never called
return k(1.0)
end
lowerbound(1.0, 1.0)
end
# same as mwe but line "local k(x, z) = kernel(x, z, σf, ℓ)" is commented out
function mwe_3(Z)
local kernel(xᵢ, xⱼ, σf, ℓ) = σf * exp( - abs2(xᵢ - xⱼ) * ℓ)
@stable function lowerbound(σf, ℓ)
# local k(x, z) = kernel(x, z, σf, ℓ) # this is never called
local k(x) = kernel.(x, Z, σf, ℓ)
local s(x) = dot(k(x), k(x)) # this is never called
return k(1.0)
end
lowerbound(1.0, 1.0)
end
# I am aware that this is a *non-const* global
Z = collect(LinRange(0, 30, 30));
mwe(Z) # type instability detected
mwe_2(Z) # NO type instability detected
mwe_3(Z) # NO type instability detected