Отрицательный динамический индекс в Нумбе - PullRequest
0 голосов
/ 12 октября 2018

Кажется, что Numba возражает против отрицательных динамических показателей в кортежах.

@jit
def test_fn():
    tup = (3,2,4,6,2)
    total = 0
    for idx in range(5):
        total += tup[-idx]
    return total  

Дает IndexError: tuple index out of range, но, конечно, прекрасно без декоратора @jit.Это известное / желаемое / неизбежное поведение?

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Это действительно странно, сравните с приведенным ниже кодом, который хорошо работает:

@jit(nopython=True)
def test_fn1():
    tup = (3, 2, 4, 6, 2)
    total = 0
    total += tup[-0]
    total += tup[-1]
    total += tup[-2]
    total += tup[-3]
    total += tup[-4]
return total

Но ваш пример не работает (он прерывается, когда idx равен -1), мне кажется, что это ошибка.
У меня есть эта проблема как с numba 0.39.0, так и с 0.40.0.

0 голосов
/ 12 октября 2018

Это определенно похоже на странную ошибку.Если я использую аргумент forceobj=True для numba.jit или если я передам locals с любой из локальных переменных tup, total или idx соответствующего типа, то функции Numba будут работать.

Еще более загадочно, если я просто добавлю вызовы к numba.typeof(idx), то это также сработает, не требуя дополнительных аргументов внутри вызова к jit.К сожалению, когда я запускаю numba --annotate из командной строки в моем скрипте с этими изменениями, похоже, что все они вызывают все, что трактуется как pyobject.

Это все с numba 0.40.0.

Вот некоторые изменения, которые я пробовал в скрипте:

# file 'test_numba.py'
import numba
import numpy as np

@numba.jit()
# @numba.jit(forceobj=True)
# @numba.jit(locals={'tup': tuple, 'idx': np.int64, 'total': np.int64})
#  also tried mixing and matching about 'locals' with and without the
#  numba.typeof calls below, and used `numba --annotate test_numba.py`
#  from command line to inspect annotated types.
def test_fn():
    tup = (3,2,4,6,2)
    total = 0
    print(numba.typeof(tup))
    print(numba.typeof(total))
    for idx in range(5):
        print(numba.typeof(idx))
        total += tup[-idx]
    return total

if __name__ == "__main__":
    test_fn()
0 голосов
/ 12 октября 2018

извините, в моем предыдущем ответе я был немного смущен.это работает:

@jit
def test_fn():
    tup = (3,2,4,6,2)
    total = 0
    for idx in tup: #changes have been made here
        total = total + idx #and here
    return total

старый ответ:

код недействителен:

def test_fn (): tup = (3,2,4,6, 2) total = 0 для idx в диапазоне (5): total + = tup [- (idx + 1)] # здесь были сделаны изменения, возвращающие итоговое значение, это происходит из-за того, что индекс '-0' недопустим.list(range(5)) возвращает [0, 1, 2, 3, 4], поэтому -0 произойдет.исправление делает так, что '-0' будет '-1', потому что это то, что возвращает то, что вы хотите.

РЕДАКТИРОВАТЬ: забыл упомянуть, что индекс -0 фактически принимается как 0, но этоневерно.

...