I have been learning to use JET.jl to improve the performance of my code. I am still getting familiar with its output. I would appreciate some help understanding why the function below produces a runtime dispatch warning in @report_opt
.
Basically, what we do is define a struct Rectangle
, overload isless()
to sort rectangles by their area, then create a function that generates m
random rectangles and finds the largest one and its index.
julia> import Base.isless
julia> using JET
julia> struct Rectangle
width::Float64
height::Float64
end
julia> isless(r1::Rectangle, r2::Rectangle) = isless(r1.width * r1.height, r2.width * r2.height)
isless (generic function with 44 methods)
julia> function largestrandomrectangle(m::Int)
rects = Rectangle[Rectangle(rand(), rand()) for _ in 1:m]
findmax(rects)
end
largestrandomrectangle (generic function with 1 method)
julia> @report_opt largestrandomrectangle(100)
βββββ 2 possible errors found βββββ
β @ REPL[5]:2 Main.rand()
ββ @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.8/Random/src/Random.jl:257 #self#(Random.default_rng(), Random.Float64)
βββ @ /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.8/Random/src/Random.jl:257 Random.Val(1)
ββββ @ essentials.jl:714 %1()
ββββ runtime dispatch detected: %1::Type{Val{_A}} where _A()
βββββββββββββββββββββββββ
β @ REPL[5]:4 Main.findmax(rects)
ββ @ reducedim.jl:1159 Base.#findmax#821(Base.:, #self#, A)
βββ @ reducedim.jl:1159 Base._findmax(A, dims)
ββββ @ reduce.jl:911 Base.findmax(Base.identity, a)
βββββ @ reduce.jl:885 Base.mapfoldl(#275, Base._rf_findmax, Base.pairs(domain))
ββββββ @ reduce.jl:162 Base.#mapfoldl#257(Base._InitialValue(), #self#, f, op, itr)
βββββββ @ reduce.jl:162 Base.mapfoldl_impl(f, op, init, itr)
ββββββββ @ reduce.jl:44 Base.foldl_impl(opβ², nt, itrβ²)
βββββββββ @ reduce.jl:49 Base.reduce_empty_iter(op, itr)
ββββββββββ @ reduce.jl:370 Base.reduce_empty_iter(op, itr, Base.IteratorEltype(itr))
βββββββββββ @ reduce.jl:371 Base.reduce_empty(op, Base.eltype(itr))
ββββββββββββ @ reduce.jl:348 Base.mapreduce_empty(#275, $(QuoteNode(Base.BottomRF{typeof(Base._rf_findmax)}(Base._rf_findmax))), _)
ββββββββββββ runtime dispatch detected: Base.mapreduce_empty(#275, $(QuoteNode(Base.BottomRF{typeof(Base._rf_findmax)}(Base._rf_findmax)))::Base.BottomRF{typeof(Base._rf_findmax)}, _::Type{Pair{Int64, Rectangle}})
βββββββββββββββββββββββββββββ
The first issue shows up even if you call @report_opt rand()
, so I am not sure I can do anything about it.
The second issue is what confuses me. I think what it is saying is that my function will error if the rects
is empty (i.e. if m=0
). But that is exactly what I want to happen!
julia> findmax(Rectangle[])
ERROR: MethodError: reducing over an empty collection is not allowed; consider supplying `init` to the reducer
Am I safe to ignore the warning, or will I actually obtain better performance by modifying largestrandomrectangle()
to return some kind of dummy object for empty input?