У меня есть функция, которую я пытаюсь ускорить, используя декоратор @jit из модуля Numba. Для меня важно максимально ускорить это, потому что мой основной код вызывает эту функцию миллионы раз. Вот моя функция:Как решить ошибку опускания Numba?
from numba import jit, types
import Sweep #My own module, works fine
@jit(types.Tuple((types.complex128[:], types.float64[:]))(types.complex128[:], types.complex128[:], types.float64[:], types.float64[:], types.float64))
def MultiModeSL(Ef, Ef2, Nf, u, tijd):
dEdt= np.zeros(nrModes, dtype=np.complex128)
dNdt0= np.zeros(nrMoments, dtype=np.complex128)
Efcon = np.conjugate(Ef)
for j in range(nrModes):
for n in range(nrMoments):
dEdt += 0.5 * CMx[:,j,n,0] * dg * (1+ A*1j) * Nf[n] * Ef[j] * np.exp(1j* (Sweep.omega[j]-Sweep.omega) *tijd)
for k in range(nrModes):
if n==0:
dNdt0 += g* CMx[j, k, 0,:] * Efcon[j] * Ef[k] * np.exp(1j* (Sweep.omega[k]-Sweep.omega[j]) *tijd)
dNdt0 += dg*(1+A*1j) * CMx[j,k,n,:] * Nf[n] * Efcon[j] * Ef[k] * np.exp(1j* (Sweep.omega[k]-Sweep.omega[j]) *tijd)
dEdt += - 0.5*(pd-g)*Ef + fbr*Ef2 + Kinj*EAinj*(1 + np.exp(1j*(u+Vmzm)))
dNdt = Sweep.Jn - Nf*ed - dNdt0.real
return dEdt, dNdt
Функция работает отлично, без декоратора Jit. Однако, когда я запускаю его с @jit, я получаю эту ошибку:
numba.errors.LoweringError: Failed at object (object mode frontend)
Failed at object (object mode backend)
dEdt.1
File "Functions.py", line 82
[1] During: lowering "$237 = call $236(Ef, Ef2, Efcon, Nf, dEdt.1, dNdt0, tijd, u)" at /home/humblebee/MEGA/GUI RC/General_Formula/Functions.py (82)
Линия 82 соответствует Для цикла с J в качестве итератора.
Можете ли вы мне помочь?
EDIT: Основываясь на предложении Питера и его сочетании с Einsum, я был в состоянии удалить петлю. Это сделало мою функцию раз быстрее. Вот новый код:
def MultiModeSL(Ef, Ef2, Nf, u, tijd):
dEdt= np.zeros(nrModes, dtype=np.complex128)
dNdt0= np.zeros(nrMoments, dtype=np.complex128)
Efcon = np.conjugate(Ef)
dEdt = 0.5* np.einsum("k, jkm, mk, kj -> j", dg*(1+A*1j), CMx[:, :, :, 0], (Ef[:] * Nf[:, None]), np.exp(1j* (OMEGA[:, None]-OMEGA) *tijd))
dEdt += - 0.5*(pd-g)*Ef + fbr*Ef2 + Kinj*EAinj*(1 + np.exp(1j*(u+Vmzm)))
dNdt = - np.einsum("j, jkm, jk, kj ", g, CMx[:,:,:,0], (Ef*Efcon[:,None]), np.exp(1j* (OMEGA[:, None]-OMEGA) *tijd))
dNdt += -np.einsum("j, j, jknm, kjm, kj",dg, (1+A*1j), CMx, (Nf[:]*Efcon[:,None]*Ef[:,None,None]), np.exp(1j* (OMEGA[:, None]-OMEGA) *tijd) )
dNdt += JN - Nf*ed
return dNdt
Можете ли вы предложить больше методов для ускорения этого?
Что такое 'nrModes'? Я считаю, что это проблема с ошибкой или ошибкой индекса, можете ли вы отлаживать значения в цикле, которые находятся внутри индексов? – Anzel
@ Anzel nrModes - это переменная, которая определена вне функции. Я использую его как глобальную переменную. Я не думаю, что это ошибка или ошибка индекса, потому что функция работает отлично, без декоратора jit. Не сомневаюсь, я заменил все nrModes и nrMoments на 2, и ошибка осталась прежней. Все другие переменные, такие как Ef, Nf и т. Д., Объявляются с использованием nrModes и nrMoments, поэтому их размеры совпадают. Я уверен, что это не проблема с ошибкой индекса – krishan
, но как насчет типа 'CMx'? Вы уверены, что это связано? Ваша информация слишком ОГРАНИЧИВАЕТСЯ, что никто не попытается помочь. Одно из предложений для отладки состоит в том, чтобы делать явные контуры в вашем задании 'CMx', а не как' CMx [:, j, n, 0] ', и вы увидите, что они не соответствуют вашим объявлениям типа jit – Anzel