在转换为32位整数后,Cython函数中神秘地翻转了位

2024-04-19 20:49:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个复杂的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

Tags: 函数poslocalnp矩阵colintgroups
1条回答
网友
1楼 · 发布于 2024-04-19 20:49:02

取决于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是一种选择?你知道吗

相关问题 更多 >