[Numpy-discussion] Calling BLAS functions from Python
Jens Jørgen Mortensen
jjmo at dtu.dk
Tue Aug 27 07:18:42 EDT 2019
Hi!
I'm trying to use dgemm, zgemm and friends from scipy.linalg.blas to
multiply matrices efficiently. As an example, I'd like to do:
c += a.dot(b)
using whatever BLAS scipy is linked to and I want to avoid copies of
large matrices. This works the way I want it:
>>> import numpy as np
>>> from scipy.linalg.blas import dgemm
>>> a = np.ones((2, 3), order='F')
>>> b = np.ones((3, 4), order='F')
>>> c = np.zeros((2, 4), order='F')
>>> dgemm(1.0, a, b, 1.0, c, 0, 0, 1)
array([[3., 3., 3., 3.],
[3., 3., 3., 3.]])
>>> print(c)
[[3. 3. 3. 3.]
[3. 3. 3. 3.]]
but if c is not contiguous, then c is not overwritten:
>>> c = np.zeros((7, 4), order='F')[:2, :]
>>> dgemm(1.0, a, b, 1.0, c, 0, 0, 1)
array([[3., 3., 3., 3.],
[3., 3., 3., 3.]])
>>> print(c)
[[0. 0. 0. 0.]
[0. 0. 0. 0.]]
Which is also what the docs say, but I think the raw BLAS function dgemm
could do the update of c in-place by setting LDC=7. See here:
http://www.netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html
Is there a way to call the raw BLAS function from Python?
I found this capsule thing, but I don't know if there is a way to call
that (maybe using ctypes):
>>> from scipy.linalg import cython_blas
>>> cython_blas.__pyx_capi__['dgemm']
<capsule object "void (char *, char *, int *, int *, int *,
__pyx_t_5scipy_6linalg_11cython_blas_d *,
__pyx_t_5scipy_6linalg_11cython_blas_d *, int *,
__pyx_t_5scipy_6linalg_11cython_blas_d *, int *,
__pyx_t_5scipy_6linalg_11cython_blas_d *,
__pyx_t_5scipy_6linalg_11cython_blas_d *, int *)" at 0x7f06fe1d2ba0>
Best,
Jens Jørgen
More information about the NumPy-Discussion
mailing list