一些标准的 C 库数学运算与 noGIL 不兼容
Some standard C library math operations don't play nice with noGIL
我有一个包含以下代码的 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
当我取消注释循环中两行中的任何一行时,编译失败。
- 为什么 libc.math abs 函数不能很好地与 nogil 一起使用,而 sqrt、pow 等其他函数似乎可以?
- 我必须向我的函数(和 .pxd 文件)添加什么才能使其成为 nogil?我已经尝试添加以下页面 https://lbolla.info/python-threads-cython-gil 但它仍然无法编译。
这个问题类似于:
提前致谢!
abs
isn't in the C standard library math.h:
These convenience abs overloads are exclusive of C++. In C, abs is only declared in (and operates on int values).
我有点惊讶 Cython 没有抱怨你 cimport
ing 一些不存在的东西,但它会使用 Python abs
builtin(或可能是稍微优化的 Cython 等价物)。
您需要 fabs
。
正如@DawidW 已经指出的那样,您应该在您的案例中使用 math.h
中的 fabs
。
我想详细说明一下原因(据我了解):
- 这可能是一个错误:他们可以从任何地方
cimport
abs
:cython
、numpy
等等。或者根本不导入它 - 这仍然是内置 abs
.
- Cython 尝试通过 C 对应的内置函数替换 Python 功能,整个列表 is here。根据输入的类型Python-
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)
从 stdlib.h
翻译成 abs
abs(d)
从 math.h
翻译成 fabs
在 2. 和 3.gil 的情况下不需要,但是从 Cython 的角度来看 Python-abs 正在使用中(即使它被映射到不同的函数)这不是定义为 "nogil",因此需要 gil。
如果我们真的从 clib.stdlib
导入 abs
会发生什么?
%%cython
from libc.stdlib cimport abs
cdef do_abs(object o, int i, double d):
print(abs(o))
print(abs(i))
print(abs(d))
我们得到:
- Cython 尝试将
o
转换为 C 整数(这可能会在 运行 时间内失败)并对其结果调用 C-abs
。
- 对整数使用 C-abs
i
- 不编译,因为 Cython 阻止将
double
值用作整数(这是一件好事,因为 C 编译器只转换双精度值,所以花费了很多调试时间到一个整数(如果幸运的话会发出警告))。
主要区别:使用 abs
作为整数参数现在允许 nogil。
对您的代码有些不相关的评论:
一个。定义 cdef double my_abs(double a) nogil
以便能够将其用作 nogil-section。
乙。我不确定,当您将 python-object 作为 varargin 传递时,Cython 是否正确理解所有内容,因为它应该如何推断 Python-object 应该被强制转换为的正确类型?最好通过显式转换来帮助它,例如:
printf("%d %s", abs(i), <char *>"\n")
我有一个包含以下代码的 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
当我取消注释循环中两行中的任何一行时,编译失败。
- 为什么 libc.math abs 函数不能很好地与 nogil 一起使用,而 sqrt、pow 等其他函数似乎可以?
- 我必须向我的函数(和 .pxd 文件)添加什么才能使其成为 nogil?我已经尝试添加以下页面 https://lbolla.info/python-threads-cython-gil 但它仍然无法编译。
这个问题类似于:
提前致谢!
abs
isn't in the C standard library math.h:
These convenience abs overloads are exclusive of C++. In C, abs is only declared in (and operates on int values).
我有点惊讶 Cython 没有抱怨你 cimport
ing 一些不存在的东西,但它会使用 Python abs
builtin(或可能是稍微优化的 Cython 等价物)。
您需要 fabs
。
正如@DawidW 已经指出的那样,您应该在您的案例中使用 math.h
中的 fabs
。
我想详细说明一下原因(据我了解):
- 这可能是一个错误:他们可以从任何地方
cimport
abs
:cython
、numpy
等等。或者根本不导入它 - 这仍然是内置abs
. - Cython 尝试通过 C 对应的内置函数替换 Python 功能,整个列表 is here。根据输入的类型Python-
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)
从stdlib.h
翻译成 abs(d)
从math.h
翻译成
abs
fabs
在 2. 和 3.gil 的情况下不需要,但是从 Cython 的角度来看 Python-abs 正在使用中(即使它被映射到不同的函数)这不是定义为 "nogil",因此需要 gil。
如果我们真的从 clib.stdlib
导入 abs
会发生什么?
%%cython
from libc.stdlib cimport abs
cdef do_abs(object o, int i, double d):
print(abs(o))
print(abs(i))
print(abs(d))
我们得到:
- Cython 尝试将
o
转换为 C 整数(这可能会在 运行 时间内失败)并对其结果调用 C-abs
。 - 对整数使用 C-abs
i
- 不编译,因为 Cython 阻止将
double
值用作整数(这是一件好事,因为 C 编译器只转换双精度值,所以花费了很多调试时间到一个整数(如果幸运的话会发出警告))。
主要区别:使用 abs
作为整数参数现在允许 nogil。
对您的代码有些不相关的评论:
一个。定义 cdef double my_abs(double a) nogil
以便能够将其用作 nogil-section。
乙。我不确定,当您将 python-object 作为 varargin 传递时,Cython 是否正确理解所有内容,因为它应该如何推断 Python-object 应该被强制转换为的正确类型?最好通过显式转换来帮助它,例如:
printf("%d %s", abs(i), <char *>"\n")