Startup option to turn off @assert

I often use something like

@boundscheck all(x .> 0) || error()

instead of

@assert all(x .> 0)

so that I could “test run” the code first. If no error, I would then start with check-bounds=no to run the code in “performance mode”.

I know, I know, it’s not the intended designed use of @boundscheck but it works fine before v1.10. Basically it appears in every function I wrote.

Given the current performance regression of check-bounds=no since v1.10, I would ask for a startup option like to-assert=no such that I would turn off all @assert for performance.

1 Like

anyone has the same problem as mine?

I think there is no official way, yet. However, you can run your own with slight inconveniences.

You can use @static or something similar to depend on a state (a command line argument, an environment variable or something else) to conditionally define a macro to do something or not (like the checks you do with @boundscheck). Obviously, this means that the module needs to be recompiled when this state changes, but that’s the price to pay for maximum performance when the mechanism is deactivated. This is similar to what @debug does.

The inconvenience is, that the behavior now depends on this state at the time of compilation. If this state changes, Julia’s regular mechanisms won’t notice and therefore the needed recompilation won’t happen on its own. There are probably all sorts of ways how to trigger the recompilation, the most trivial might be to simply add a semicolon at the end of one of your .jl files in the module. This will change the hash and therefore trigger recompilation.

If you want you can additionally add a runtime check of this state when compiled with “test/debug mode”. This way you can quickly switch between the modes (without getting full performance, probably only worth if the tests are a bit heavier) and can still switch to full performance (but again only with recompilation).

2 Likes

could u illustrate the use of @static with command line argument?

I use check-bounds because it’s the only command line argument I could set AFAIK

there’s some discussion here Do something about `@assert` · Issue #51729 · JuliaLang/julia · GitHub

3 Likes

You can hand over arbitrary command line options after --:

> julia -e 'println(@static isempty(Base.ARGS) ? "performance" : "test")'
performance

> julia -e 'println(@static isempty(Base.ARGS) ? "performance" : "test")' -- --my-custom-option
test

Obviously, you would use a more robust check than this and do something else in your code than providing the code directly and only doing conditional printing.

4 Likes

I don’t understand @static

in your example. What’s the difference without using @static ?

When providing the code to execute as in my example, there is no practical difference. However, when you have that code in a .jl file within a package, you’ll notice the difference.

Without @static it will do a runtime check. In your use case, all(x .> 0) will not be checked, but a test whether this needs to be calculated is still evaluated.

With @static the test whether to calculate all(x .> 0) is removed, too, during precompilation of your module.

1 Like

Probably a bad idea. The --check-bounds=no setting actually often makes performance worse, because it inhibits the Julia compiler’s inference and optimization.

1 Like

@static does the branch at macro expansion time, which is during load time.

1 Like

performance regression in bounds-check=no is definitely not a desirable outcome and it led to a lot of discussions recently.

1 Like