我正在使用prange
来修改数组。我尝试在cython编译器生成的HTML页面中尽可能少的黄线:
cython function_prange.pyx -a
但是当提取数组的一部分来修改它时,我总是会生成这样的代码:
{
#ifdef WITH_THREAD
PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
#endif
#ifdef _OPENMP
#pragma omp flush(__pyx_parallel_exc_type)
#endif /* _OPENMP */
if (!__pyx_parallel_exc_type) {
__Pyx_ErrFetchWithState(&__pyx_parallel_exc_type, &__pyx_parallel_exc_value, &__pyx_parallel_exc_tb);
__pyx_parallel_filename = __pyx_filename; __pyx_parallel_lineno = __pyx_lineno; __pyx_parallel_clineno = __pyx_clineno;
__Pyx_GOTREF(__pyx_parallel_exc_type);
}
#ifdef WITH_THREAD
PyGILState_Release(__pyx_gilstate_save);
#endif
}
是否可以避免这些__Pyx_ErrFetchWithState
/ __Pyx_ErrRestoreWithState
?这真的很重要吗?
以下是我正在使用的代码:
第一个函数在 function_nogil.pyx
中向一个大小为1的数组中的矩阵的对角线添加一个doubleimport cython
@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False) # turn off negative index wrapping for entire function
cdef void add_diag(double [:,:,:] a, int a_len, int a_wid, double coeff) nogil:
cdef int x_max = a_len
cdef int x
for x in xrange(x_max):
a[0,x,x] = a[0,x,x] + coeff
function_nogil.pxd
中的标题cdef void add_diag(double [:,:,:] a, int a_len, int a_wid, double coeff) nogil
在 function_prange.pyx中使用prange
的功能
@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False) # turn off negative index wrapping for entire function
def prange_loop_idx(double [:,:,:] a, int a_dim1, int a_dim2, int a_dim3, double coeff,int num_threads):
cdef int i = 0
with nogil,parallel(num_threads=num_threads):
for i in prange(a_dim1):
add_diag(a[i:i+1:,],a_dim2,a_dim3,coeff)
答案 0 :(得分:1)
它没有它看起来那么糟糕。当你查看完整的C代码时,你会发现这只是一个错误处理代码,只有在出现错误情况后才能通过powershell.exe -file "stuff.ps1" "ValueforParam1" "ValueForParam2"
跳转到它来执行。
(错误条件是它检查memoryview切片是否构造正确 - 我认为这是使用切片而不是单个索引的结果。将步骤设置为0会在此处触发错误。)< / p>
所以你有一些额外的错误检查可能并非严格必要,但我认为单独留下是明智的(在我的电脑上就是这条线):
goto
但你担心的实际代码在正常操作中没有被调用,因此几乎没有成本,你可以忽略。
我认为if (unlikely(__pyx_memoryview_slice_memviewslice(
&__pyx_t_4,
__pyx_v_a.shape[0], __pyx_v_a.strides[0], __pyx_v_a.suboffsets[0],
0,
0,
&__pyx_t_5,
__pyx_v_i,
(__pyx_v_i + 1),
0,
1,
1,
0,
1) < 0))
{
__PYX_ERR(0, 21, __pyx_L12_error)
}
和parallel
生成的代码可能足够复杂,以至于生成的html文件在向您显示正确位时并非100%有用,这就是您看到的原因它链接到该行,但您没有看到我上面显示的错误检查代码。