Refactor calcfc_internal to remove nested function#218
Conversation
This is in support of efforts to integrate PRIMA with SciPy. They provide wheels for musl, and in musl you cannot have nested functions in Fortran (at least, not without gcc 14, which is cutting edge, and therefore it's not practical for scipy to switch to it).
|
Separately I am working on some other PRs to merge the changes in my repo back into this one. Stay tuned for those over the next couple days. |
|
Thank you, Nickolai. However, I would like to propose another solution for the nested functions:
Alternatively, we can also include a script in The reason for this solution is as follows. The code of PRIMA is supposed to be the reference implementation, which is its name (if we only need something that works, then Powell's F77 version is fine and we would not need PRIMA at all, but I suppose you know very well that Powell's code does not work well as a reference implementation). The nested subroutine is indeed the mathematically correct implementation. We should not sacrifice the correctness due to compiler issues. If we change the code, then 10 years later, when gcc-14.0+ becomes the most popular compilers, we need to change it back to the correct version. This makes the code not future-proof, contradicting the "Why" of PRIMA:
Similar things have already been done in the Fortran version and MATLAB binding. PRIMA never sacrifices correctness and clarity for compiler's fault, which is not a strange thing to me (See also https://github.com/zequipe/test_compiler). Thank you. |
|
Why is the nested function mathematically correct? Or maybe a better question, why is refactoring the code to not be a nested function mathematically incorrect? |
|
Because We also have to take into account the consistency among the solvers. See how |
|
I think it's better to avoid compiling with an executable stack if possible. Removing the nested function here means that we could do that when compiling the Fortran code without bindings (since, as we discussed, we prefer to keep the nested functions in the bindings because the only alternative is a global variable which breaks thread safety). That said, it's not something that anyone has complained about so I don't feel particularly strongly about it at the moment and I'm ok with closing this PR until someone complains about it (in which case we can try to direct them to gcc 14's |
This was done to support building on musl back when we were hoping to include the Python bindings into scipy. Even though we will likely use gcc14 to support musl for any potential release of the bindings as a separate package (gcc14 with -ftramponine-impl=heap allows for nested functions), we can refactor this code to not require a nested function in the first place, which I think is a preferable solution.
Of course this doesn't remove the nested functions in the bindings themselves, which we need to keep, but if we have the opportunity to avoid using a nested function I think we should do so.