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

ParallelIR produces wrong code when fusion is off #62

Closed ninegua closed 8 years ago

ninegua commented 8 years ago

The following program gives wrong code in C, which looks like the same body is being repeated twice. If we comment out the PIRSetFuseLimit line, the fused code looks correct.

using ParallelAccelerator

ParallelAccelerator.set_debug_level(3)
ParallelAccelerator.ParallelIR.PIRSetFuseLimit(0)

@acc function nearest(X, centroids, i)
    numCenter = size(centroids, 1)
    label = 1
    dist = 10000000.0
    for j = 1:numCenter
        d = sqrt(sum((X[i,:] .- centroids[j,:]).^2))
        if d < dist
            dist = d
            label = j
        end
    end
    return label
end

X = rand(100, 2)
centroids = rand(5,2)
println(nearest(X, centroids, 1))
DrTodd13 commented 8 years ago

If you look at the following output of DomainIR, the lines starting with GenSym(12) through GenSym(16) are already a duplicate of the lines starting with GenSym(17) through GenSym(21). I don't think ParallelIR and CGen are doing anything weird after that. Looks like a DomainIR issue.

domain code = $(Expr(:lambda, Any[:X,:centroids,:i], Any[Any[Any[symbol("#s232"),Int64,2],Any[:X,Array{Float64,2},0],Any[:numCenter,Int64,18],Any[:label,Int64,2],Any[:dist,Float64,2],Any[:i,Int64,0],Any[:centroids,Array{Float64,2},0],Any[:j,Int64,18],Any[:d,Float64,18]],Any[],Any[Union{},Union{},UnitRange{Int64},Tuple{Int64,Int64},Int64,Int64,Int64,Int64,Bool,Bool,Bool,Int64,Array{Float64,2},Array{Float64,2},Array{Float64,2},Array{Float64,2},Float64,Array{Float64,2},Array{Float64,2},Array{Float64,2},Array{Float64,2},Float64,Bool,Int64,Int64,Int64,Bool,Bool,Bool,Bool,Bool],Any[]], :(begin # /tmp/issue62.jl, line 9: numCenter = (top(arraysize))(centroids::Array{Float64,2},1)::Int64 # /tmp/issue62.jl, line 10: label = 1 # /tmp/issue62.jl, line 11: dist = 1.0e7 # /tmp/issue62.jl, line 12: GenSym(2) = $(Expr(:new, UnitRange{Int64}, 1, :(((top(getfield))(Base.Intrinsics,:select_value)::I)((Base.sle_int)(1,numCenter::Int64)::Bool,numCenter::Int64,(Base.box)(Int64,(Base.sub_int)(1,1)))::Int64)))

s232 = 1

    GenSym(6) = (Core.Intrinsics.add_int)(numCenter::Int64,1)::Int64
    GenSym(7) = (Core.Intrinsics.box)(Int64,GenSym(6))::Int64
    GenSym(8) = #s232::Int64 === GenSym(7)::Bool
    GenSym(9) = (Core.Intrinsics.not_int)(GenSym(8))::Bool
    GenSym(10) = (Core.Intrinsics.box)(Bool,GenSym(9))::Bool
    unless GenSym(10) goto 1
    2:
    GenSym(4) = #s232::Int64
    GenSym(11) = (Core.Intrinsics.add_int)(#s232::Int64,1)::Int64
    GenSym(5) = (Core.Intrinsics.box)(Int64,GenSym(11))::Int64
    j = GenSym(4)
    #s232 = GenSym(5) # /tmp/issue62.jl, line 13:
    GenSym(12) = $(Expr(:select, :(X::Array{Float64,2}), :($(Expr(:ranges, :(i::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(X::Array{Float64,2},2)::Int64)))))))))
    GenSym(13) = $(Expr(:select, :(centroids::Array{Float64,2}), :($(Expr(:ranges, :(j::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(centroids::Array{Float64,2},2)::Int64)))))))))
    GenSym(14) = $(Expr(:mmap, Any[:($(Expr(:select, :(X::Array{Float64,2}), :($(Expr(:ranges, :(i::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(X::Array{Float64,2},2)::Int64)))))))))),:($(Expr(:select, :(centroids::Array{Float64,2}), :($(Expr(:ranges, :(j::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(centroids::Array{Float64,2},2)::Int64))))))))))], ([:(x1::Float64),:(x2::Float64)];) -> (Any[:(((top(sub_float))(x1,x2)::Float64,))])::Type[Float64]))
    GenSym(15) = $(Expr(:mmap, Any[GenSym(14)], ([:(x1::Float64)];) -> (Any[:(((top(^))(x1,2)::Float64,))])::Type[Float64]))
    GenSym(16) = $(Expr(:reduce, 0.0, GenSym(15), ([:(x1::Float64),:(x2::Float64)];) -> ([:(((top(add_float))(x1,x2)::Float64,))])::Type[Float64]))
    GenSym(17) = $(Expr(:select, :(X::Array{Float64,2}), :($(Expr(:ranges, :(i::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(X::Array{Float64,2},2)::Int64)))))))))
    GenSym(18) = $(Expr(:select, :(centroids::Array{Float64,2}), :($(Expr(:ranges, :(j::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(centroids::Array{Float64,2},2)::Int64)))))))))
    GenSym(19) = $(Expr(:mmap, Any[:($(Expr(:select, :(X::Array{Float64,2}), :($(Expr(:ranges, :(i::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(X::Array{Float64,2},2)::Int64)))))))))),:($(Expr(:select, :(centroids::Array{Float64,2}), :($(Expr(:ranges, :(j::Int64), :($(Expr(:range, 1, 1, :((top(arraysize))(centroids::Array{Float64,2},2)::Int64))))))))))], ([:(x1::Float64),:(x2::Float64)];) -> (Any[:(((top(sub_float))(x1,x2)::Float64,))])::Type[Float64]))
    GenSym(20) = $(Expr(:mmap, Any[GenSym(19)], ([:(x1::Float64)];) -> (Any[:(((top(^))(x1,2)::Float64,))])::Type[Float64]))
    GenSym(21) = $(Expr(:reduce, 0.0, GenSym(20), ([:(x1::Float64),:(x2::Float64)];) -> ([:(((top(add_float))(x1,x2)::Float64,))])::Type[Float64]))
    d = (ParallelAccelerator.API.sqrt)(GenSym(21))::Float64 # /tmp/issue62.jl, line 14:
    GenSym(22) = (Core.Intrinsics.lt_float)(d::Float64,dist::Float64)::Bool
    unless GenSym(22) goto 4 # /tmp/issue62.jl, line 15:
    dist = d::Float64 # /tmp/issue62.jl, line 16:
    label = j::Int64
    4:
    3:
    GenSym(23) = (top(getfield))(GenSym(2),:stop)::Int64
    GenSym(24) = (Core.Intrinsics.add_int)(GenSym(23),1)::Int64
    GenSym(25) = (Core.Intrinsics.box)(Int64,GenSym(24))::Int64
    GenSym(26) = #s232::Int64 === GenSym(25)::Bool
    GenSym(27) = (Core.Intrinsics.not_int)(GenSym(26))::Bool
    GenSym(28) = (Core.Intrinsics.box)(Bool,GenSym(27))::Bool
    GenSym(29) = (Core.Intrinsics.not_int)(GenSym(28))::Bool
    GenSym(30) = (Core.Intrinsics.box)(Bool,GenSym(29))::Bool
    unless GenSym(30) goto 2
    1:
    0:  # /tmp/issue62.jl, line 19:
    return label::Int64
end::Int64)))
ninegua commented 8 years ago

Thanks for spotting it! I should have double checked more carefully. The issue is fixed in f899deb02f74d495c0e32806c1f6ba1a1d463c76