Keyword arguments preventing eliding boundscheck

OmarElrefaei
Wed, 01 Mar 2023 19:59:36 +0000
Performance

So I’ve got a MWE here with a weird behavior.
Note: this seems to be actually fixed in v1.9. But I couldn’t track any relevant issues to PR.

I’m trying to elide some checking code with @boundscheck. (yes, the real use case is a numerical hot loop)

At first I was experimenting with positional arguments:

f2(x, a=0) = @boundscheck "not elided!"
Base.@propagate_inbounds f3(x, a=0) = @boundscheck "not elided!"

function caller(x)
    @inbounds @show f2(x)
    @inbounds @show f2(x, 2)

    @inbounds @show f3(x)
    @inbounds @show f3(x, 2)
    nothing
end
caller(0)

# f2(x) = "not elided!"
# f2(x, 2) = nothing
# f3(x) = nothing
# f3(x, 2) = nothing

After I figured out how to work with @inbounds and @boundscheck properly, I faced some trouble with optional arguments (f2).
But I figured it was because f2(x) was calling f2(x, a) without the “inbound-dedness” so f2(x) boundschecks was not elided. This was fixed with propagate_inbounds.

But now when I also found out the hard way that a similar thing appears to happen with keyword arguments and is not easily fixed.

f4(x; k=0) = @boundscheck "not elided!"
@propagate_inbounds f5(x; k=0) = @boundscheck "not elided!"

function caller(x)
    @inbounds @show f4(x)
    @inbounds @show f4(x, k=2)

    @inbounds @show f5(x)
    @inbounds @show f5(x, k=2)
    nothing
end
caller(0)

# f4(x) = "not elided!"
# f4(x, k = 2) = "not elided!"
# f5(x) = nothing
# f5(x, k = 2) = "not elided!"

Does anyone know of a possible cause for specifying keyword argument to prevent proper inlining or skipping boundchecks?
Or maybe there is a common workaround?
I’ve tried removing the default value of 2 and/or specifying type k::Int64 but neither changes the behavior.
@code_typed does show very obviously the difference between v1.8.5 and v1.9 (click for more details)
3 posts - 2 participants