EDIT: Этот вопрос сильно устарел! numba теперь поддерживает Enum
и namedtuple
из коробки, которые обеспечивают разумное решение для группировки констант.Лучший способ обработки нескольких констант в контейнере с numba?
Я делаю несколько битхиптингов на питоне и хочу ускорить его с помощью numba. Для этого у меня много постоянных целочисленных значений, которые я должен обрабатывать, возможно, хорошо читаемым образом. Я хотел бы сгруппировать их вместе с объектами, подобными перечислению, имеющими все константы в одном пространстве имен, доступными с помощью оператора attribute-get. И, конечно, мне также хотелось бы, чтобы numba понимал, что там происходит, чтобы поддерживать высокие скорости с помощью jit-компиляции. Мой первый и самый наивный попробовать на что было похоже, что:
class SomeConstantsContainer:
SOME_NAME = 0x1
SOME_OTHER_CONSTANT = 0x2
AND_ANOTHER_CONSTANT = 0x4
К сожалению, когда я смотрю на аннотацию, похоже, Numba не понимая, что значения являются постоянными, и он всегда возвращается к медленному доступа к объектам на объектах python. Это то, что аннотацию говорит об этом:
# $29.2 = global(SomeConstantsContainer: <class 'constants.SomeConstantContainer'>) :: pyobject
# $29.3 = getattr(attr=SOME_VARIABLE, value=$29.2) :: pyobject
Я знаю, что я всегда мог возвратиться к чему-то вроде этого:
from numpy import np
SOME_STUPID_CONSTANT = np.int64(0x1)
ANOTHER_STUPID_CONSTANT = np.int64(0x2)
В этом случае JIT компилятор а) не нужно искать атрибут контейнера и b) точно знает, что он должен иметь дело с простым целым числом. Просто невероятно уродливо писать так. Я мог бы жить с обозначением всех констант явно целыми числами или позволить контейнеру сделать это. Тем не менее, я действительно хотел бы сгруппировать константы в контейнерах для ясности, а скомпилированную версию jit понять синтаксис и не тратить время на некоторый медленный поиск атрибутов python для каждого использования констант. Любые лучшие идеи, как сделать второй подход более похожим на первый подход, но сохраняя высокие скорости выполнения? Есть ли какой-то контейнер enum, который понимает numba, который я только что пропустил?
Edit: используя Также новый enum
контейнер не помочь:
@enum.unique
class SomeConstantsContainer(enum.IntEnum):
SOME_NAME = 0x1
SOME_OTHER_CONSTANT = 0x2
AND_ANOTHER_CONSTANT = 0x4
Это дает:
# $42.3 = global(SomeConstantsContainer: <enum 'SomeConstantsContainer'>) :: pyobject
# $42.4 = getattr(attr=SOME_OTHER_CONSTANT, value=$42.3) :: pyobject
Непонятно, что вы спрашиваете. Вы пытаетесь представить эти переменные в виде значений 'const' в испускаемом коде C/machine? Если да, то почему? Вы не можете проверить const-correctness на уровне Python, так что это может не иметь смысла. То есть, если они существуют как атрибуты класса, как в вашем примере кода, то любой может изменять их волей-неволей в любое время в Python * before * и отправляется JIT-скомпилированный вызов функции. Выполнение const-correctness на C-уровне не принесло бы вам ничего, о чем я знаю (но был бы очень заинтересован в контр-примерах). – ely
Я хочу, чтобы их распознавали и обрабатывали не как объекты python, а как целые константы. Я также хочу, чтобы jit-компилятор мог очистить поиск атрибутов на объекте-контейнере. – Michael
ПРИМЕЧАНИЕ. Этот вопрос сейчас сильно устарел. numba теперь поддерживает 'Enum', а также' namedtuple', которые предлагают более элегантные способы ответить на этот вопрос. – Michael