You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@Moelf found something in stack overflow where lowering/inference is doing something weird where we box a variable that doesn't need to be boxed, then check if it exists even if it existing isn't conditional which then leads to bad inference.
julia>functiontestMaxWeird!(x,X,β)
xmax =0.0@inboundsfor i ∈eachindex(x)
x[i] = X[i,2] * β[1] + X[i,2] * β[2]
if x[i] > xmax
xmax = x[i]
endend
y =sum(exp(xj-xmax) for xj ∈ x)
return xmax
end
julia>functiontestMaxWeird2!(x,X,β)
xmax =0.0@inboundsfor i ∈eachindex(x)
x[i] = X[i,2] * β[1] + X[i,2] * β[2]
if x[i] > xmax
xmax = x[i]
endend# y = sum(exp(xj-xmax) for xj ∈ x)return xmax
end
julia> H =10000;
julia> X =rand(H,2);
julia> β =rand(2);
julia> x =zeros(H);
julia>@code_warntypetestMaxWeird!(x,X,β)
MethodInstance fortestMaxWeird!(::Vector{Float64}, ::Matrix{Float64}, ::Vector{Float64})
from testMaxWeird!(x, X, β) in Main at REPL[13]:1
Arguments
#self#::Core.Const(testMaxWeird!)
x::Vector{Float64}
X::Matrix{Float64}
β::Vector{Float64}
Locals
#7::var"#7#8"@_6::Union{Nothing, Tuple{Int64, Int64}}
val::Nothing
y::Any
xmax@_9::Core.Box
i::Int64
xmax@_11::Union{}
xmax@_12::Union{}
Body::Any1 ── Core.NewvarNode(:(#7))
│ Core.NewvarNode(:(val))
│ Core.NewvarNode(:(y))
│ (xmax@_9= Core.Box())
│ Core.setfield!(xmax@_9, :contents, 0.0)
│ nothing
│ %7= Main.eachindex(x)::Base.OneTo{Int64}
│ (@_6= Base.iterate(%7))
│ %9= (@_6===nothing)::Bool
│ %10= Base.not_int(%9)::Bool
└─── goto #9 if not %102 ┄─ %12=@_6::Tuple{Int64, Int64}
│ (i = Core.getfield(%12, 1))
│ %14= Core.getfield(%12, 2)::Int64
│ %15= Base.getindex(X, i, 2)::Float64
│ %16= Base.getindex(β, 1)::Float64
│ %17= (%15*%16)::Float64
│ %18= Base.getindex(X, i, 2)::Float64
│ %19= Base.getindex(β, 2)::Float64
│ %20= (%18*%19)::Float64
│ %21= (%17+%20)::Float64
│ Base.setindex!(x, %21, i)
│ %23= Base.getindex(x, i)::Float64
│ %24= Core.isdefined(xmax@_9, :contents)::Bool
└─── goto #4 if not %243 ── goto #54 ── Core.NewvarNode(:(xmax@_11))
└─── xmax@_115 ┄─ %29= Core.getfield(xmax@_9, :contents)::Any
│ %30= (%23>%29)::Any
└─── goto #7 if not %306 ── %32= Base.getindex(x, i)::Float64
└─── Core.setfield!(xmax@_9, :contents, %32)
7 ┄─ (@_6= Base.iterate(%7, %14))
│ %35= (@_6===nothing)::Bool
│ %36= Base.not_int(%35)::Bool
└─── goto #9 if not %368 ── goto #29 ┄─ (val =nothing)
│ nothing
│ val
│ (#7 = %new(Main.:(var"#7#8"), xmax@_9))
│ %43=#7::var"#7#8"
│ %44= Base.Generator(%43, x)::Base.Generator{Vector{Float64}, var"#7#8"}
│ (y = Main.sum(%44))
│ %46= Core.isdefined(xmax@_9, :contents)::Bool
└─── goto #11 if not %4610 ─ goto #1211 ─ Core.NewvarNode(:(xmax@_12))
└─── xmax@_1212 ┄ %51= Core.getfield(xmax@_9, :contents)::Any
└─── return%5
julia>@code_warntypetestMaxWeird2!(x,X,β)
MethodInstance fortestMaxWeird2!(::Vector{Float64}, ::Matrix{Float64}, ::Vector{Float64})
from testMaxWeird2!(x, X, β) in Main at REPL[2]:1
Arguments
#self#::Core.Const(testMaxWeird2!)
x::Vector{Float64}
X::Matrix{Float64}
β::Vector{Float64}
Locals
@_5::Union{Nothing, Tuple{Int64, Int64}}
val::Nothing
xmax::Float64
i::Int64
Body::Float641 ─ Core.NewvarNode(:(val))
│ (xmax =0.0)
│ nothing
│ %4= Main.eachindex(x)::Base.OneTo{Int64}
│ (@_5= Base.iterate(%4))
│ %6= (@_5===nothing)::Bool
│ %7= Base.not_int(%6)::Bool
└── goto #6 if not %72 ┄ %9=@_5::Tuple{Int64, Int64}
│ (i = Core.getfield(%9, 1))
│ %11= Core.getfield(%9, 2)::Int64
│ %12= Base.getindex(X, i, 2)::Float64
│ %13= Base.getindex(β, 1)::Float64
│ %14= (%12*%13)::Float64
│ %15= Base.getindex(X, i, 2)::Float64
│ %16= Base.getindex(β, 2)::Float64
│ %17= (%15*%16)::Float64
│ %18= (%14+%17)::Float64
│ Base.setindex!(x, %18, i)
│ %20= Base.getindex(x, i)::Float64
│ %21= (%20> xmax)::Bool
└── goto #4 if not %213 ─ (xmax = Base.getindex(x, i))
4 ┄ (@_5= Base.iterate(%4, %11))
│ %25= (@_5===nothing)::Bool
│ %26= Base.not_int(%25)::Bool
└── goto #6 if not %265 ─ goto #26 ┄ (val =nothing)
│ nothing
│ val
└── return xmax
The text was updated successfully, but these errors were encountered:
It might be that. Adding a type to xmax doesn't help also for reference, it makes it a bit better but it still boxes the variable which makes it bad. This issue is always rearing it's head, on super innocent code even.
@Moelf found something in stack overflow where lowering/inference is doing something weird where we box a variable that doesn't need to be boxed, then check if it exists even if it existing isn't conditional which then leads to bad inference.
The text was updated successfully, but these errors were encountered: