pythonc++machine-learningcythonmlpack

undefined symbol in Cython module when using mlpack


I met the problem "undefined symbol" when using mlpack in Cython. Here is my test case:

cdef extern from "<mlpack/core.hpp>" namespace "arma":
    ctypedef unsigned uword

    cdef cppclass vec:
        vec()
        vec(uword)

    cdef cppclass mat:
        mat()
        mat(uword, uword)
        void matprint "print" ()
        double& operator() (const uword, const uword)

cdef extern from "<mlpack/methods/pca/pca.hpp>" namespace "mlpack::pca":
    cdef cppclass ExactSVDPolicy:
        ExactSVDPolicy()

    cdef cppclass PCA[ExactSVDPolicy]:
        PCA()
        void Apply(const mat&, mat&, vec&, mat&)


cdef mat m = mat(4, 2)
(<double*>&m(0, 0))[0] = 1.2
(<double*>&m(1, 0))[0] = 1.0
(<double*>&m(2, 0))[0] = 0.8
(<double*>&m(3, 0))[0] = 0.6 
(<double*>&m(0, 1))[0] = 0.6
(<double*>&m(1, 1))[0] = 0.8
(<double*>&m(2, 1))[0] = 1.0
(<double*>&m(3, 1))[0] = 1.2

cdef vec eig = vec(2)
cdef mat coeff = mat(4, 2)
cdef PCA[ExactSVDPolicy] pca

m.matprint()
pca.Apply(m, m, eig, coeff)
m.matprint()

Here is the setup file:

from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension

setup(ext_modules = cythonize([Extension("pca", ["pca.pyx"], language='c++')]))

Compilation was OK, but when I import the module, python complains that:

undefined symbol: _ZN6mlpack5Timer5StartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE

I looked for the symbol, it is defined in the libmlpack.so. I put it in /usr/local/lib, which is included in LD_LIBRARY_PATH, but it seems Python does not find the symbol during runtime. Is there anyone who can help? Thanks.


Solution

  • The extension must be linked to the library it is using.

    setup(ext_modules=cythonize([Extension(
        "pca", ["pca.pyx"], language='c++'),
        libraries='mlpack',
    ]))
    

    That all symbols can be found, and libraries linked correctly, can be checked by ldd <.so>.

    See Compiling and Linking Cython documentation.