wrapping a C library (GSL) in a cython code by using callback

淺唱寂寞╮ 提交于 2019-11-30 16:34:36

First Rule: Premature optimization is the root of all evil.

Second Rule: Follow first rule at all cost.

Third Rule: Do not use C++ complex features ( complex in comparison to C - this includes classes) if there is no need for that (even if you are a C++ fanatic like I am). This is especially true if you are mixing C++ with C libraries.

I can't see any reason why C++ classes are necessary in your example, especially because you create an unnecessary indirection (the wrapper) by doing that! If you are coding in compiled language for performance, unnecessary steps and indirections is exactly want you want to avoid! You are making your life difficult for no reason, especially because is the GSL routines in C that will do 99.9% of the computations in your program. Why not just use something like cython-gsl and resume your code to something like that (taken from cython-gsl example folder). This is much shorter, cleaner and I can't see the reason why it would not perform well given that python is not doing any heavy work (assuming that the function foo() will be converted to C which seems to be the case)!

from cython_gsl cimport *

ctypedef double * double_ptr ctypedef void * void_ptr

cdef double foo(double x, void * params) nogil:
    cdef double alpha, f
    alpha = (<double_ptr> params)[0]
    f = log(alpha*x) / sqrt(x)
    return f


def main():
    cdef gsl_integration_workspace * w
    cdef double result, error, expected, alpha
    w = gsl_integration_workspace_alloc (1000)

    expected = -4.0
    alpha = 1

    cdef gsl_function F
    F.function = &foo
    F.params = &alpha

    gsl_integration_qags (&F, 0, 1, 0, 1e-7, 1000, w, &result, &error)
    print "result          = % .18f\n" % result
    print "estimated error          = % .18f\n" % error

After compiling it with the below commands:

cython test_gsl.pyx
gcc -m64 -pthread -fno-strict-aliasing -Wstrict-prototypes -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -I/usr/include -I/vol/dalek/anaconda/include/python2.7 -c test_gsl.c -o build/temp.linux-x86_64-2.7/test_gsl.o
gcc -pthread -shared -L/usr/lib/ -L/vol/dalek/anaconda/lib -o test_gsl.so  build/temp.linux-x86_64-2.7/test_gsl.o -lpython2.7  -lgsl -lgslcblas -lm

If I import test_gsl in python without pyximport, it works perfectly. Since pyximport doesn't support linking against external libraries.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!