Использование Numba Jitclass с вводом из слов и кортежей - PullRequest
0 голосов
/ 08 июля 2019

Я работаю над оптимизацией некоторого моего кода, который в основном содержится в одном классе Python.Он очень мало манипулирует объектами python, поэтому я подумал, что использование Numba будет хорошим совпадением, но у меня есть большое количество параметров, которые мне нужны при создании объекта, и я не думаю, что полностью понимаю относительно недавнюю поддержку dict в Numba.( документация здесь ).Все параметры, которые у меня есть, являются либо плавающими, либо целочисленными, и передаются в объект, сохраняются, а затем используются во время выполнения кода, например так:

import numpy as np
from numba import jitclass, float64

spec = [
    ('p', dict),
    ('shape', tuple),               # the shape of the array
    ('array', float64[:,:]),          # an array field
]

params_default = {
    par_1 = 1,
    par_2 = 0.5
    }

@jitclass(spec)
class myObj:
    def __init__(self,params = params_default,shape = (100,100)):
        self.p = params
        self.shape = shape
        self.array = self.p['par_2']*np.ones(shape)

    def inc_arr(self):
        self.array += self.p['par_1']*np.ones(shape)

Там совсем немного, я неМне кажется, я понимаю, что для этого нужно Нумбе.Если я хочу оптимизировать это с помощью Numba в режиме nopython, нужно ли передавать спецификацию в декоратор jitclass?Как определить спецификацию для словаря?Должен ли я также объявить кортеж формы?Я посмотрел на документацию , которую я нашел на декораторе jitclass, а также на документацию dict numba, и я не уверен, что делать.Когда я запускаю приведенный выше код, я получаю следующую ошибку:

TypeError: spec values should be Numba type instances, got <class 'dict'>

Нужно ли как-то включать элементы dict в спецификацию?Из документации не ясно, какой будет правильный синтаксис для этого.

Альтернативно, есть ли способ заставить Numba выводить типы ввода?

1 Ответ

1 голос
/ 10 июля 2019

spec должен состоять из специфичных для numba типов , а не из типов python!Таким образом, tuple и dict в спецификации должны быть напечатаны типами numba (и на самом деле разрешены только однородные дикты).

Так что вы либо указываете свой params_default dict в сопряженной функции, как показано здесь или вы явно набираете numba dict , как показано здесь .

Для этого случая я воспользуюсь последним подходом:

import numpy as np
from numba import jitclass, float64

# Explicitly define the types of the key and value:
params_default = nb.typed.Dict.empty(
    key_type=nb.typeof('par_1'),
    value_type=nb.typeof(0.5)
)

# assign your default values
params_default['par_1'] = 1.  # Same type required, thus setting to float
params_default['par_2'] = .5

spec = [
    ('p', nb.typeof(params_default)),
    ('shape', nb.typeof((100, 100))),               # the shape of the array
    ('array', float64[:, :]),          # an array field
]

@jitclass(spec)
class myObj:
    def __init__(self, params=params_default, shape=(100, 100)):
        self.p = params
        self.shape = shape
        self.array = self.p['par_2'] * np.ones(shape)

    def inc_arr(self):
        self.array += self.p['par_1'] * np.ones(shape)

Как уже указывалось: диктат, на самом деле, однородно напечатан.Таким образом, все ключи / значения должны быть одного типа.Поэтому сохранение int и float в одном и том же файле не сработает.

...