Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Building from OpenBLAS 0.3.21 error due to LAPACK_FORTRAN_STRLEN_END #3877

Closed
mfauvel opened this issue Dec 26, 2022 · 5 comments
Closed

Building from OpenBLAS 0.3.21 error due to LAPACK_FORTRAN_STRLEN_END #3877

mfauvel opened this issue Dec 26, 2022 · 5 comments

Comments

@mfauvel
Copy link

mfauvel commented Dec 26, 2022

Hello,

I have a c function that use dpbrtf as follows

 dpbtrf_("U", n_, order_, Ab, ldab, info)

The program compiled and openblas was provided by the debian repo of my distribution:

libopenblas-dev/stable,now 0.3.13+ds-3 amd64  [installé]
  Optimized BLAS (linear algebra) library (dev, meta)

And it runs fine (assessed with some handcrafted tests). I try to use the last openblas version (0.3.21) : the compilation was fine but when I try to compile my program with the new openblas library I got an error because of missing argument:

gcc -I /opt/OpenBLAS/include/ -L /opt/OpenBLAS/lib/ -O3 -Wall -pedantic -fpic -shared -o shared_function.so ref_c_func.c -lopenblas -fopenmp -lgfortran
ref_c_func.c: In functionbatch_cholesky_banded’:
ref_c_func.c:579:7: error: too few arguments to functiondpbtrf_579 |       dpbtrf_("U", n_, order_, Ab, ldab, info);
      |       ^~~~~~~
In file included from /opt/OpenBLAS/include/lapack.h:11,
                 from ref_c_func.c:5:
/opt/OpenBLAS/include/lapack.h:12304:42: note: declared here
12304 | #define LAPACK_dpbtrf_base LAPACK_GLOBAL(dpbtrf,DPBTRF)
      |                                          ^~~~~~
/opt/OpenBLAS/include/lapacke_mangling.h:12:39: note: in definition of macroLAPACK_GLOBAL12 | #define LAPACK_GLOBAL(lcname,UCNAME)  lcname##_
      |                                       ^~~~~~
/opt/OpenBLAS/include/lapack.h:12305:6: note: in expansion of macroLAPACK_dpbtrf_base12305 | void LAPACK_dpbtrf_base(
      |      ^~~~~~~~~~~~~~~~~~

When I check in lapack.h, I see that when LAPACK_FORTRAN_STRLEN_END is defined it adds a new parameter to the function dpbtrf_ (from lapack.h)

#define LAPACK_dpbtrf_base LAPACK_GLOBAL(dpbtrf,DPBTRF)
void LAPACK_dpbtrf_base(
    char const* uplo,
    lapack_int const* n, lapack_int const* kd,
    double* AB, lapack_int const* ldab,
    lapack_int* info
#ifdef LAPACK_FORTRAN_STRLEN_END
    , size_t
#endif
);
#ifdef LAPACK_FORTRAN_STRLEN_END
    #define LAPACK_dpbtrf(...) LAPACK_dpbtrf_base(__VA_ARGS__, 1)
#else
    #define LAPACK_dpbtrf(...) LAPACK_dpbtrf_base(__VA_ARGS__)
#endif

I try to comment the line #define LAPACK_FORTRAN_STRLEN_END : the program now compile but I get a segmentation fault.

I don't know how to handle this point: I search but I did not find what is the meaning of the parameter size_t and how to provide this value to the function ?

I am aware of the FAQ to replace the library (https://github.com/xianyi/OpenBLAS/wiki/faq#replacing-system-blasupdating-apt-openblas-in-mintubuntudebian).

ps: the objective of using compiled version of openblas is to use my program on another computer were I cannot install packages.

@mfauvel
Copy link
Author

mfauvel commented Dec 26, 2022

Ok my bad, when I build the openblas library with the option FC=gfortran I do not have any segmentation fault and I got correct result.

Still, I need to comment the line #define LAPACK_FORTRAN_STRLEN_END before compiling my program.

I don't understand why there is one more parameter with the function per default now ?

@martin-frbg
Copy link
Collaborator

This is a change introduced with recent LAPACK version 3.10 (which OpenBLAS imports from the Reference-LAPACK project (also known as "netlib").
The background is that string handling differs between C and Fortran such that the Fortran compiler needs to be told the length of each string argument via extra arguments added at the end of the list. Many old codes do/did not fo this for single-character arguments, and it was argued that this meant relying on undefined behaviour.
see #2154 and related Reference-LAPACK/lapack#339

@mfauvel
Copy link
Author

mfauvel commented Dec 27, 2022

Many thanks @martin-frbg for your explanation. However, I am not sure about the correct way to modify my code:

  • Should I add 1 (or any number, but from the lapack.h it seems to be 1) at the end of my call to dpbtrf such as dpbtrf_("U", n_, order_, Ab, ldab, info, 1)
  • Or comment the definition of LAPACK_FORTRAN_STRLEN_END is a correct way to handle this change. But in that case, as far as I understand, we do no tell to the copmpiler the length of the strings ?

@martin-frbg
Copy link
Collaborator

martin-frbg commented Dec 27, 2022

The correct way should be to add the "1" for the length of the single-character "U" argument at the end of your dpbtrf line, but as you wrote you could also comment the definition of LAPACK_FORTRAN_STRLEN_END to stay with the old behaviour (which has been implicated in a few otherwise unexplained problems as seen in the Reference-LAPACK issue ticket and others mentioned therein).
Some discussion happened in Reference-LAPACK/lapack#604 - from that two possible solutions would be to (a) always use the corresponding LAPACKE interface instead of calling a LAPACK function directly or (b) have your own code check if LAPACK_FORTRAN_STRLEN_END is defined and supply arguments accordingly

@mfauvel
Copy link
Author

mfauvel commented Dec 27, 2022

Thanks @martin-frbg. I close the issue.
Best wishes

@mfauvel mfauvel closed this as completed Dec 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants