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

Union types. #73

Open DrTodd13 opened 8 years ago

DrTodd13 commented 8 years ago

In the following code, the input AST has Union return type. This Union type is lost by the end of domain IR. I suspect some LambdaHandling issue and not DomainIR itself but we need to investigate.

@acc function f1(a :: Float64, b :: Int64) if a < b return a else return b end end

ct = code_typed(f1,(Float64,Int64)) 1-element Array{Any,1}: :($(Expr(:lambda, Any[:a,:b], Any[Any[Any[:a,Float64,0],Any[:b,Int64,0],Any[symbol("##fy#7061"),Float64,18]],Any[],Any[],Any[]], :(begin # none, line 2:

fy#7061 = (Base.box)(Float64,(Base.sitofp)(Float64,b::Int64))

    unless (Base.box)(Base.Bool,(Base.or_int)((Base.lt_float)(a::Float64,##fy#7061::Float64)::Bool,(Base.box)(Base.Bool,(Base.and_int)((Base.box)(Base.Bool,(Base.and_int)((Base.eq_float)(a::Float64,##fy#7061::Float64)::Bool,(Base.lt_float)(##fy#7061::Float64,9.223372036854776e18)::Bool)),(Base.slt_int)((Base.box)(Int64,(Base.fptosi)(Int64,##fy#7061::Float64)),b::Int64)::Bool)))) goto 0 # none, line 3:
    return a::Float64
    goto 1
    0:  # none, line 5:
    return b::Int64
    1: 
end::Union{Float64,Int64}))))

domain code = $(Expr(:lambda, Any[:a,:b], Any[Any[Any[symbol("##fy#7422"),Float64,18],Any[:a,Float64,0],Any[:b,Int64,0]],Any[],Any[Float64,Bool,Bool,Bool,Int64,Int64,Bool,Bool,Bool,Bool,Bool,Bool,Bool],Any[]], :(begin # /mnt/home/taanders/.julia/v0.4/ParallelAccelerator/test/todd1.jl, line 10: GenSym(0) = (Core.Intrinsics.sitofp)(Float64,b::Int64)::Float64

fy#7422 = (Core.Intrinsics.box)(Float64,GenSym(0))::Float64

    GenSym(1) = (Core.Intrinsics.eq_float)(a::Float64,##fy#7422::Float64)::Bool
    GenSym(2) = (Core.Intrinsics.lt_float)(##fy#7422::Float64,9.223372036854776e18)::Bool
    GenSym(3) = (Core.Intrinsics.and_int)(GenSym(1),GenSym(2))::Bool
    GenSym(4) = (Core.Intrinsics.fptosi)(Int64,##fy#7422::Float64)::Int64
    GenSym(5) = (Core.Intrinsics.box)(Int64,GenSym(4))::Int64
    GenSym(6) = (Core.Intrinsics.box)(Bool,GenSym(3))::Bool
    GenSym(7) = (Core.Intrinsics.slt_int)(GenSym(5),b::Int64)::Bool
    GenSym(8) = (Core.Intrinsics.and_int)(GenSym(6),GenSym(7))::Bool
    GenSym(9) = (Core.Intrinsics.lt_float)(a::Float64,##fy#7422::Float64)::Bool
    GenSym(10) = (Core.Intrinsics.box)(Bool,GenSym(8))::Bool
    GenSym(11) = (Core.Intrinsics.or_int)(GenSym(9),GenSym(10))::Bool
    GenSym(12) = (Core.Intrinsics.box)(Bool,GenSym(11))::Bool
    unless GenSym(12) goto 0 # /mnt/home/taanders/.julia/v0.4/ParallelAccelerator/test/todd1.jl, line 11:
    return a::Float64
    goto 1
    0:  # /mnt/home/taanders/.julia/v0.4/ParallelAccelerator/test/todd1.jl, line 13:
    return b::Int64
    1:
end::Int64)))
ninegua commented 8 years ago

Domain IR tries to guess the return type since the incoming AST could just be Any type. However, there is no guarantee that there is only one return statement, or the last statement is a return. This can be fixed with a more rigorous reasoning.

That being said, I don't think there is a clean way to translate Union type in CGen, e.g., mixing j2c array and scalar in a C union type could be a potential disaster.

DrTodd13 commented 8 years ago

Yes, so maybe a long term thing to think about but in the short term we should at least catch the case that we can't translate yet and throw an exception so that we fall back to pure Julia.