私はNumbaモジュールから@jitデコレータを使ってスピードアップしようとしている関数を持っています。私の主なコードは何百万回もこの機能を要求しているので、できるだけ高速化することが不可欠です。ここに私の関数はあります: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行目はイテレータとしてのForループに対応しています。
お手伝いできますか?
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'タイプはどうですか?あなたは縛られていると確信していますか?誰も助けようとしないあなたの情報はあまりにも限られています。デバッグするための1つの提案は 'CMx [:、j、n、0]'のようにではなく、あなたの 'CMx'割り当て内で明示的なループを実行することです、あなたはそれらがあなたのjit型宣言の範囲外であるかどうかを見なければなりません – Anzel