Индексировать массив массивом в numba

Как часть более сложной функции, которую я хочу скомпилировать numba, мне нужно проиндексировать массив A другим массивом idx.

Важно отметить, что размерность массива A является переменной. Форма может быть (N), (N,N) или (N,N,N) и т. д.

В python я могу сделать это с помощью кортежей:

def test():
    A = np.arange(5*5*5).reshape(5,5,5)
    idx = np.array([0,2,4])
    return A[tuple(idx)]

Однако индексация массива с помощью кортежа, по-видимому, не поддерживается numba, так как я получаю следующую ошибку:

TypingError: Failed in nopython mode pipeline (step: nopython frontend)
No implementation of function Function(<class 'tuple'>) found for signature:
 
 >>> tuple(array(int64, 1d, C))

Обратите внимание, что это всего лишь минимальный рабочий пример. В общем, я не узнать длину idx.

Я подумал о преобразовании A в вектор и преобразовании idx к соответствующему скалярному индексу.

Это лучшее решение или есть простая «нумба-альтернатива» индексация с помощью кортежа?

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
0
42
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Importantly, the dimension of the array A is variable. The shape can be (N), (N,N), or (N,N,N) etc.

Размерность массива является частью его типа в Numba. Это означает, что массивы A с разными размерами относятся к разным типам, и поэтому работающая с ними функция должна быть скомпилирована нескольких типов. Действительно, Numba необходимо установить четко определенный тип для всех входных/выходных параметров (и внутренних переменных) скомпилированные функции. С переменным количеством измерений, определенным во время выполнения, вам нужно переменное количество скомпилированных функций и оболочка Python, чтобы выбрать правильную реализацию функции. Дело в том, что компиляция функции довольно дорогая, и самая большая проблема - это индексация массивов, как вы указали.

In python, I can do so using tuples

Это потому, что Python работает с объекты с динамическим типом. Но это также одна из основных причин, почему Python такой медленный по сравнению с Numba.

indexing an array with a tuple is apparently not supported by numba

Индексирование массива с помощью кортежа должно поддерживаться, но создание кортежа из динамического массива переменного размера в Numba невозможно (и уж точно никогда не будет). Действительно, тип кортежа (требуемый во время компиляции) в основном состоит из списка его элементов, который зависит от динамического свойства (известного только во время выполнения). Для получения дополнительной информации об этом, пожалуйста, прочитайте: Numba Создание кортежа из списка .

Is that the best solution or is there a simple "numba alternative" to indexing with a tuple?

В общем, от работы с массивом переменной размерности с помощью Numba однозначно стоит отказаться, так как он для этого не предназначен. При этом это не означает, что вы не можете решить такую ​​проблему с помощью Numba.

Одним из решений является работа с сглаживание массивов и сглаживание индексов. Идея состоит в том, чтобы сгладить A с помощью A.ravel(), а затем передать Нумбе. То же самое можно сделать с фигурой: A.shape можно передать в Numba как динамический одномерный массив с помощью shape = np.array(A.shape, dtype=np.int) (выполняется вне функции Numba). Я предполагаю, что массив непрерывен для ясности (и здравомыслия). Затем функция Numba может получить доступ к данному элементу A, используя выражение вроде:

A[idx[0]*strides[0] + idx[1]*strides[1] + ... + idx[n-1]*strides[n-1]]

Где n = len(shape). Шаги могут быть предварительно вычисленный один раз, используя:

strides = np.array(n, dtype=np.int64)
for i in range(n):
    strides[i] = 1
    for j in range(i+1, n):
        strides[i] *= shape[j]

Вы можете вычислить плоский индекс во время выполнения, используя базовый цикл:

pos = np.int64(0)
for i in range(n):
    pos += np.int64(idx[i]) * strides[i]
# A[pos]

Обратите внимание, что выполнение такой операции неэффективно, особенно для непрерывного доступа. При этом динамические массивы переменного размера принципиально неэффективны. Вы можете скомпилировать код Numba для некоторых конкретных значений n, чтобы ускорить эти конкретные случаи (например, массивы с небольшим количеством измерений, например <=8). Для массивов высокого порядка с непостоянным размером AFAIK нет быстрого универсального способа сделать это. Вам нужно работать с (относительно большим) смежные срезы массива flatten, чтобы помочь Numba генерировать более быстрый код.

Большое спасибо за этот отличный ответ! Особенно мне очень помогает объяснение глубинных причин и вопросов эффективности. Да, я знаю размеры во время компиляции.

wheat 23.04.2022 14:36

Другие вопросы по теме