[CUDA error记录]CUDA error: device-side assert triggered的一种可能

具体问题描述分析

在运行Pytorch的过程中,对新建张量的语句frame_volume = torch.zeros((bs, ch, self.ch_num, h, w)).to(x)报了如下错误:

RuntimeError: CUDA error: device-side assert triggered

并且有大量类似的CUDA的报错:

.../ATen/native/cuda/ScatterGatherKernel.cu:115: operator(): block: [xxx,0,0], thread: [xxx,0,0] Assertion `idx_dim >= 0 && idx_dim < index_size && "index out of bounds"` failed.

在网上查找,发现大部分出现类似CUDA error: device-side assert triggered的原因都是在分类问题中索引越界导致的,但显然新建张量没有类似的索引问题,且通过进一步定位,发现报错是由.to(x)产生的,即将张量转换到GPU上引起的。于是我怀疑问题并不出在这一句,而是之前的操作导致的。
通过CUDA中的报错提到ScatterGatherKernel,想到可能是程序中的torch.gather出现问题。于是通过debug进行调试,发现果然在如下代码片段中的gather之后,debug无法显示变量used_volumegather_idx中的内容,说明这一步操作已经导致问题出现。

for out_idx in range(4, -1, -1):
	out_volume = get_volume(out_idx)
	if out_idx != 0:
	   add_volume = self._bisample(out_volume, img_shape)
	used_volume = torch.cat([used_volume, 
	                         add_volume],
	                        dim=1)
	used_volume = torch.gather(used_volume, 1, gather_index)

used_volume = torch.gather(used_volume, 1, gather_index)操作前,可以正常查看变量内容:
在这里插入图片描述
而操作后,变量内容无法正常查看:
在这里插入图片描述
针对我这段程序,问题其实也很明显,在循环到最后一次的时候,并没有从out_volume生成add_volume(就是忘了写else),导致最后一次循环叠加的其实是上一次循环生成的变量,而每次循环产生的out_volume在第一维长度是递增的,所以导致正确的索引再错误的张量上是越界的。

总结

对于CUDA error: device-side assert triggered这类报错,很可能问题不出在报错的代码,而是之前就已经发生,具体的内容可以参考CUDA的报错信息。如果有条件单步debug,可以在可疑代码附近进行单步调试,若发现某一步之后,变量内容无法正常显示,那问题应该就出在这一步,之后可以继续深入排查原因。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐