cudaMemcpy2D 导致段错误

Posted

技术标签:

【中文标题】cudaMemcpy2D 导致段错误【英文标题】:cudaMemcpy2D causing seg fault 【发布时间】:2016-06-08 17:14:58 【问题描述】:

我正在尝试使用 cudaMallocPitch()cudaMemcpy2D() 分配和初始化一个二维数组。我已经能够使用以前的 API 分配多个数组,但是有一个特定的数组不断导致我的程序出现段错误。

我的代码是,

int size = totalPat * trainingSize * wordSize; // 65 * 672 * 15
char ** h_pattern = (char**) malloc((size_t) 40 * sizeof(char));

for(int = 0; i < 40; i++)
   h_pattern[i] = (char*) malloc((size_t) size * sizeof(char));
   fill_n(h_pattern[i], size, '\0');
 

 char * d_pattern;
 size_t dpitch;
 size_t spitch = size * sizeof(char);

 cudaMallocPitch(&d_patterns, &dpitch, spitch, 40));
 cudaMemcpy2D(d_pattern, dpitch, h_pattern, spitch, spitch, 40, cudaMemcpyHostToDevice); 

我使用 cuda-gdb 来调试我的程序并找到问题所在,它在 cudaMemcpy2D() 中不断出现段错误。 Backtrace 给出以下输出,

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff501dd00 in cudbgGetAPIVersion () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
(cuda-gdb) backtrace
#0  0x00007ffff501dd00 in cudbgGetAPIVersion () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#1  0x00007ffff4efc68e in cuMemGetAttribute_v2 () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#2  0x00007ffff4f0cc7f in cuMemGetAttribute_v2 () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#3  0x00007ffff4efd7f1 in cuMemGetAttribute_v2 () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#4  0x00007ffff4e6b322 in cuMemGetAttribute_v2 () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#5  0x00007ffff4e74b38 in cuMemGetAttribute_v2 () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#6  0x00007ffff4e4d92a in cuMemcpy2DUnaligned_v2 () from /usr/lib/x86_64-linux-gnu/libcuda.so.1
#7  0x000000000045bc5d in cudart::driverHelper::memcpy2DPtr(char*, unsigned long, char const*, unsigned long, unsigned long, unsigned long, cudaMemcpyKind, CUstream_st*, bool, bool) ()
#8  0x0000000000435039 in cudart::cudaApiMemcpy2DCommon(void*, unsigned long, void const*, unsigned long, unsigned long, unsigned long, cudaMemcpyKind, bool) ()
#9  0x00000000004350f8 in cudart::cudaApiMemcpy2D(void*, unsigned long, void const*, unsigned long, unsigned long, unsigned long, cudaMemcpyKind) ()
#10 0x0000000000462073 in cudaMemcpy2D ()

在 devtalk 论坛中,有一个关于音高限制的问题,其中 cudaMemcpy2D() 因音高大小大于 2^18 而失败,但是这个问题是从 2007 年开始的,我认为这个限制不再存在。在文档中还提到,如果 dpitch 或 spitch 超过允许的最大值 cudaMemcpy2D() 会返回错误,但他们不知道允许的最大值是多少。

非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

您的代码正在尝试将 char 类型的 40 * size 字节数据复制到 char* 类型的 40 字节主机内存空间。

相反,您需要为主机上的所有 40 种模式分配一个线性内存空间,例如:

char* h_pattern;
h_pattern = (char*) malloc((size_t) 40* size * sizeof(char));

【讨论】:

以上是关于cudaMemcpy2D 导致段错误的主要内容,如果未能解决你的问题,请参考以下文章

CUDA程序优化之数据传输

CUDA程序优化之数据传输

CUDA程序优化之数据传输

为啥无限递归会导致段错误

QNetworkReply 导致段错误

NotifyHeader.code 导致段错误