-
Notifications
You must be signed in to change notification settings - Fork 444
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
CBLAS/LAPACKE extension for 64bit integer #666
Comments
Summon people participated in the discussions mentioned in the Related Work section: |
For Julia: @amontoison Also related: #824 |
Yes, I'm lurking... OpenBLAS currently does it by running a big objcopy after the initial build, which is far from ideal. And standardization of the expected ILP64 suffix across (at least) Julia/Go/(Num|Sci)Py is obviously desirable. |
Ok, I compiled a bit what @mkrainiuk proposed, some of us already discussed in mpimd-csc/flexiblas#12, and what I discussed with a colleague. Let us distinguish between suffixed and not suffixed. First, we have the ones without suffixes:
I would like to introduce the 32-bit and 64-bit builds with suffixes. This could be for example
Regarding the rules for suffixes for each symbol, my suggestion is this. We look at all symbols from the point of view of their native interface. That is, before the compiler does any name mangling. This means that the normal BLAS and LAPACK routines are treated in the Fortran context, and CBLAS and LAPACK from a C perspective. This keeps the approach invariant even under strange compilers and ABI definition, like using IBM/Sun compilers or macOS(like @ViralBShah reported there: mpimd-csc/flexiblas#12 (comment) ) As for the suffixes themselves, I thought of the following:
|
I do not like the additional complexity of having a libblas64.so with non-suffixed symbols, but I guess it is inevitable for backwards compatibility ? Fully agreed on the leading underscore, and on not treating the "work" interfaces as something special - after all, they are (or may be) using ILP64 internally themselves, not just doing some work for another function that happens to be ILP64. Cc @rgommers for NumPy and SciPy as the discussion seems to be gravitating towards here (we had something similar planned on a smaller scope) Maybe @kortschak or @vladimir-ch for Gonum if there is interest ? |
Gonum has a focus on floats, so I'm not sure how much interest there is in this from us. |
Thanks - discussion is entirely about large array addressing not fixed-point math. |
That allows to recompile projects with
The |
@mkrainiuk
In general, it looks as it fits the suggestions we made here. |
Thanks for the great feedback!
It's possible when the standard API is built for LP64 and the extended _64 API is built for ILP64, but it requires some code modifications for using _64 in an application:
This is a good point, I considered new header file, but it requires manual update for any new function, so for CBLAS since the number of functions is relatively small I decided to generate the macro on the fly instead. I agree that this approach won't work for LAPACKE, so I'm looking for another solution that also can make this Fortran symbol renaming automatically during the build. |
From my opinion, as mentioned before, we need three build variants. The standard build, without any special options, suffixes or similar one, that leads to the LP64 variant, as you mentioned. Then an ILP64 built without suffixes, (and
That's something nobody can guarantee and it is up to the programmer.
Since the set of functions changes only slowly, one can provide such a header file and eventually a script, which generates a new header from all the sources. One advantage of such a header file would be that one can provide it to the user as well to allow an easy migration between LP64 and ILP64 mode. |
I agree with @martin-frbg that the set of functions in LAPACK and LAPACKE changes slowly. For LAPACKE, at this point, there is no script that I am aware of and we are writing the LAPACKE layer functions by hand. This is possible because we only add a few routines at each release. Adding a layer related to LP64 / ILP64 / etc variants by hand would not be too much of an overkill. There is an exponential growth here though, but that would work. I am not asking for more work by hand but we are already generating S, C, D, Z by hand, and while not ideal that work-ish. The point is that LAPACK is slowly growing. @martin-frbg is correct. |
Different Martin but of course I agree with him :) |
First two build variants are supported. Could you please share more details why two sets of symbols in one library would be bad? If ones load one set of symbols from the library (without suffixes) and do not load another set (with suffixes) or vise versa what kind of problems it could cause? |
Right, but with the suffixes we can give a chance to programmers to ensure the correct ILP64 symbols are always used.
Agree, so the header file with manual updating could work too if I won't find a nice automatic solution. |
The case where both symbols in one Library cause problems is easily constructed... On the one hand Julia, Python load it via dlopen and flags like RTLD_GLOBAL and RTLD_NOW can be specified. And on the other hand strange cross dependencies over third level projects Like qrupdate, arpack,... In combination with different linker options and orders this leads to hard-to-debug problems. |
We implement the Also, Apple is using a different convention in Accelerate for LAPACK ILP64. We use |
I'd expect having explicit _64 in the symbol name could help in the described case, because regardless of the loaded library it always points to ILP64 implementation vs standard name that could be either LP64 or ILP64, depends on what library is picked up for the symbol resolution. |
Thank you for bringing it up. It's an interesting approach to add for the Relative Work. |
Hi all, thanks for the very useful discussion and progress on this topic. The issue description is pretty clear about the two ways this is currently done (the Julia/OpenBLAS way and the MKL/cuBLAS way), and proposes to go with the MKL/cuBLAS way - which is implemented in the C/Fortran API naming vs binary symbol namingThe The For the most important/common cases we get a single trailing underscore and hence end up with the same binary symbol names for BLAS. And different ones for CBLAS:
The story for LAPACK/LAPACKE will be the same; LAPACK will match, LAPACKE won't. Current statusWhen building current
For NumPy/SciPy we build OpenBLAS with
Julia does the same as NumPy/SciPy. I downloaded Julia 1.9.2 (the latest release) and it has a
So as in the table higher up, the BLAS symbols match with reference BLAS with If we'd instead use
Now the CBLAS symbol name matches, but the BLAS one doesn't (which is worse). For completeness I also checked what R is doing; they don't have ILP64 support in the source code of their main code base as far as I can tell. They also don't distribute Linux binaries themselves, and Windows/macOS are standalone installers - so not much to worry about there. Finally also note that for the OpenBLAS scheme:
HistoryGiven that the issue description here only mentions Julia for the
Regarding other open source projects that considered the symbol suffix topic:
Impact & changes needed to adapt to
|
I will note the one big reason for why Julia went with the alternate mangling; it's so that FORTRAN code that wants to link to these symbols can do so easily. For the Julia world in particular, because we have |
I did not implement anything in FlexiBLAS yet, since I want to see the proper solution in the reference implementation first. But I prefer the MKL style, since I works independent from the compiler's name mangling scheme and thus gives a cleaner view on the whole thing. Even though, many projects rely on the Fortran API, having consistent names in C part is necessary as well. As soon as we have a proper standard, FlexiBLAS will implement this, but with a small difference to the stuff implemented at the moment in the master branch: Each API variant will result in a separate library, as described above. Although the SunPerf library is mostly mentioned as the first occurrence of the suffixed symbols, and up to my knowledge SuiteSparse is the only project, which supports it, we can safely ignore this. This library and its hardware can be seen as legacy stuff. Especially the SunPerf BLAS approach leads to strange function names like Adjusting the symbol names in Julia and NumPy/SciPy should not be a problem since they resolve the symbols at runtime and thus the symbols name could be mangled on the fly to fit the library. IMHO the Julia/OpenBLAS way is relies too much on the name mangling done by gfortran and was implemented, as @ViralBShah said, a bit in a grotesque way. |
While that can be useful, I highly encourage library developers to not make this the default, as it tends to cause problems on operating systems that load libraries with
We have spent a lot of time and energy coming up with a naming scheme that is consistent, easily transformable from existing source code, works with a variety of compilers/languages (C, FORTRAN, etc...) and protects against symbol confusion. As said before, we use LBT to translate from other naming conventions to this one, so at some level we can adapt to anything that is decided here, but I think it highly likely that all of the software that is being built in the Julia ecosystem that uses BLAS/LAPACK will continue to be built to the current naming interface, so as to be as useful as possible to other projects, whether they be written in Julia, C, or FORTRAN. |
Sure, from a software development point of view that is a horrible thing. But I still have to deal with researchers and their code and there somebody says "Can we try this for larger examples" and thus the whole code gets compiled with the increased integer flag. For this reason the "dangerous" variant of the library is required. For all other cases, and proper software development, the suffixed API should be the way to go. |
I totally understand these kind of constraints. This is another reason why I suggest naming conventions that can be easily used within the constraints of compiler name mangling rules. In the FORTRAN example, we recompile ancient code all the time by simply adding a series of -D flags to redefine dgemm to dgemm_64, as in the example I gave above. In fact, many of our third party dependencies such as LAPACK are built with these compiler flags, defined for all BLAS and LAPACK symbols. This kind of simple renaming is not possible if we don’t follow the compiler name mangling rules, and will require source code changes in order to rebuild. |
Thanks for the replies and context @staticfloat and @grisuthedragon.
I'll note that the symbol names that end up in the binary are the same in all common cases (compiler mangling appending a single
Thanks for the correction, good to know.
I wish that that were true for NumPy/SciPy, but it isn't - it's all determined at build time. SciPy does have a layer which re-exports a C API with stable names, so for other Python packages there's no issue, they can use that. But for NumPy/SciPy it'll be quite a bit of work to adapt to this. Which I'm willing to do, but it's probably going to take a while before it's all done.
I think the key thing here is to distinguish between the "researcher wants to try this with limited effort" and the "how do we package BLAS and LAPACK for redistribution" use cases. For the former you may want the dangerous variant, and as a HPC cluster admin or some such role you may make it available to the users you support. But for the latter, you never want to deal with it. We should only ever see |
This is the wrong assumption. Regarding the IBM XLF (compilers used on POWER-based HPC systems), there is nothing added to the binaries' symbol names. Thus adding |
So long as the LAPACK build provides a way to mangle the names with whatever suffix one wants as part of the build process, different projects can take whatever approach works best. In absence of this support in the build, all of us have to resort to crude hacks. |
We haven't seen the LAPACK version of this PR yet, and looking at how the BLAS64 one handles the symbol (re)naming in the sources by resorting to CMAKE copy-and-regexreplace trickery in the build directory instead of preprocessing does not give me the highest hopes. OpenBLAS already finds out how the compiler likes to mangle symbol names, guess I will have to retain at least part of its current objcopy trickery to please everybody, even if I rewrite everything to support simultaneous provision of 32 and 64bit integer interfaces. (That simultaneous presence of blas/blas_64 symbolscould be a good thing, except I expect some distributors will then go ahead and hack it apart again to supply libblas and libblas64 for their alternatives system...) Curious coincidence that this issue got numbered after the eigenvalue of the beast :) |
Hi All, The PR for LAPACKE is merged now, please share your feedback for the changes, if you have any. If there are no concerns for the current approach I will close this issue. |
Closing as completed since the changes were merged and there is no ongoing discussion. |
Intro
CBLAS/LAPACKE wrappers support 32bit integer and 64bit integer with the same function names located in different libraries but this approach does not allow mixing both libraries in one environment because of the symbols conflict.
This FR is for discussing potential solution to avoid this problem and have stable work in any environment for the applications/libraries that has dependency on CBLAS/LAPACKE built with 64bit integer or any other projects with similar API.
Problem
Similar to Fortran API where integer with no size specified is used, CBLAS/LAPACKE API integer type can be selected by special build option during compilation.
Example for CBLAS:
lapack/CBLAS/include/cblas.h
Lines 20 to 24 in 655e588
Since C/Fortran symbols do not reflect the data type in the name in general (like C++), linker cannot detect if the resolved symbols has correct Integer type. As the result symbols mismatch could cause unexpected behavior, like incorrect results, data corruption, and segmentation fault.
Example:
Related Work
_64
suffix for 64bit integer to default LP64 interface library,_64
extension for Fortran-like LAPACK C API and CBLAS/LAPACKE API (link)_64
suffix in the name (link)Proposal
Define a suffix for API with 64bit integer support so that users can control integer type and right API call in the code and avoid any runtime conflicts
Suffix considerations
64_
suffix for all C and Fortran symbols.Please note, from the API perspective it will be two different suffixes for C and Fortran APIs:
_64
for Fortran API, because e.g.,snrm2
/snrm2_64
functions will be converted tosnrm2_
/snrm2_64_
symbols (default gfortran/ifort compilers behavior on Unix)64_
for C API in order to get same symbol suffix, because e.g.cblas_snrm2
/cblas_snrm264_
functions will be converted tocblas_snrm2
/cblas_snrm264_
symbol (default gcc/icc/clang compilers behavior)_64
, it will improve readability for function names with numbers, e.g.: for APIDGGES3
it is better to haveDGGES3_64
instead ofDGGES364
._64
suffixProposed suffix for CBLAS/LAPACK API:
_64
Please note,
_64
must be at the end of the function name for the symbol identification simplicity, including cases likeLAPACKE_dgeqrf_work
, ILP64 API will beLAPACKE_dgeqrf_work_64
, notLAPACKE_dgeqrf_64_work
Example:
Other Considerations
lapack/CBLAS/include/cblas.h
Line 134 in 655e588
The text was updated successfully, but these errors were encountered: