ParallelAccelerator.jl
ParallelAccelerator.jl copied to clipboard
@par and explicit type issue.
using ParallelAccelerator
ParallelAccelerator.ParallelIR.set_debug_level(3)
@acc function score2()
exps = 0
@par exps(+) for i in 1:100
exps += i
end
return exps
end
score2()
This results in:
ERROR: LoadError: UndefVarError: ret not defined
in score2() at /home/taanders/.julia/v0.5/CompilerTools/src/OptFramework.jl:598
in include_from_node1(::String) at ./loading.jl:488
in process_options(::Base.JLOptions) at ./client.jl:262
in _start() at ./client.jl:318
while loading /tmp/t1.jl, in expression starting on line 15
If you add Int64 type annotations to exps outside the loop then the error disappears.
How does this lack of annotation even lead to this particular error? Can anybody explain? We need to catch this issue and give a better error message or fix the problem automatically if at all possible.
The particular error originated at a place where the return type of a function call cannot be determined. Julia 0.5 has removed static_typeof
, so we had to resort to an elaborated trick, which works out when all types check out, but would result in an undefined variable when something goes wrong. I don't think we can auto-correct this error because it hits the limitation of Julia's type inference.
There are two constraints here:
-
We must make sure Julia's type checking works out on
@acc
translated code, so that we can get accurate types for parameters, variables, and so on. -
We are offering sequential compatibility so the code should continue to run with native Julia when setting
PROSPECT_MODE=none
.
Together they pose a challenge to the design space on how we can support comprehension, map/reduce, and @par
. Whatever our translation is, the result has to pass both type checker and be able to run with native Julia. The choice we made earlier was to utilize lambdas (inner functions) and unify the interface around a fixed set of API calls, where we can provide sequential implementation. There could be ways to translate certain things a little differently, but:
-
Comprehension used to expand into direct loops in Julia 0.4, but that is no longer the case in Julia 0.5, where it becomes calls to generators, which always involves lambda. This is why we had less trouble with Julia 0.4 at making sure things type check.
-
map/reduce are Julia's built in library function that we support, they take lambda as argument.
-
We provide additional API such as cartesianarray (what comprehension translates to) and cartesianmapreduce (what
@par
translates to) that can be used directly. They take lambda as argument too.
We could have translated @par
without using lambdas, but I don't think we can avoid the general issue in other places.
I agree; this is a general problem. Can we return an error when an escaping variable is not typed?