gpt4 book ai didi

python - 使用回调将 C 库 (GSL) 包装在 cython 代码中

转载 作者:搜寻专家 更新时间:2023-10-31 01:43:48 26 4
gpt4 key购买 nike

我是 cythonc 的新手。我想使用 cython 来加速我的代码的性能。我想在我的代码中使用 gsl_integration 库进行集成。更新:test_gsl.pyx

cdef extern from "math.h":
double log(double x) nogil
cdef extern from "gsl/gsl_math.h":
ctypedef struct gsl_function:
double (* function) (double x, void * params)
void * params

cdef extern from "gsl/gsl_integration.h":
ctypedef struct gsl_integration_workspace
gsl_integration_workspace * gsl_integration_workspace_alloc(size_t n)
void gsl_integration_workspace_free(gsl_integration_workspace * w)

int gsl_integration_qags(const gsl_function * f, double a, double b, double epsabs, double epsrel, size_t limit, gsl_integration_workspace * workspace, double *result, double *abserr)


cdef double do_callback(double x, void* params):
return (<MyCallback>params).eval(x)

cdef class MyCallback:
cdef double a
def __init__(self, a):
self.a = a
cpdef double eval(self, double x):
return self.a * log(x+1) * x
def call_gsl(self):
cdef gsl_integration_workspace* w =gsl_integration_workspace_alloc (1000)

cdef gsl_function F
F.function = &do_callback
F.params = <void*>self

cdef double result = 3, error = 5
gsl_integration_qags(&F, 0, 1, 0, 1e-7, 1000, w, &result, &error)
print result, error
gsl_integration_workspace_free(w)

.pyx 代码是使用以下 setup.py 文件编译的,不会引发任何错误消息:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy
import sys
ext = Extension("test_gsl", ["test_gsl.pyx"],
include_dirs=[numpy.get_include(),
"/usr/include/"],
library_dirs=["/usr/lib/"],
libraries=["gsl"])

setup(ext_modules=[ext],
cmdclass = {'build_ext': build_ext})

甚至使用命令行:

cython test_gsl.pyx
gcc -pthread -fno-strict-aliasing -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/vol/anaconda/lib/python2.7/site-packages -I/usr/include -I/vol/anaconda/include/python2.7 -c test_gsl.c `pkg-config --cflags gsl`
gcc -pthread -shared test_gsl.o -L/usr/lib -L/vol/anaconda/lib -lgsl -lgslcblas -lpython2.7 `pkg-config --libs gsl` -o test_gsl.so

当它在 python 中导入如下时,它确实会引发错误:

>>> import pyximport; pyximport.install()
(None, <pyximport.pyximport.PyxImporter object at 0x7f0c7e888150>)
>>> import gsl
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/anaconda/lib/python2.7/site-packages/Cython-0.20.1-py2.7-linux-x86_64.egg/pyximport/pyximport.py", line 431, in load_module
language_level=self.language_level)
File "/anaconda/lib/python2.7/site-packages/Cython-0.20.1-py2.7-linux-x86_64.egg/pyximport/pyximport.py", line 210, in load_module
mod = imp.load_dynamic(name, so_path)
ImportError: Building module gsl failed: ['ImportError: /users/dalek/.pyxbld/lib.linux-x86_64-2.7/gsl.so: undefined symbol: gsl_integration_qags\n']

gsl_integration_qags 已经正确定义了,我不明白为什么我又报错了?

最佳答案

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.

我看不出有任何理由在您的示例中需要 C++ 类,尤其是因为您通过这样做创建了不必要的间接(包装器)!如果您为了性能而使用编译语言进行编码,那么您一定要避免不必要的步骤和间接访问!你无缘无故地让你的生活变得困难,特别是因为 C 中的 GSL 例程将完成你程序中 99.9% 的计算。为什么不使用类似 cython-gsl 的东西呢?并将您的代码恢复为类似的代码(取自 cython-gsl 示例文件夹)。这要短得多,更干净,而且我看不出为什么它不能很好地执行,因为 python 没有做任何繁重的工作(假设函数 foo() 将被转换为 C,这似乎是这种情况)!

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

关于python - 使用回调将 C 库 (GSL) 包装在 cython 代码中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24513246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com