-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
type inference issue with vectors if ints and floats in julia 1.10 #526
type inference issue with vectors if ints and floats in julia 1.10 #526
Comments
julia> using VectorizationBase
julia> vxi = Vec(ntuple(identity, 4)...);
julia> vxf = Vec(ntuple(float, 4)...);
julia> vxiu = VecUnroll((vxi,vxi,vxi,vxi));
julia> vxfu = VecUnroll((vxf,vxf,vxf,vxf));
julia> @code_warntype VectorizationBase.promote(vxiu,vxfu,vxfu)
MethodInstance for promote(::VecUnroll{3, 4, Int64, Vec{4, Int64}}, ::VecUnroll{3, 4, Float64, Vec{4, Float64}}, ::VecUnroll{3, 4, Float64, Vec{4, Float64}})
from promote(x, y, z) @ Base promotion.jl:397
Arguments
#self#::Core.Const(promote)
x::VecUnroll{3, 4, Int64, Vec{4, Int64}}
y::VecUnroll{3, 4, Float64, Vec{4, Float64}}
z::VecUnroll{3, 4, Float64, Vec{4, Float64}}
Locals
@_5::Int64
pz::VecUnroll{3, 4, Float64, Vec{4, Float64}}
py::VecUnroll{3, 4, Float64, Vec{4, Float64}}
px::Any
Body::Tuple{Any, VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}}
1 ─ nothing
│ %2 = Base._promote(x, y, z)::Tuple{Any, VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}}
│ %3 = Base.indexed_iterate(%2, 1)::Core.PartialStruct(Tuple{Any, Int64}, Any[Any, Core.Const(2)])
│ (px = Core.getfield(%3, 1))
│ (@_5 = Core.getfield(%3, 2))
│ %6 = Base.indexed_iterate(%2, 2, @_5::Core.Const(2))::Core.PartialStruct(Tuple{VecUnroll{3, 4, Float64, Vec{4, Float64}}, Int64}, Any[VecUnroll{3, 4, Float64, Vec{4, Float64}}, Core.Const(3)])
│ (py = Core.getfield(%6, 1))
│ (@_5 = Core.getfield(%6, 2))
│ %9 = Base.indexed_iterate(%2, 3, @_5::Core.Const(3))::Core.PartialStruct(Tuple{VecUnroll{3, 4, Float64, Vec{4, Float64}}, Int64}, Any[VecUnroll{3, 4, Float64, Vec{4, Float64}}, Core.Const(4)])
│ (pz = Core.getfield(%9, 1))
│ %11 = Core.tuple(x, y, z)::Tuple{VecUnroll{3, 4, Int64, Vec{4, Int64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}}
│ %12 = Core.tuple(px, py, pz)::Tuple{Any, VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}}
│ Base.not_sametype(%11, %12)
│ %14 = Core.tuple(px, py, pz)::Tuple{Any, VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}}
└── return %14 Note that julia> @code_warntype Base._promote(vxiu,vxfu,vxfu)
MethodInstance for Base._promote(::VecUnroll{3, 4, Int64, Vec{4, Int64}}, ::VecUnroll{3, 4, Float64, Vec{4, Float64}}, ::VecUnroll{3, 4, Float64, Vec{4, Float64}})
from _promote(x, y, z) @ Base promotion.jl:374
Arguments
#self#::Core.Const(Base._promote)
x::VecUnroll{3, 4, Int64, Vec{4, Int64}}
y::VecUnroll{3, 4, Float64, Vec{4, Float64}}
z::VecUnroll{3, 4, Float64, Vec{4, Float64}}
Locals
R::Type{VecUnroll{3, 4, Float64, Vec{4, Float64}}}
Body::Tuple{VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}}
1 ─ nothing
│ (R = Base.promote_typeof(x, y, z))
│ %3 = Base.convert(R::Core.Const(VecUnroll{3, 4, Float64, Vec{4, Float64}}), x)::VecUnroll{3, 4, Float64, Vec{4, Float64}}
│ %4 = Base.convert(R::Core.Const(VecUnroll{3, 4, Float64, Vec{4, Float64}}), y)::VecUnroll{3, 4, Float64, Vec{4, Float64}}
│ %5 = Base.convert(R::Core.Const(VecUnroll{3, 4, Float64, Vec{4, Float64}}), z)::VecUnroll{3, 4, Float64, Vec{4, Float64}}
│ %6 = Core.tuple(%3, %4, %5)::Tuple{VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}, VecUnroll{3, 4, Float64, Vec{4, Float64}}}
└── return %6 Julia type inference being a PITA as usual. |
I marked this as a good first issue. Then also add tests that it does infer correctly. |
I tried to do this, but it still seems somewhat complicated:
If I run your example from above promotion
I see that this does indeed remove the instability. (Of course this would not be the PR, since I am using unexported Base functions but for now its worth to try) However, my function LVTest() still does not infer correctly code_warntype output
Any ideas on how to make progress? |
Apparently, multiplying a vector of floats with a vector of ints causes problems with the julia compiler. The return type
res
cannot be inferred anymore (red::Any
) and this causes performance losses.I have tested this on Julia 1.9.3, and there the example below works fine there, but not on Julia 1.10.
Of course, one can manually promote Integers to Floats before multiplying, at least as a workaround.
Minimum working example:
The output of
versioninfo()
:The text was updated successfully, but these errors were encountered: