ParallelAccelerator.jl
ParallelAccelerator.jl copied to clipboard
Union types.
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)))
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.
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.