2017-05-30 2 views
2

J'essaie d'utiliser le produit scalaire de la bibliothèque BLAS en utilisant Cython, mais lorsque le module compilé est appelé apparaît la trace suivante "undefined symbol: cblas_ddot". Exécuter le np. config .show() pour voir les bibliothèques liées:Appel de blas ddot à partir de Cython

lapack_info: 
     libraries = ['lapack', 'lapack'] 
     library_dirs = ['/usr/lib64'] 
     language = f77 

lapack_info: 
    libraries = ['lapack', 'lapack'] 
    library_dirs = ['/usr/lib64'] 
    language = f77 

openblas_lapack_info: 
    NOT AVAILABLE 

blas_info: 
    libraries = ['cblas', 'blas'] 
    library_dirs = ['/usr/lib64'] 
    define_macros = [('HAVE_CBLAS', None)] 
    language = c 

atlas_3_10_blas_threads_info: 
    NOT AVAILABLE 

atlas_threads_info: 
    NOT AVAILABLE 

atlas_3_10_threads_info: 
    NOT AVAILABLE 

atlas_blas_info: 
    NOT AVAILABLE 

atlas_3_10_blas_info: 
    NOT AVAILABLE 

atlas_blas_threads_info: 
    NOT AVAILABLE 

openblas_info: 
    NOT AVAILABLE 

blas_mkl_info: 
    NOT AVAILABLE 

blas_opt_info: 
    libraries = ['cblas', 'blas'] 
    library_dirs = ['/usr/lib64'] 
    language = c 
    define_macros = [('NO_ATLAS_INFO', 1), ('HAVE_CBLAS', None)] 

blis_info: 
    NOT AVAILABLE 

atlas_info: 
    NOT AVAILABLE 
atlas_3_10_info: 
    NOT AVAILABLE 

lapack_mkl_info: 
    NOT AVAILABLE 

Et le ldd /usr/lib/python2.7/site-packages/numpy/core/multiarray.so et readlink -e/usr/lib/libblas.so.3 montre: /usr/lib/libblas.so.3.7.0

Donc apparemment les bibliothèques BLAS sont liées, mais ne trouvent pas le cblas_ddot. Le fichier ciboire:

import numpy as np 
cimport numpy as np 

cdef extern from "cblas.h": 
    double ddot "cblas_ddot"(int N, 
          double *X, int incX, 
          double *Y, int incY) 

ctypedef np.float64_t dtype_t 
def matmul(np.ndarray[dtype_t, ndim=2] A, 
      np.ndarray[dtype_t, ndim=2] B): 
    cdef Py_ssize_t i, j 
    cdef np.ndarray[dtype_t,ndim=2] out = np.zeros((A.shape[0],B.shape[1])) 
    cdef np.ndarray[dtype_t, ndim=1] A_row, B_col 
    for i in range(A.shape[0]): 
     A_row = A[i,:] 
     for j in range(B.shape[1]): 
      B_col = B[:, j] 
      out[i,j] = ddot(
       A_row.shape[0], 
       <dtype_t*>A_row.data, 
       A_row.strides[0] // sizeof(dtype_t), 
       <dtype_t*>B_col.data, 
       B_col.strides[0] // sizeof(dtype_t)) 

Le fichier compilation ressemble à: importation numpy

if __name__ == '__main__': 

    from distutils.core import setup 
    from distutils.extension import Extension 
    from Cython.Distutils import build_ext 


    # The Cython modules to setup 
    ext_modules = [ 
     Extension('matmul', ['matmul.pyx'], include_dirs= 
     [numpy.get_include()]) 
    ] 

    # Run the setup command 
    setup(
     cmdclass = {'build_ext': build_ext}, 
     ext_modules = ext_modules 
    ) 
+1

Pouvez-vous montrer comment vous le compilez? – DavidW

+0

Oui, monsieur, le poste a été mis à jour avec les commandes de compilation –

Répondre

0

Vous avez juste besoin de le dire pour relier la bibliothèque en setup.py:

Extension(... # as before 
    libraries=[':libcblas.so.3'] 
) 

La bibliothèque exacte peut dépendre un peu de ce que vous avez installé. Essayez d'abord 'cblas', si cela échoue rechercher quel fichier libcblas vous avez. Notez que vous devez lier à libcblas plutôt qu'à libblas.

Vous pouvez également consulter le Scipy BLAS Cython bindings pour vous faire gagner du temps en créant manuellement ce matériel (bien que je pense que ce soit pour BLAS plutôt que CBLAS).