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
Zis created in global scope (see end of script below). -
A function
mwethat, according to DispatchDoctor.jl, exhibits type instability when called withmwe(Z). The instability comes from an inner function calledlowerbound. Functionlowerbounddefines in its body two anonymous¹ functions that are never called. -
A function
mwe_2that 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_3that 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?
¹ As pointed out below by @nsajko, these are not actually anonymous functions. I point out the mistake here, but do not correct it above so that the comment below does not appear out of place.
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