lapack icon indicating copy to clipboard operation
lapack copied to clipboard

C -> Fortran ABI issues in CBLAS & LAPACKE

Open jabl opened this issue 5 years ago • 5 comments

Hello,

since it's inception CBLAS seems to have assumed it's Ok to pass a length=1 string to the Fortran BLAS without passing a hidden string length argument. And the newer LAPACKE seems to have followed suit.

While this has worked (apparently adequately?) for several decades, in light of increasingly sophisticated compiler optimizations, for instance interprocedural or link-time optimizations, such sins are unfortunately coming back to haunt us.

The R developers noticed something fishy in their LAPACK interface with recent versions of GFortran. They don't use LAPACKE, but the issue is due to them also omitting the string length argument. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90329 and links to mailing list threads therein for details.

While some workarounds exist, they aren't really bulletproof, and the proper and robust fix is to change the interfaces so that they match between the caller and the callee. The problem is that there is no "standard" Fortran ABI, and different compilers use different ways to pass the hidden string length information. A couple of ways around this:

  1. Use the Fortran 2003 ISO_C_BINDING feature to create a C ABI compatible wrapper routine that can then call the actual Fortran implementation. This would be robust, but the downside is that this approach requires a Fortran compiler with the ISO_C_BINDING feature (which is all(?) actively maintained compilers these days, but if you want to retain support for old compilers this could be a problem). Also there would be an extra layer of indirection, e.g. instead of "cblas_foo -> foo" it would be "cblas_foo -> cblas_icb_foo -> foo", although it should be possible for the compiler to inline the extra wrapper.

  2. Use knowledge of compiler-specific argument passing conventions and macro magic. This is somewhat brittle, and requires fiddling with build machinery and macros, but doesn't need ISO_C_BINDING, and avoids the extra wrapper routines.

jabl avatar May 08 '19 08:05 jabl

Having thought about this issue for a while, there's also the option

  1. Rewrite CBLAS and LAPACKE in Fortran using BIND(C). That would avoid the extra wrapper issue with option 1. and the fragility of option 2.

jabl avatar Jun 20 '19 18:06 jabl

#515 closed the CBLAS part. We still need to change LAPACKE/include/lapack.h to solve this issue.

weslleyspereira avatar Mar 25 '21 18:03 weslleyspereira

I've had reason to add the LAPACK_FORTRAN_STRLEN_END info to some of the interfaces in a local copy of LAPACKE/include/lapack.h. I'm happy to go ahead and add it to all of them, but I'd like to check that I'm not duplicating work someone else has already done.

eshpc avatar May 10 '21 10:05 eshpc

Hi @eshpc. As far as I know, nobody is working on that, and it would certainly be good to have these ifdefs on LAPACKE too. Thanks!

weslleyspereira avatar May 10 '21 12:05 weslleyspereira

@weslleyspereira OK, thanks for the info. I'll submit a PR when it is ready.

eshpc avatar May 10 '21 12:05 eshpc

Solved by #515 and #561. Please, let me know if there is still something to be done.

weslleyspereira avatar May 24 '23 22:05 weslleyspereira