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

ENH: allow using symbol-suffixed 64-bit BLAS/LAPACK for numpy.dot and linalg #15012

Merged
merged 7 commits into from
Dec 2, 2019

Conversation

pv
Copy link
Member

@pv pv commented Nov 29, 2019

(This is partially for discussion, but should be functional:)

Add support for 64-bit BLAS/LAPACK with 64_ symbol suffix (henceforth "BLAS64_").

BLAS64_ is 64-bit BLAS with 64-bit integer interface (ILP64) with 64_ appended to all symbol names. This what you get with INTERFACE64=1 SYMBOLSUFFIX=64_ in OpenBLAS, and is the approach used by Julia. Fedora also has 64-bit OpenBLAS packages with this configuration. The point with this is that you can safely link both to 32-bit and 64-bit BLAS at the same time, without having to coordinate all packages. In particular, numpy can link to BLAS64_ and you don't get segfaults if you do import numpy from a program that also links to 32-bit BLAS (which would be the case with 64-bit BLAS/LAPACK if done in the usual way --- for ELF it mostly problem for programs embedding Python, not so much for standalone Python, but Numpy probably cares about both use cases and the 'usual' way is no-go).

See OpenMathLib/OpenBLAS#646 and JuliaLang/julia#4923 (and also #13956 , #5906 )

This PR adds numpy.distutils support for detecting OpenBLAS64_, based on the library name and checking it actually contains the correct symbols.

It adds a build-time environment variable NPY_USE_BLAS64_=1. If it's set, Numpy gets linked only with 64-bit BLAS. It's off by default for now, but it should be safe to turn it to be on by default later on.

The 64-bit BLAS functions are then used to implement cblasfuncs.c, so that numpy.dot et al. get the 64-bit goodness. Moreover, the latter commits also implement its usage in numpy.linalg.

Addresses: #5533 (if you have the right 64-bit BLAS installed). Moreover, the numpy.distutils support should be useful for all downstream libraries.

(I don't have a machine with enough memory to check this actually fixes the issues with n > 2**32-1 matrix products, but the call does end up in libopenblas64_.so so it should.)

This is an emerging "standard" for 64-bit BLAS/LAPACK, avoiding symbol
clashes with 32-bit BLAS/LAPACK, originally introduced for Julia.
OpenBLAS can be compiled with 64-bit integer size and symbol suffix
'64_' (INTERFACE64=1 SYMBOLSUFFIX=64_).  OpenBLAS built with this
setting is also provided by some Linux distributions (e.g. Fedora's
64-bit openblas packages).
This is enabled by setting NPY_USE_BLAS64_=1 environment variable at
build time.  If set, Numpy will be linked both against a 32-bit BLAS and
a symbol-suffixed 64-bit BLAS.  (This is safe and does not cause symbol
clashes thanks to the suffixing.)
…able

When Numpy is compiled with BLAS64_ enabled, use the 64-bit CBLAS
routines to provide cblasfuncs, and dot() et al.
@pv pv changed the title ENH: allow using symbol-suffixed 64-bit BLAS for numpy.dot ENH: allow using symbol-suffixed 64-bit BLAS/LAPACK for numpy.dot and linalg Nov 29, 2019
@pv pv marked this pull request as ready for review November 30, 2019 15:31
@isuruf
Copy link
Contributor

isuruf commented Dec 1, 2019

I checked with OpenBLAS and this works. I also installed a scipy with MKL and replaced libopenblas64_.so with a shared library created using MKL static libs exporting only blas, cblas, lapack symbols and renamed the symbols with a 64_ suffix. There was no crash when importing scipy and numpy and numpy called 64_ variants.

@@ -10,10 +10,20 @@
#include <assert.h>
#include <numpy/arrayobject.h>
#include "npy_cblas.h"
#include "npy_cblas64_.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the trailing _ in the name?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To match the symbol name convention.

@mattip
Copy link
Member

mattip commented Dec 1, 2019

This is really useful for people with lots of memory. We should add checks so that calling BLAS with a large array does not segfault as in this example, maybe as a separate issue since this PR is quite large as it is.

Name bikeshedding: is the 64_ name the standard?

@pv
Copy link
Member Author

pv commented Dec 1, 2019

There's of course no real standard suffix, but 64_ is used by Julia and apparently by Sunperf, and Fedora already ships packages built with it. To avoid proliferation of incompatible conventions, I believe we should not deviate from this choice.

@pv
Copy link
Member Author

pv commented Dec 1, 2019

I'll add the test in a separate PR, as we'll probably need some machinery to stop it from running on low-memory systems, which it would trash to standstill...

@mattip
Copy link
Member

mattip commented Dec 1, 2019

There is a test for large zip files that tries to allocate and skips if it cannot, with a slow marker as well so it is not typically run

@pv
Copy link
Member Author

pv commented Dec 1, 2019

The "user experience" with not checking beforehand is sometimes bad (i.e. machine hangs). gh-15021 has a more elaborate suggestion for the low-memory check.

@pv
Copy link
Member Author

pv commented Dec 1, 2019

Azure failures seem spurious ("[NuGet] The operation has timed out" when trying to install mingw).

@charris
Copy link
Member

charris commented Dec 2, 2019

Thanks Pauli. It will be good to get this out there. If nothing else it will help set the standard for the 64 bit move.

@eric-wieser
Copy link
Member

Should this have a release note?

@pv
Copy link
Member Author

pv commented Dec 2, 2019 via email

@pv
Copy link
Member Author

pv commented Dec 2, 2019 via email

@refraction-ray
Copy link

Really nice to see numpy is becoming more 64bit and all the great efforts toward this!
Curious about symbol conventions for ilp64 interface of MKL and how to link this 64bit aware numpy to mkl ilp64 interface instead of openblas. Any ideas?

@isuruf
Copy link
Contributor

isuruf commented Dec 6, 2019

@refraction-ray, to do that, you'll have to create a shared library from MKL static library exporting only the BLAS, LAPACK symbols and then renaming those symbols.

@refraction-ray
Copy link

@isuruf by renaming, you mean using GNU objcopy to rename all symbol names following the new 64bit prefix convention openblas and numpy utilized? And I am not sure about only export BLAS LAPACK symbols part. What is the danger if all symbols are exported to the new .so file and how to fast specify all BLAS and LAPACK symbols to be exported?

@isuruf
Copy link
Contributor

isuruf commented Dec 6, 2019

@isuruf by renaming, you mean using GNU objcopy to rename all symbol names following the new 64bit prefix convention openblas and numpy utilized?

yes.

What is the danger if all symbols are exported to the new .so file

There are symbols already in the MKL libs with and without 64_ suffix.

how to fast specify all BLAS and LAPACK symbols to be exported?

Use a linker script.

pv added a commit to pv/numpy that referenced this pull request Dec 14, 2019
Changing these to support ILP64 blas was missed in numpygh-15012
charris pushed a commit to charris/numpy that referenced this pull request Dec 15, 2019
Changing these to support ILP64 blas was missed in numpygh-15012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants