IntelLabs / ParallelAccelerator.jl

The ParallelAccelerator package, part of the High Performance Scripting project at Intel Labs
BSD 2-Clause "Simplified" License
294 stars 32 forks source link

@par and explicit type issue. #135

Open DrTodd13 opened 7 years ago

DrTodd13 commented 7 years ago
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.

ninegua commented 7 years ago

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:

  1. 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.

  2. 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:

  1. 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.

  2. map/reduce are Julia's built in library function that we support, they take lambda as argument.

  3. 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.

ehsantn commented 7 years ago

I agree; this is a general problem. Can we return an error when an escaping variable is not typed?