2016-06-16 11 views
1

필자는 인텔의 수학 커널 라이브러리 (mkl)에서 루틴을 사용하는 파이썬 c 확장을 작성했습니다. 이것은 내가 처음으로 c 확장자를 작성한 것입니다. 방금 배웠습니다.파이썬을위한 c 확장자에 외부 공유 인텔의 mkl 라이브러리 포함

c 확장이 컴파일되었습니다. 하지만 파이썬에서 가져올 때, 그것은 정의되지 않은 심볼을 말하고, mkl에 정의 된 함수를 찾을 수 없습니다.

외부 C 라이브러리를 파이썬 C 확장명에 포함시키는 방법은 무엇입니까?

도움 주셔서 감사합니다.

mkl_helper.c :

#include "Python.h" 
#include "numpy/arrayobject.h" 
#include "mkl.h" 

static PyObject* test4 (PyObject *self, PyObject *args) 
{ 
    // test4 (m, n, 
    //  a, ja, ia, 
    //  c, jc, ic) 

    PyArrayObject *shape_array; 
    PyArrayObject *a_array; // csr_matrix.data 
    PyArrayObject *ja_array; // csr_matrix.indices 
    PyArrayObject *ia_array; // csr_matrix.indptr 
    PyArrayObject *c_array; 
    PyArrayObject *jc_array; 
    PyArrayObject *ic_array; 

    if (!PyArg_ParseTuple(args, "O!O!O!O!O!O!O!", 
          &PyArray_Type, &shape_array, 
          &PyArray_Type, &a_array, 
          &PyArray_Type, &ja_array, 
          &PyArray_Type, &ia_array, 
          &PyArray_Type, &c_array, 
          &PyArray_Type, &jc_array, 
          &PyArray_Type, &ic_array)) 
    { 
     return NULL; 
    } 

    long * ptr_int  = shape_array->data; 
    int m    = ptr_int[0]; 
    int n    = ptr_int[1]; 
    int k    = n; 

    float * a_data_ptr = a_array->data; 
    float * ja_data_ptr = ja_array->data; 
    float * ia_data_ptr = ia_array->data; 
    float * c_data_ptr = c_array->data; 
    float * jc_data_ptr = jc_array->data; 
    float * ic_data_ptr = ic_array->data; 

    char trans = 'T'; 
    int sort = 0; 
    int nzmax = n*n; 
    int info = -3; 
    int request = 0; 

    mkl_scsrmultcsr(&trans, &request, &sort, 
     &m, &n, &k, 
     a_data_ptr, ja_data_ptr, ia_data_ptr, 
     a_data_ptr, ja_data_ptr, ia_data_ptr, 
     c_data_ptr, jc_data_ptr, ic_data_ptr, 
     &nzmax, &info); 

    return PyInt_FromLong(info); 

} 

static struct PyMethodDef methods[] = { 
    {"test4", test4, METH_VARARGS, "test2(arr1)\n take a numpy array and return its shape as a tuple"}, 
    {NULL, NULL, 0, NULL} 
}; 

PyMODINIT_FUNC 
initmkl_helper (void) 
{ 
    (void)Py_InitModule("mkl_helper", methods); 
    import_array(); 
} 

setup.py :

from distutils.core import setup, Extension 
import numpy as np 

ext_modules = [ Extension('mkl_helper', sources = ['mkl_helper.c']) ] 

setup(
     name = 'mkl_helper', 
     version = '1.0', 
     include_dirs = [np.get_include()], #Add Include path of numpy 
     ext_modules = ext_modules 
) 

test.py : 실행 test.py의

import mkl_helper 

결과 :

Traceback (most recent call last): 
    File "<string>", line 1, in <module> 
ImportError: /home/rxu/local/lib/python2.7/site-packages/mkl_helper.so: undefined symbol: mkl_scsrmultcsr 

업데이트 2016년 6월 16일는 :

이 유용 할 것으로 보인다

1.12. https://docs.python.org/2/extending/extending.html에 확장 모듈 용 C API를 제공하면 다른 c 확장에 하나의 c 확장을 포함한다고해도 공유 라이브러리로 링크하면 문제가 발생할 수 있습니다. 그래서, 내가 정적 라이브러리로 mkl을 연결해야 할 것 같아요? 또는 inlcude mkl.h를 python.h에 추가 하시겠습니까?

그러나 파이썬 (c가없는)에서는 ctypes.cdll.LoadLibrary ("./ mkl_rt.so")를 사용하여 mkl의 공유 라이브러리를로드 한 다음 문제없이 공유 라이브러리의 c 함수를 사용할 수 있습니다. in here). 그러나 파이썬/C API는 C에서 같은 일을 할 수 없습니까?

staticly 외부 C 라이브러리를 연결하는 경우, setup.py는해야 할 수도 있습니다 : 클래스 distutils.core.Extensions에서 추가 개체를 https://docs.python.org/2/distutils/apiref.html?highlight=include#distutils.ccompiler.CCompiler.add_include_dir

관련 질문에 아무 대답과 사이 썬에 대해 : Combining Cython with MKL

이 하나가 보인다 더 도움이 : Python, ImportError: undefined symbol: g_utf8_skip

되지 않습니다이 하나 개의 사용 dlopen을 : Undefined Symbol in C++ When Loading a Python Shared Library

답변

1

oopcode의 답변을 0,123,169에가 작동합니다. 다음과 같이 상황이 개선되었습니다.

파이썬에 c 확장자를 가져 오는 중에는 오류가 없습니다. 파이썬에서 c 확장자를 호출하면 다음 오류가 발생합니다. 인텔 MKL 치명적인 오류 : libmkl_mc.so 또는 libmkl_def.so를로드 할 수 없습니다.

mkl로 수동으로 numpy를 컴파일 할 때 site.cfg 파일이 라이브러리 경로를 요청하고 인텔의 mkl에 대한 경로를 포함하는 것을 기억합니다. extra_link_args 라이브러리 경로를 추가해야 할 것 같아요 ...하지만 그 작동하지 않았다.

아나콘다가있는 사람은 here과 같은 오류가 있습니다. 비슷한 케이스 인텔 포럼 here.

이 유래 질문은 extra_compile_args도 필요하다 말한다 : How to pass flag to gcc in Python setup.py script

setup.py

from distutils.core import setup, Extension 
import numpy as np 

extra_link_args=["-I", "(intel's dir)/intel/compilers_and_libraries_2016.3.210/linux/mkl/include", "-L", "(intel's dir)/intel/mkl/lib/intel64/libmkl_mc.so", "-mkl"] 
ext_modules = [ Extension('mkl_helper', sources = ['mkl_helper.c'], extra_link_args=extra_link_args) ] 


setup(
     name = 'mkl_helper', 
     version = '1.0', 
     include_dirs = [np.get_include()], #Add Include path of numpy 
     ext_modules = ext_modules 
) 

업데이트 : 나는 마침내 here 의로 일하고있어하지만 MKL stillll 단지에만 12 중 하나를 사용 cpu.