ошибка отпечатка пальца Python numba

Я пытаюсь numba оптимизировать некоторый код. Я проработал первые примеры в разделе 1.3.1 руководства пользователя 0.26.0 (http://numba.pydata.org/numba-doc/0.26.0/user/jit.html) и получить ожидаемые результаты, поэтому я не думаю, что проблема в установке .

Вот мой код:

import numba
import numpy
import random

a = 8
b = 4

def my_function(a, b):
    all_values = numpy.fromiter(range(a), dtype = int)
    my_array = []
    for n in (range(a)):
        some_values = (all_values[all_values != n]).tolist()
        c = random.sample(some_values, b)
        my_array.append(sorted([n] + c))
    return my_array

print(my_function(a, b))

my_function_numba = numba.jit()(my_function)

print(my_function_numba(a, b))

Что после распечатки ожидаемых результатов вызова my_function возвращает следующее сообщение об ошибке:

ValueError                                Traceback (most recent call last)
<ipython-input-8-b5d8983a58f6> in <module>()
     19 my_function_numba = numba.jit()(my_function)
     20 
---> 21 print(my_function_numba(a, b))

ValueError: cannot compute fingerprint of empty list

Отпечаток пустого списка?


person zazizoma    schedule 11.06.2016    source источник


Ответы (1)


Я не уверен конкретно в этой ошибке, но в целом, чтобы быть быстрым numba, требуется определенное подмножество numpy/python (см. здесь и здесь, чтобы узнать больше). Так что я мог бы переписать это так.

@numba.jit(nopython=True)
def fast_my_function(a, b):
    all_values = np.arange(a)
    my_array = np.empty((a, b + 1), dtype=np.int32)
    for n in range(a):
        some = all_values[all_values != n]
        c = np.empty(b + 1, dtype=np.int32)
        c[1:] = np.random.choice(some, b)
        c[0] = n
        c.sort()
        my_array[n, :] = c
    return my_array

Главное отметить:

  1. никаких списков, я заранее распределяю все.
  2. без использования генераторов (как в Python 2, так и в 3 for n in range(a) будет преобразован в быстрый собственный цикл)
  3. добавление nopython=True к декоратору делает так, что numba будет жаловаться, если я использую что-то, что не может быть эффективно JITed.
person chrisb    schedule 13.06.2016
comment
Отлично, большое спасибо. И я перешел от 91,3 микросекунды к 12 микросекундам. Любая причина, по которой c = np.empty(b + 1, dtype=np.int32), а не c = np.empty(a, dtype=np.int32)? - person zazizoma; 13.06.2016
comment
В приведенном выше коде c имеет длину b, затем вы добавляете к нему [n] перед добавлением, поэтому я думаю, что это правильная форма? - person chrisb; 13.06.2016
comment
Ага. Спасибо еще раз! - person zazizoma; 13.06.2016