首页 > 解决方案 > 为什么我在 pycuda 中调用内核时会获得非法内存访问?

问题描述

我正在尝试使用 PyCuda 在我的 RTX 2080 Ti 上使用 Hodgkin 和 Huxley 形式实现神经元模型。代码非常大,所以我不会把它全部放在这里。我的课的第一部分是设置神经元的数量,在 GPU 中创建所有变量,并根据神经元的数量获取块和网格的大小(线程 1 个神经元)

class Inter_PC:
    def __init__(self, ):

        self.NbODEs = 25
        self.NbCells = int(1024 * 1)
        self.init_vector()
        self.init_vector_param()
        self.Create_GPU_SourceModule()

        BLOCK_SIZE = 1024
        self.grid = (int(self.NbCells / BLOCK_SIZE), 1)
        self.block = (BLOCK_SIZE, 1, 1)

在函数init_vectorandinit_vector_param中,我将向量用于计算 GPU 中的 ODE 结果

def init_vector(self):
    self.Vs_PC_dydx1 = self.put_vect_on_GPU(np.zeros((self.NbCells), dtype=np.float32))
    self.Vs_PC_dydx2 = self.put_vect_on_GPU(np.zeros((self.NbCells), dtype=np.float32))
    self.Vs_PC_dydx3 = self.put_vect_on_GPU(np.zeros((self.NbCells), dtype=np.float32))
    self.Vs_PC_dydx4 = self.put_vect_on_GPU(np.zeros((self.NbCells), dtype=np.float32))
    self.Vs_PC_y = self.put_vect_on_GPU(np.zeros((self.NbCells), dtype=np.float32))
    self.Vs_PC_yt = self.put_vect_on_GPU(np.zeros((self.NbCells), dtype=np.float32))
    ...
def init_vector_param(self):
    self.E_leak = self.put_vect_on_GPU(np.ones((self.NbCells), dtype=np.float32) * -65)
    self.E_Na = self.put_vect_on_GPU(np.ones((self.NbCells), dtype=np.float32) * 55)
    ...
def put_vect_on_GPU(self, Variable):
    Variable_gpu = cuda.mem_alloc(Variable.nbytes)
    cuda.memcpy_htod(Variable_gpu, Variable)
    return Variable_gpu

在函数Create_GPU_SourceModule中,我创建了要在 GPU 上使用的内核。

def Create_GPU_SourceModule(self):
    self.mod = SourceModule("""
    #include <math.h>
      __global__ void m_inf_PC(float *V_PC, float *res)
      {
        int idx = threadIdx.x + blockDim.x * blockIdx.x; 
        res[idx] = 1.0 / ( 1. * exp(-(V_PC[idx] + 40.) / 3.));
      }
      __global__ void h_inf_PC(float *V_PC, float *res)
      {
        int idx = threadIdx.x + blockDim.x * blockIdx.x; 
        res[idx] = 1.0 / ( 1. * exp((V_PC[idx] + 45.) / 3.)); 
      }
      ...

我有一个函数来更新我在 RK4 求解器中的所有变量updateParameters

def setParameters(self):
    func = self.mod.get_function("set_vect_val")
    func(self.Vs_PC_y, self.E_leak, block=self.block, grid=self.grid)
    func = self.mod.get_function("set_vect_val")
    func(self.Vd_PC_y, self.E_leak, block=self.block, grid=self.grid)
    func = self.mod.get_function("h_inf_PC")
    func(self.Vs_PC_y, self.h_s_PC_y, block=self.block, grid=self.grid)
    func = self.mod.get_function("m_KDR_inf_PC")
    func(self.Vs_PC_y, self.m_KDR_s_PC_y, block=self.block, grid=self.grid)
    func = self.mod.get_function("m_m_inf_PC")
    func(self.Vs_PC_y, self.m_s_PC_y, block=self.block, grid=self.grid)
    func = self.mod.get_function("m_m_inf_PC")
    func(self.Vd_PC_y, self.m_d_PC_y, block=self.block, grid=self.grid)
    func = self.mod.get_function("h_inf_PC")
    func(self.Vd_PC_y, self.h_d_PC_y, block=self.block, grid=self.grid)

当我运行代码时,我收到此错误:

Traceback (most recent call last):
 File "C:/Users/maxime/Desktop/SESAME/PycharmProjects/Modele_Micro3/Class_PyrCell_GPU.py", line 1668, in <module>
    Vm = PC.rk4_Time(30000)
 File "C:/Users/maxime/Desktop/SESAME/PycharmProjects/Modele_Micro3/Class_PyrCell_GPU.py", line 1637, in rk4_Time
    self.updateParameters()
  File "C:/Users/maxime/Desktop/SESAME/PycharmProjects/Modele_Micro3/Class_PyrCell_GPU.py", line 998, in updateParameters
    func = self.mod.get_function("h_inf_PC")
  File "C:\Python389\lib\site-packages\pycuda\compiler.py", line 326, in get_function
    return self.module.get_function(name)
pycuda._driver.LogicError: cuModuleGetFunction failed: an illegal memory access was encountered
PyCUDA WARNING: a clean-up operation failed (dead context maybe?)
cuMemFree failed: an illegal memory access was encountered

我不明白的是,我第一次使用内核时不会发生错误h_inf_PC,它发生在函数的第 13 行,setParameters但我已经在同一个函数的第 5 行调用了同一个内核。如果我注释掉h_inf_PC导致问题的对内核 ( ) 的调用,则错误会打开另一个对内核的调用,但不一定是下一个。

标签: pythonpycuda

解决方案


推荐阅读