Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何解决下降错误?_Python_Numpy_Numba - Fatal编程技术网

Python 如何解决下降错误?

Python 如何解决下降错误?,python,numpy,numba,Python,Numpy,Numba,我有一个函数,我正试图使用Numba模块中的@jit装饰器来加速这个函数。对我来说,必须尽可能地加快这个速度,因为我的主代码调用这个函数数百万次。以下是我的功能: from numba import jit, types import Sweep #My own module, works fine @jit(types.Tuple((types.complex128[:], types.float64[:]))(types.complex128[:], types.complex12

我有一个函数,我正试图使用Numba模块中的@jit装饰器来加速这个函数。对我来说,必须尽可能地加快这个速度,因为我的主代码调用这个函数数百万次。以下是我的功能:

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作为迭代器的For循环

你能帮我吗

编辑: 根据Peter的建议,并将其与Einsum相结合,我能够删除循环。这使我的功能快了3倍。以下是新代码:

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

你能推荐更多的技术来加速吗?

从你的代码中我看不出为什么这是不可矢量化的。矢量化可以将这种Python代码的速度提高大约100倍。不确定它相对于jit的表现

例如,看起来您可以将您的dEdt从循环中取出,并使用以下方法一步计算:

dEdt = 0.5 * (Cmx[:, :, :, 0] * dg * (1+A*1j) * Nf[:] * Ef[:, None] * np.exp( 1j* (Sweep.omega[None, :, None, None]-Sweep.omega) *tijd)).sum(axis=2).sum(axis=1) - 0.5*(pd-g)*Ef + fbr*Ef2  + Kinj*EAinj*(1 + np.exp(1j*(u+Vmzm)) )

(虽然我真的不知道Sweet.omega的维度是什么)。

可能还有其他问题,但其中一个问题是目前似乎不支持在模块名称空间中引用数组(下面是简单的repo)。尝试导入
omega
作为名称

In [14]: %%file Sweep.py
    ...: import numpy as np
    ...: constant_val = 0.5
    ...: constant_arr = np.array([0, 1.5, 2.])
Overwriting Sweep.py

In [15]: Sweep.constant_val
Out[15]: 0.5

In [16]: Sweep.constant_arr
Out[16]: array([ 0. ,  1.5,  2. ])

In [17]: @njit
    ...: def f(value):
    ...:     return value + Sweep.constant_val
    ...: 

In [18]: f(100)
Out[18]: 100.5

In [19]: @njit
    ...: def f(value):
    ...:     return value + Sweep.constant_arr[0]

In [20]: f(100)
LoweringError: Failed at nopython (nopython mode backend)
'NoneType' object has no attribute 'module'
File "<ipython-input-19-0a259ade6b9e>", line 3
[1] During: lowering "$0.3 = getattr(value=$0.2, attr=constant_arr)" at <ipython-input-19-0a259ade6b9e> (3)
[14]中的
:%%file Sweep.py
…:将numpy作为np导入
…:常数=0.5
…:常数_arr=np.数组([0,1.5,2.]))
覆盖Sweep.py
In[15]:Sweep.constant\u val
Out[15]:0.5
In[16]:扫频常数
Out[16]:数组([0,1.5,2.])
在[17]中:@njit
…:定义f(值):
…:返回值+Sweep.constant\u val
...: 
In[18]:f(100)
Out[18]:100.5
在[19]中:@njit
…:定义f(值):
…:返回值+扫描。常量\u arr[0]
In[20]:f(100)
LoweringError:在nopython(nopython模式后端)失败
“非类型”对象没有属性“模块”
文件“”,第3行
[1] 期间:将“$0.3=getattr(值=$0.2,attr=constant_arr)”降低到(3)

什么是
nrModes
?我认为这是一个越界或索引错误问题,您能用循环中的值调试索引中的值吗?@Anzel nrModes是一个在函数外部定义的变量。我用它作为一个全局变量。我不认为这是一个越界或索引错误的问题,因为函数在没有jit装饰器的情况下工作得非常好。仍然可以肯定的是,我用2替换了所有nrModes和NRMONTES,误差保持不变。所有其他变量(如Ef、Nf等)都是使用nrModes和nrMoments声明的,因此它们的维度匹配。我确定这不是索引错误问题,但是关于
CMx
type呢?你确定它在规定范围内吗?你的信息太有限,没有人会帮助你。调试的一个建议是在
CMx
赋值中执行显式循环,而不是像
CMx[:,j,n,0]
那样,您应该看看它们是否超出了jit类型声明的范围。这肯定是其中一个问题,我现在已经在代码中更改了它。我在函数OMEGA=Sweep.OMEGA.copy()之外创建了一个新变量,在导入模块时只会发生一次,所以我可以接受它。\ \然而,@jit仍然给我同样的下降错误:(…我将尝试按照Peter的建议进行矢量化,但是如果你对JIT装饰器有一些想法,我愿意看到它看起来很棒,但没有给出预期的结果。我将在我的问题中添加更多的信息,我希望你能帮助我使用dEdt公式,我将为dNdt公式扩展相同的过程。嗨,我已经编辑了我的问题。现在您可以看到一个更新的代码,其中我使用了您的建议与np.einsum()相结合。代码运行速度快了3倍。您对加快它有其他建议吗?既然循环消失了,就不需要使用零进行初始化。而且我认为现在您正在使用einsum所有与广播相关的重塑([:,无,:,:,:],等)可以消失。太好了..谢谢你。删除零,会加快一点速度(但这对大量重复很重要).我不同意与广播相关的重塑。这些是计算所必需的,否则我会将向量元素相乘,而不是矩阵。不管怎样,你帮了我很大的忙。谢谢你。你是对的。我可以省去重塑。实施起来很有魅力。谢谢你无数次。