I struggling to obtain a minimal working example. But I have one situation which looks like:
function outer!(f::Function, output,x::AbstractVector)
for i in 1:10
output = inner!(f,output,x)
end
return output
end
f
is given by the user, most likely as a closure. Something like:
function run()
a = 5
f(x,a) = a*x
output = outer!( x -> f(x,a), output, x)
end
I am seeing some allocations associated with this closure. Curiously, if I modify the outer!
function to:
function outer!(f::Function, output,x::AbstractVector)
g = (x) -> f(x) # <<< set g here as pass g in the loop to inner!
for i in 1:10
output = inner!(g,output,x)
end
return output
end
or to
function outer!(f::Function, output,x::AbstractVector)
for i in 1:10
output = inner!((x) -> f(x),output,x) # pass a closure instead of `f` directly
end
return output
end
the allocations go away. It seems that telling the compiler how many parameters f
is what is solving the problem.
Maybe this is related to this known issue. But I am not completely sure.
As a workaround, adding g = (x) -> f(x)
in my case is not a problem, but it seems like a hack to something I am not quite understanding.
Any insight is appreciated.
By the way: I cannot find type instabilities anywhere. Does not seem to be related to that. Also there is not such a big performance penalty (as reported in the issue). Just some some thousand allocations more.