У меня сложная функция 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.
Используя отладчик, я подтвердил, что содержимое столбца переменной pre-cast ranked_groups
действительно ограничены числом столбцов.
В то время как примерно в 9 из 10 раз мы используем этот код, некоторые значения в ranked_groups_col_c
(после приведения) выглядят так, как будто биты были случайно зашифрованы,Например, с матрицей COO из 208621 столбцов я записал в журнал такие случаи:
>>> 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