2

I am trying to compile a Cython program, but I get an error trying to link LAPACK and BLAS (it can't find the libraries). I have Anaconda Accelerate, which automatically links MKL to NumPy, so I tried to copy NumPy's link.

>>> import numpy as np
>>> np.show_config()
mkl_info:
    include_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/include']
    define_macros = [('SCIPY_MKL_H', None)]
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/lib']
blas_mkl_info:
    include_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/include']
    define_macros = [('SCIPY_MKL_H', None)]
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/lib']
lapack_mkl_info:
    include_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/include']
    define_macros = [('SCIPY_MKL_H', None)]
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/lib']
blas_opt_info:
    include_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/include']
    define_macros = [('SCIPY_MKL_H', None)]
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/lib']
openblas_lapack_info:
  NOT AVAILABLE
lapack_opt_info:
    include_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/include']
    define_macros = [('SCIPY_MKL_H', None)]
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['/home/ubuntu/miniconda3/envs/LDFMap/lib']

So this is my setup.py file

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
import numpy as np
import os

setup(
    author = "Rohan Pandit",
    url='https://www.github.com/rohanp/LDFMap',
    ext_modules = cythonize([Extension("LDFMap",
                            sources = ["LDFMap.pyx"],
                            include_dirs = [np.get_include(), "/home/ubuntu/LDFMap/src/include", "/home/ubuntu/miniconda3/envs/LDFMap/include"],
                            language="c++",
                            libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread'],
                            library_dirs = ["/home/ubuntu/LDFMap/src/include", '/home/ubuntu/miniconda3/envs/LDFMap/lib'],
                            extra_compile_args = ["-I /home/ubuntu/LDFMap/src/include", "-I /usr/local/include"],
                                        )])

        )

and here is my error message: (I added line breaks for readability)

g++ -pthread -shared -L/home/ubuntu/miniconda3/envs/LDFMap/lib -Wl,  
-rpath=/home/ubuntu/miniconda3/envs/LDFMap/lib,--no-as-needed 
build/temp.linux-x86_64-3.4/LDFMap.o -L/home/ubuntu/LDFMap/src/include
-L/home/ubuntu/miniconda3/envs/LDFMap/lib -
L/home/ubuntu/miniconda3/envs/LDFMap/lib -lmkl_lapack95_lp64 - 
lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread - 
lpython3.4m -o /home/ubuntu/LDFMap/src/LDFMap.cpython-34m.so 

/usr/bin/ld: cannot find -lmkl_lapack95_lp64

What I don't understand is if this link worked for NumPy, why isn't it working for my program?

rohanp
  • 610
  • 1
  • 8
  • 20

1 Answers1

3

Specifying explicitly the include path and BLAS/LAPACK libraries for your installation is going to lead to a very platform dependent and difficult to maintain module.

What you should do instead, is to use scipy to get the pointer to the LAPACK functions you need, as explained in this post (see in particular the gist in the first link). This way, if Scipy was installed with MKL, your Cython program will also use automatically use MKL BLAS/LAPACK.

rth
  • 10,680
  • 7
  • 53
  • 77
  • I tried `from scipy.linalg.cython_lapack cimport dgesvd`, (dgesvd is needed by a C++ header file that I use), but I still get an error: `Symbol not found: _dgesvd_` (I've tried ... `cimport dgesvd as _dgesvd_` and ... `cimport dgesvd as dgesvd_`) – rohanp Jul 28 '15 at 14:30
  • @rohanp That will only work for `>=scipy-0.16`, for earlier versions of scipy, you need to do the whole `f2py_pointer(scipy.linalg.blas.dgemm._cpointer)` etc (e.g. for dgemm), as explained in that gist. – rth Jul 28 '15 at 15:01
  • 1
    I am using scipy-0.16. The error occurs not at compile time, but at run time. Could it have to do with the fact that I'm calling dgesvd in an external C++ function that I import using `cdef extern`? – rohanp Jul 30 '15 at 03:18
  • 1
    Do you know how to link the mkl libraries in anaconda with C++ code? – Chris Apr 12 '19 at 16:28