JuliaHub is happy to announce a new open source tool for static code analysis to prove that a Julia function is allocation-free. Use this to ensure that codes are safe for real-time applications, such as how we use it for JuliaSim to analyze SciML control codes!
Would it be possible to use the same technique from outside a function, to check in the tests for example that a given function signature cannot allocate? Because I can imagine that people don’t always want to have the dynamic dispatch behavior in their actual package but it seems currently you have to apply it to the actual function. You could of course do a wrapper function with the same arguments but it seems tedious maybe
Hard agree on making that the main interface instead of the current method-level annotation. I don’t see myself using this on functions on the critical path, where not getting dynamic dispatch is as important (if not more so) as not getting allocations.
It’s a tool, you can use it however you want. The README example is just one way. There’s two main ways we are starting to make use of the new tool. The first one is to create unit tests that enforce that package code does not allocate in its inner loops. This makes sure that performance doesn’t regress.
But the second way is to ensure builds are safe. When we are building for safety-critical real-time applications, you want to ensure that the real-time loop has certain properties, such as not allocating and thus having no GC pauses. What you can do is add this macro to the binary build so that you have a confirmation that your binary will only build if this property is satisfied, otherwise you get an error before deployment.
This is really exciting for real time work in Julia!
The last missing piece IMO will be to opt-out functions from GC pauses caused by other threads if the have been proved allocation-free by this macro.
In our current application we have pairs of hard real time and non latency-critical supervisory threads. At the moment, too many allocations on the supervisory thread cause the real time one to pause too.
Can it be extended to check for locks/files/sleep/sockets? Note that Compare-and-Swap (CAS) and similar paradigms are okay.
At the recent Audio Developer Conference, I saw a Clang-based tool that hijacks malloc from libc and errors at runtime. Since it is not just a static check, it will also work for code that you did not write, but merely linked to.
Also if I’m not gravely misunderstanding something, profiling a call signature seems more properly “static”. The macro’ed function needs to be called with runtime inputs to count allocations and does return a value, though the allocations are supposedly searched in the IR itself so the input values and code execution doesn’t sound strictly necessary.
On second thought, I don’t think this would work. For the call to have an effect, LLVM must be able to infer that x and y don’t alias from the fact that Base.mightalias(x, y) is false, but I’m not sure that’s even possible.