我有一个pyx文件,其中包含以下代码:
cimport cython
from libc.math cimport sqrt, abs
from libc.stdio cimport printf
from cython.parallel import prange
cdef double my_abs(double a):
return sqrt(a*a)
cpdef loop(int a):
cdef int i
cdef int sum = 0
for i in prange(a, nogil=True):
printf("%s %i %s %f\n", "The square root of ", i, " is ", sqrt(i))
#printf("%s %i %s %f\n", "The absolute value of ", i, " is ", abs(i))
#printf("%s %i %s %f\n", "The absolute value of ", i, " is ", my_abs(i))
return
当我取消注释循环中的两行中的任何一行时,哪个编译失败。
这个问题类似于:
谢谢!
答案 0 :(得分:3)
abs
isn't in the C standard library math.h:
这些方便的Abs重载是C ++独有的。在C语言中,abs仅在中声明(并在int值上操作)。
对于Cython没有抱怨您cimport
不存在的东西,我感到有些惊讶,但是它将使用Python abs
builtin(或者可能是经过稍微优化的Cython等效项) )。
您要使用fabs
。
答案 1 :(得分:1)
@DawidW已经指出,在这种情况下,您应该使用fabs
中的math.h
。
我想详细说明原因(据我了解):
cimport
,abs
等任何地方cython
numpy
。还是根本不导入它-保留在内置abs
中。abs
,C-abs
,fabs
,fabsf
等。例如:
%%cython
from numpy cimport abs # just for fun, "cimport" abs from numpy!
cdef do_abs(object o, int i, double d):
print(abs(o))
print(abs(i))
print(abs(d))
在这里,自动:
abs(o)
转换为__Pyx_PyNumber_Absolute
(Python的功能)abs(i)
从abs
转换为stdlib.h
abs(d)
从fabs
转换为math.h
在2.和3.情况下,不需要gil,但是从Cython的角度来看,正在使用Python-abs(即使将其映射到不同的函数)也没有定义为“ nogil”,因此需要gil。
如果我们真的从abs
导入clib.stdlib
,会发生什么?
%%cython
from libc.stdlib cimport abs
cdef do_abs(object o, int i, double d):
print(abs(o))
print(abs(i))
print(abs(d))
我们得到:
o
强制转换为C整数(在运行时可能会失败),并对其结果调用C-abs
。i
double
值用作整数(这是一件好事,由于C编译器只是将双精度值转换为整数,因此花费了很多调试时间整数(如果幸运的话,发出警告)。 主要区别:现在,将abs
用作整数参数可以使用nogil。
对您的代码有些不相关的注释:
A。定义cdef double my_abs(double a) nogil
使其能够使用nogil节。
B。我不确定,当您将python对象作为varargin传递时,Cython可以正确理解所有内容,因为它应如何推断出将Python对象强制转换为的正确类型?最好通过显式强制转换来帮助它,例如:
printf("%d %s", abs(i), <char *>"\n")