I am transitioning quantum chemistry code from Matlab to Julia 0.5.0. Great experience so far!
I am having trouble with type instability in one of the performance-critical functions. The function is recursive and involves 6 recursion relationships with 6 terms each. When terminating the recursion, it returns values that are pre-computed outside the recursion function.
Here is a minimal example (boiled down to one recursion relation with a single term, and no math) that shows the same type inference behavior:
function outerfun0()
val = 1.0 # expensive to calculate
function recur(a)
if a>0
return recur(a-1)
else
return val
end
end
@code_warntype recur(2)
end
The output is
Variables:
#self#::#recur#25{Float64}
a::Int64
Body:
begin
unless (Base.slt_int)(0,a::Int64)::Bool goto 4 # line 8:
return ((Core.getfield)((Core.getfield)(#self#::#recur#25{Float64},:recur)::CORE.BOX,:contents)::ANY)((Base.box)(Int64,(Base.sub_int)(a::Int64,1)))::ANY
4: # line 10:
return (Core.getfield)(#self#::#recur#25{Float64},:val)::Float64
end::ANY
I do not understand why there is ::ANY and ::CORE.BOX, which I think indicate a type instability related to the return type of recur. Julia seems to correctly infer types for a (Int64) and for val (Float64). All the code paths through recur return a Float64. So everything appears to be type-stable.
Interestingly, if I remove val in the inner function, the ::CORE.BOX disappears, but ::ANY stays:
function outerfun1()
val = 1.0 # expensive to calculate
function recur(a)
if a>0
return recur(a-1)
else
return 1.0
end
end
@code_warntype recur(2)
end
Output:
Variables:
#self#::#recur#30
a::Int64
Body:
begin
unless (Base.slt_int)(0,a::Int64)::Bool goto 4 # line 24:
return ((Core.getfield)((Core.getfield)(#self#::#recur#30,:recur)::ANY,:contents)::ANY)((Base.box)(Int64,(Base.sub_int)(a::Int64,1)))::ANY
4: # line 26:
return 1.0
end::ANY
How to get rid of this type instability? I can’t find a way. Neither type-annotating the return type of ‘recur’ nor wrapping both return expressions of recur with Float64() appears to help.