index-error: "invalid subindex in axis 0" with pycuda

index-error: "invalid subindex in axis 0" with pycuda

import math # all the libraries i import
import numpy as np
!pip install pycuda
import pycuda.gpuarray as gpu
import pycuda.cumath as cm

import pycuda.autoinit
import pycuda.driver as drv
from pycuda.compiler import SourceModule

我在使用带有 for 循环的 PyCUDA GPUarrays 后抛出一个错误。我定义了一个使用 for 循环的函数 PropagatorS,它 运行 在我刚刚使用 numpy 时很好,但在切换到 cuda 后就不行了。

def PropagatorS(N, L, area, z0):

  p = gpu.zeros((N,N), dtype = 'complex_')

  for ii in gpu.arange(0, N, 1):
      for jj in gpu.arange(0, N, 1):
          u = (ii - N/2 - 1)/area
          v = (jj - N/2 - 1)/area
          p[ii, jj] = cm.exp(1j*np.pi*L*z0*(u**2 + v**2))
  return p

尝试使用一些值:

p = PropagatorS(200, 700*10**-9, 0.002, 0.08))

returns “索引错误:轴 0 中的子索引无效”。错误发生在这一行:

--->    p[ii, jj] = cm.exp(1j*np.pi*L*z0*(u**2 + v**2))

我正在使用 Colab 运行 此代码。我找不到任何关于此的故障排除线程,希望有人可以提供帮助。 :)

这不是你使用 cumath 的方式。

cumath 类似 exp 的函数接受一个 array 参数,并对该数组执行操作。不需要双重嵌套的 for 循环。

所以:

math.exp 接受一个参数并计算该参数的 e 次方。

cumath.exp 接受一个输入数组,returns 一个相同形状的数组,其中返回数组的每个元素都是 e 中相应元素的幂输入数组。

这是一个简单的例子:

$ cat t31.py
import math # all the libraries i import
import numpy as np
import pycuda.gpuarray as gpu
import pycuda.cumath as cm

import pycuda.autoinit
import pycuda.driver as drv
from pycuda.compiler import SourceModule

def PropagatorS(N):

  q = gpu.zeros((N,N), dtype = np.float32)
  p = gpu.ones_like(q)
  cm.exp(p, out=q)
  return q


p = PropagatorS(4)
print(p)
$ LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64 python t31.py
[[ 2.71828175  2.71828175  2.71828175  2.71828175]
 [ 2.71828175  2.71828175  2.71828175  2.71828175]
 [ 2.71828175  2.71828175  2.71828175  2.71828175]
 [ 2.71828175  2.71828175  2.71828175  2.71828175]]
$

我认为做你想做的至少有几个选择:

  1. 在 numpy 中用你想要的指数创建一个数组。将该 numpy 数组传输到 GPU 数组。然后在该 GPU 阵列上调用 cumath.exp

  2. a pycuda kernel来做。

这是一个可能的例子,说明如何使用方法 1 来做到这一点,即 cumath.exp:

$ cat t32.py
import math # all the libraries i import
import numpy as np
import pycuda.gpuarray as gpu
import pycuda.cumath as cm

import pycuda.autoinit
import pycuda.driver as drv
from pycuda.compiler import SourceModule

def PropagatorS(N, L, area, z0):

  p = np.zeros((N,N), dtype = np.complex64)

  for ii in range(0, N, 1):
      for jj in range(0, N, 1):
          u = (ii - N/2 - 1)/area
          v = (jj - N/2 - 1)/area
          p[ii, jj] = 1j*np.pi*L*z0*(u**2 + v**2)
  q = gpu.to_gpu(p)
  r = cm.exp(q)
  return r


p = PropagatorS(4, 700*10**-9, 0.002, 0.08)
print(p)
$ LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64 python t32.py
[[ 0.70264995+0.71153569j  0.84094459+0.54112124j  0.90482706+0.42577928j
   0.92267275+0.385584j  ]
 [ 0.84094459+0.54112124j  0.93873388+0.34464294j  0.97591674+0.21814324j
   0.98456436+0.17502306j]
 [ 0.90482706+0.42577928j  0.97591674+0.21814324j  0.99613363+0.0878512j
   0.99903291+0.04396812j]
 [ 0.92267275+0.385584j    0.98456436+0.17502306j  0.99903291+0.04396812j
   1.00000000+0.j        ]]