If by “infered correctly” you mean that actual types are printed, it’s not what inference means. In Julia, a runtime object always has a concrete type.
Good correction, my bad. Then most of my observations don’t hold, probably, since i didn’t know that.
This workaround, while making sense, feels much heavier compilation wise.
Edit: i got curious and run a test on the fib function:
function fib(n::Int64)
if n > 25
t = @spawn fib(n-2)
return fib(n-1) + fetch(t)
else
return serial_fib(n)
end
end
function fib_(n::Int64)
if n > 25
return fib_(n-1) + fetch(@spawn fib_(n-2))
else
return serial_fib(n)
end
end
the second version does not seem to gain any speed (both return the correct result):
@btime fib(46) # 2.802 s (301411 allocations: 20.78 MiB)
@btime fib_(46) # 20.232 s (343674 allocations: 21.42 MiB)
turns out that fetch(@spawn f())
does not really work.
Moreover, i find this interesting:
julia> @code_warntype fib(1)
... etc
2 ─ %6 = Main.:(var"#18#19")::Core.Compiler.Const(var"#18#19", false)
│ %7 = Core.typeof(n)::Core.Compiler.Const(Int64, false)
│ %8 = Core.apply_type(%6, %7)::Core.Compiler.Const(var"#18#19"{Int64}, false)
│ (#18 = %new(%8, n))
│ %10 = #18::var"#18#19"{Int64}
... yadda yadda
couldn’t %10
be the return type of the fib(n-2)
before it gets wrapped in the task t
by @spawn
. If that’s the case then it is even more strange that
%19 = Main.fib(%18)::Any
the whole function is seen as returning ::Any
At this point, probably the type instability of fetch
could be felt more in recursive functions, due to the repeated calls to a function that the compiler sees as returning ::Any
, and hence has to check each time.
P.S: Sorry if i’m being so pedantic