【问题标题】:index-error: "invalid subindex in axis 0" with pycuda索引错误:pycuda 中的“轴 0 中的子索引无效”
【发布时间】:2022-01-24 18:09:15
【问题描述】:
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))

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

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

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

【问题讨论】:

    标签: python cuda index-error pycuda


    【解决方案1】:

    这不是你使用cumath的方式。

    cumathexp 之类的函数采用 array 参数,并在该数组上执行工作。不需要双重嵌套的 for 循环。

    所以:

    math.exp 接受一个参数并将e 提升到该参数的幂。

    cumath.exp 接受一个输入数组,并返回一个相同形状的数组,其中返回数组的每个元素都是 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.xml 中使用所需的指数创建一个数组。将该 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        ]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-12
      • 1970-01-01
      • 2021-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      相关资源
      最近更新 更多