python - 为什么我在 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_vector
andinit_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
导致问题的对内核 ( ) 的调用,则错误会打开另一个对内核的调用,但不一定是下一个。
解决方案
推荐阅读
- macos - 如何在 macOS 上显示正在运行的进程列表?
- ruby-on-rails - 如何在 rails-postgres 中存储每个用户提交的表单?
- javascript - Timeline Vis - 使用子组排序强制子组 2 在子组 1 之后
- checkbox - Rails 编辑表单复选框不检查布尔真值
- python - 使 Tkinter 框架填充垂直轴
- dji-sdk - “stopAircraftFollowing”方法不提供回调
- java - 微服务中的外部 URL 配置
- javascript - 访问 html 页面上的缓存?
- laravel - Laravel aimeos - 完整性约束违规问题
- c# - c#如何到处使用用户数据库