我有一个复杂的Cython函数,在过去的72小时里开始表现得非常奇怪。你知道吗
我们正在用一个稀疏COO矩阵做一些事情,这个矩阵需要在COO表示的列索引上循环。因为我想快速完成这项工作,所以我将提取的列值粘贴到一个类型化的C变量中,如下所示:
ranked_groups = A[local_ranked,:].tocoo()
ranked_groups_col_c = ranked_groups.col.astype(np.int32)
奇怪的是,有时ranked_groups_col_c
的内容会被置乱。也就是说,ranked_groups_col_c
应该只能包含从0到变量A
列的值。例如,如果A是100x100,我们希望ranked_groups_col_c
的值在0到99之间。你知道吗
使用调试器,我确认了预转换变量ranked_groups
的列内容确实是由列计数限定的。你知道吗
我们使用这段代码的10次中有9次是这样的,ranked_groups_col_c
(在强制转换之后)中的一些值在我看来就像是被随机置乱了。例如,对于208621列的COO矩阵,我记录的案例如下:
>>> 280205 208621
>>> 1120897 208621
>>> 891677560 208621
>>> 891677560 208621
其中,第一个数字是ranked_groups_col_c
中的索引(不应超过列计数),第二个数字是源矩阵中的列数(仅供参考)。你知道吗
我试着将NumPy升级到最新版本和以前的版本,这种情况一直在发生。我们也联系了我们的云服务提供商,他们没有回信。我不得不认为这是一些非常低级的错误,但我不清楚那可能是什么。你知道吗
更新:我们对发布整个函数有点犹豫,但这里有一个包含变量声明的片段:
# the matrix A is an argument of the function
ranked = np.argsort(-scores).astype(np.int32)
seen = np.zeros(A.shape[1], dtype=np.int32)
cdef int[:] seen_c = seen
cdef int[:] local_ranked_c
cdef int[:] ranked_groups_col_c
for i in range(n):
local_ranked = ranked[i,:]
local_ranked_c = local_ranked
ranked_groups = A[local_ranked,:].tocoo()
ranked_groups_col_c = ranked_groups.col.astype(np.int32)
for pos in range(m):
j = local_ranked_c[pos]
k = ranked_groups_col_c[pos]
if seen_c[k]:
pass
取决于Python安装(即它是64位安装吗?),可能存在转换为32位整数的问题。对于64位Python解释器,整数是64位宽的(与
int
不同,例如x86\u 64 C编译器是32位宽的)。如果一个64位Python整数在一台具有小endian顺序的机器上被强制转换为32位(例如64位Intel),那么32个高位就被简单地截断了,如果整数不大于231-1或小于-231(那么高位应该都是零或1表示正整数或负整数)。但是,如果出现较大的幅度整数,32位转换将导致错误。如果代码的C部分应该访问一个64位宽的Python整数数组作为一个32位整数数组,那么除了第0个元素的索引之外,其他所有元素都是错误的。你知道吗在Linux和OSX的64位安装上强制转换为
long
还是在64位MS Windows安装上强制转换为long long
是一种选择?你知道吗相关问题 更多 >
编程相关推荐