Hello,
I am asking for some general guidance on the following task,
There is a legacy code, written in C, that I would like to use directly in Julia. Ideally, I would like to be able to differentiate it as well (the code can be found here ).
So, my questions are:
which tools should I be using to write a Julia-wrapper? Clang.jl?
Assuming the first step work, how difficult would it be to differentiate it with Enzyme? Which constraint does this put on how the original code and the wrapper must be written?
I made the lightweight wrapper CLASS.jl package to simplify comparisons to SymBoltz.jl. Feel free to check it out and change it around. Check test/ for some simple examples and here (expand “Setup”) for a more complex one. It is structured like a problem/solution interface fairly generically around CLASS’ input/output structure.
Right now it requires you to point it to a local CLASS binary. It would be much more elegant to automatically compile it at installation or something.
Base Julia is technically enough for calling C shared libraries, though packages can help. Enzyme works on LLVM so you could use it directly on C. I haven’t seen a tutorial on Enzyme for Julia calling external code, but I’ve heard it’s possible (not necessarily implemented) if the LLVM IR is there. I’d suggest changing your topic’s title to mention autodifferentiation of Julia wrapping C, get more experienced eyes on this.
To differentiate through CLASS and make it compatible with Enzyme, should one perhaps look to modify it so there is a pure C function that one can ccall from Julia (like here) to return the desired output as a function of some given input parameters? Maybe something like this:
If so, that would require circumventing the standard interface with *.ini input configuration files and *.dat output data files.
I think it would be very interesting to try to start with something trivial, say just computing \Omega_{c0}(\omega_{c0}) = \omega_{c0}/h^2 as a function of \omega_{c0} (and some fixed h). Then, if that works, one could try to include more parameters and ramp up autodiff module-by-module (background, thermodynamics, perturbations, …) and ultimately get the C_l for the CMB as a function of some parameters or something similar.