Numba не принимает массивы с типом dtype = object - PullRequest
0 голосов
/ 11 мая 2019

У меня есть пустой массив, который я хочу заполнить списками произвольной длины для каждого индекса [i, j]. Поэтому я инициализирую пустой массив, который должен содержать объекты, подобные этому:

@jit(nopython=True, parrallel=True)
def numba_function():
    values          = np.empty((length, length), dtype=object)
    for i in range(10):
        for j in range(10):
            a_list_of_things = [1,2,3,4]
            values[i,j] = a_list_of_things

Это не с:

 TypingError: Failed in nopython mode pipeline (step: nopython frontend) Untyped global name 'object': cannot determine Numba type of <class 'type'>

Если я отключаю numba, установив nopython=False, код работает нормально. Установка dtype=list в массиве values не улучшает ситуацию.

Какие-нибудь умные уловки, чтобы преодолеть это?

1 Ответ

2 голосов
/ 13 мая 2019

Numba в режиме nopython (начиная с версии 0.43.1) не поддерживает объектные массивы.

Правильный способ ввода массива объектов:

import numba as nb
import numpy as np

@nb.njit
def numba_function():
    values = np.empty((2, 2), np.object_)
    return values

Но, как уже говорилось, это не работает:

TypingError: Failed in nopython mode pipeline (step: nopython frontend)
Internal error at resolving type of attribute "object_" of "$0.4":
NotImplementedError: object

Это также упоминается в документации numba :

2.7.1. Скалярные типы

Numba поддерживает следующие скалярные типы Numpy:

  • Целые числа: все целые числа со знаком или любой шириной до 64 бит
  • Booleans
  • Действительные числа: числа с одинарной (32-разрядной) и двойной (64-разрядной) точностью
  • Комплексные числа: комплексные числа одинарной (2x32-бит) и двойной точности (2x64 бит)
  • Дата и время: любой единицы измерения
  • Последовательности символов (но над ними нет операций)
  • Структурированные скаляры: структурированные скаляры, сделанные из любых вышеперечисленных типов, и массивы вышеупомянутых типов

Следующие скалярные типы и функции не поддерживаются:

  • Произвольные объекты Python
  • Вещественные и комплексные числа половинной и расширенной точности
  • Вложенные структурированные скаляры. Поля структурированных скаляров могут не содержать других структурированных скаляров

[...]

2.7.2. Типы массивов

Поддерживаются числовые массивы любого из указанных выше скалярных типов независимо от их формы и макета.

(Акцент мой)

Поскольку dtype=object допускает произвольные объекты Python, это не поддерживается. И dtype=list эквивалентно dtype=object ( документация )

Встроенные типы Python

Несколько типов Python эквивалентны скаляру соответствующего массива при использовании для создания объекта dtype:

int           np.int_
bool          np.bool_
float         np.float_
complex       np.cfloat
bytes         np.bytes_
str           np.bytes_ (Python2) or np.unicode_ (Python3)
unicode       np.unicode_
buffer        np.void
(all others)  np.object_

Все это говорит: было бы довольно медленно иметь object массивы, которые применяются к массивам NumPy и функциям numba. Всякий раз, когда вы решаете использовать такие object массивы, вы неявно решаете, что вам не нужна высокая производительность.

Так что, если вы хотите повысить производительность и использовать массивы NumPy, вам нужно переписать ее, чтобы сначала не использовать массивы объектов, а если она все еще медленная, то вы можете подумать о том, чтобы бросить numba в массивы, не являющиеся объектами.

...