странное и нестабильное поведение цикла while в объединенной функции - PullRequest
0 голосов
/ 29 сентября 2019

Я обнаружил, что когда индекс массива numpy выходит за границы внутри цикла while в декорированной функции njit, то, как функция обрабатывает цикл while, может быть довольно странным, и я не уверенпочему это происходит.

from numba import njit
import numpy as np


def func1(v):
    i= 0
    K= v[-1]+1
    while v[i] < K:
        i+=1
    return i

@njit        
def func2(v):
    i= 0
    K= v[-1]+1
    while v[i] < K:
        i+=1
    return i

x= np.arange(2)
result2 = func2(x)
result1 = func1(x)

Вот краткий итог результатов:

1) func2 не повысит IndexError

2) func2 возвращает разные результаты (например, иногда 4; иногда 5, 9, 12 и т. д., в основном нестабильный вывод) каждый раз, когда мы запускаем файл в консоли (я использую ipython version 7.8.0)

Я не уверен, почему и как это происходит (может быть из-за проблем numba или spyder или ipython или из-за неисправности моего процессора)Я прошу помощи здесь.


Примечание: я использую:

  • Anaconda's python, версия python 3.7.4,

  • версия spyder 3.3.6,

  • версия ipython 7.8.0,

  • версия numba 0.45.1

  • ОС Windows 10 64-разрядная

Ответы [ 2 ]

3 голосов
/ 29 сентября 2019

Numba не выполняет проверку границ массивов Numpy по соображениям производительности.В настоящее время есть работа по его необязательному включению (https://github.com/numba/numba/pull/4432). Когда вы выйдете за пределы массива, вы получите то, что находится в памяти в этом месте, или, возможно, ошибка сегмента.

1 голос
/ 29 сентября 2019

Я слышал о Numba раньше, но никогда не использовал его сам.

Вот результаты некоторых недоразумений с ним (версия 0.45.1) только сейчас.

from numba import njit
import numpy as np

x = np.arange(2)

@njit        
def func2(v):
    i = 0
    k = v[-1]+1
    while v[i] < k:
        i += 1
    return i

@njit
def func3(x):
    return x[2]



func2(x)  # returns 2, but no error raised

func3(x)  # returns 32, no error raised 
func3(np.array([0]))   # returns 32, no error raised

func2([0, 1])  # IndexError raised
func3([0, 1])  # IndexError raised

Так что для меня ошибка выглядит как результат какого-то взаимодействия между массивами Numba jit и Numpy, так как обычные списки Python ведут себя как положено.

...