想请教一个问题,麻烦解答一下!非常感谢!
调试程序的时候显示:
Phase_GPU.exe 中的 0x7518c41f 处最可能的异常: Microsoft C++ 异常: 内存位置 0x0030fbbc 处的 cudaError_enum。
线程 ‘Win32 线程’ (0x2bb8) 已退出,返回值为 1 (0x1)。
线程 ‘Win32 线程’ (0x1610) 已退出,返回值为 1 (0x1)。
程序“[11580] Phase_GPU.exe: 本机”已退出,返回值为 1 (0x1)。
请问这是为什么?
楼主您好。
抛出cudaError_enum异常有很多情况,您需要根据您的具体的出现问题的语句,以及错误的具体指来判定。
我建议您逐步调试到您出错的地方。然后根据给这个地方的出上下文代码,以及最近的cuda错误。
很多时候,例如对cuda runtime函数的错误调用(例如,给予了错误的参数),以及对于其一些库的函数的调用,都可能抛出该异常的。
所以无法直接告诉是哪里有错误,建议您需要配合下上述操作,定位出错位置,从而进一步解决可能的错误原因。谢谢。
以及,如果出现异常时候可以直接停在出错的源代码处,那么可以直接从这个附近检查。
刚才看了一下翻译,中文版的“最可能的异常”的英文是“first-chance exception"(这个翻译真**)。
那么根据楼主的信息,楼主可能是在cuda runtime内部某处出现了异常,并已经被捕捉了,以及,您应该看不到异常对话框,而是从debug output窗口看到这个提示的。
那么,楼主后面立刻退出,并且有0x01的return value, 那么很可能在您的代码中,有类似SAFE_CALL之类的网上流传的宏。这个宏检测了某些函数的返回值,并在不是CUDA_SUCCESS的时候,执行了一次exit(1);
所以:
(1)楼主如果是上文猜测,可以修改该宏,加入对__FILE__和__LINE__的输出,以及,用debug模式编译,再次运行,这样可以直接得到出错位置。
(2)反之如果我根据您的楼主位信息给出的猜测不成立,请按2#建议,逐步定位到出错地方。
当您成功定位错处位置后,请发送到本群相关代码(以及关键的附近部分代码),以便本坛进一步处理。
楼主还在么?等了好久不见人。
我上文说了如何定位问题所在位置。以及建议了定位后发到论坛继续处理。
那么我继续说一下如果楼主代码含有敏感信息,不能发到论坛。
那么给出您DIY方式的建议:
(1)在您完成了上述楼层建议的定位问题的步骤后,定位到出现问题行的下一行。
(2)在该处写上:
{
cudaError_t result = cudaGetLastError();
const char* message = cudaGetErrorString(result);
//在此处停住,观察message, 或者如果您用windows的窗口程序,可以继续写:
//MessageBoxA(NULL, message, “详情”, MB_OK);
}
然后重新编译运行。您即可知道具体原因。
建议认真阅读上文定位所在行,以及获取具体错误信息的方式。并建议及时反馈您的实践。
(另外说一下相关知识:
您的这个“最可能的异常”实际上是windows的SEH的“first chance exception"。但是脑残的中文版给翻译成了这样。而first chance exception是用来提示调试器的,而实际上代码(例如cudaMalloc(NULL, 1);这样)已经可能已经处理了错误。所以一般您可以不理会。这是提示性信息。
那么为何会导致您的process以返回值1结束了呢?因为您可能使用了/抄袭了一些检测错误的宏,子这个宏里检测到被成功处理的异常的转换为的返回值的后,使用了exit(1)之类的语句。
所以这是我建议您如何能快速定位的4#的考虑因素。
以及这也是我做出定位后,确定原因的考虑因素。
我在5#建议您的在定位后,去掉该行的原来的这个检测宏,改成cudaGetLastError()和cudaGetErrorString(…);的原因。这样您可以直接阅读错误。而不是被该宏干扰,立刻退出。
此外,建议开发工具永远使用英文版,避免出现有混淆性的翻译。
)
版主的分析是正确的,确实是因为宏检测SAFE_CALL引起的,我去掉之后debug顺利通过了!初学者,许多还都不懂,看到好多地方都使用这个宏检测,自己也试着用了,没想到会出错,还望以后多多指导!非常感谢!
LZ您好,横扫斑竹说的明显是两点:
1:您某处出现了问题,产生了错误的返回值。
2:这个错误的返回值被SAFE_CALL之类的宏检测到,然后exit(1)。
所以简单地去除宏只能做到不立即exit(1),而您还需要定位您BUG的地方,并修正。
您可否就此将您的结果加以反馈?
可能就像横扫版主所说的“您的这个“最可能的异常”实际上是windows的SEH的“first chance exception"。但是脑残的中文版给翻译成了这样。而first chance exception是用来提示调试器的,而实际上代码(例如cudaMalloc(NULL, 1);这样)已经可能已经处理了错误。所以一般您可以不理会。这是提示性信息。”我将宏去掉后,又定位监测,重新debug了,可是再没有出现异常情况或错误啊。。。
没有也正常,无非是:
(1)楼主认为没有。
(2)以前的宏过度SB. 只要不是cudaSuccess就通杀。导致,一些正常的但不是cudaSuccess的值被误干掉。
举个例子,cudaStreamQuery(), 返回not ready而不是success的情况实际上是正确的执行完query了。但是一些SB的宏就是让你挂掉。
所以楼主认为没有也好。就这样吧。
春天到了,泡妞要紧。
版主,非常不好意思,上次是因为有点急事,去掉宏后debug顺利通过,所以再没仔细看,今天又将程序稍做了修改,发现是参数问题。我程序中使用的是二维数组,由于不正确的使用,导致各种错误。不知版主能不能讲解一下在CUDA中如何使用二维数组,如何进行二维数组的内存申请、数据复制等,我看了编程手册,还是不太明白。:handshake
在CUDA C/C++里面使用二维数组,和您在普通的C里面并无区别的。亲。
您原来怎么用,直接用即可。
补充一下12#
CUDA还提供了cudaMallocPitch()和cudaMalloc3D()两个函数,这样有助于保证访存的对齐(以浪费一定空间为代价)。具体内容可见cuda C programming guide 3.3.2章节,有较为详细的示例代码。
如果您使用cudaMalloc()申请线性内存空间,那么可以自己维护访存操作,也可以使用带有维度信息的指针,实现自动计算。这些用法和C语言中是完全一样的。
[attach]2986[/attach]
祝您编码愉快~
这几天一直有个问题比较困扰。。。我将问题描述如下:
我的核函数__global__ void Phase(float p[N][N], float u[N][N]) 中只有两个二维数组参数float p[N][N], float u[N][N] ,
主函数中我是这么写的:
size_t size = N * N * sizeof(float);(#define N 805)
float (dev_p)[N];
float (dev_u)[N];
// allocate device memory
cudaMalloc(&dev_p, size);
cudaMalloc(&dev_u, size);
cudaMemcpy((void)dev_p, (void)p, size, cudaMemcpyHostToDevice);
cudaMemcpy((void*)dev_u, (void*)u, size, cudaMemcpyHostToDevice);
dim3 dimBlock(30,30);
dim3 dimGrid((N+dimBlock.x-1)/dimBlock.x, (N+dimBlock.y-1)/dimBlock.y);
Phase<<<dimGrid, dimBlock>>>(dev_p, dev_u);
我调试程序的时候,总是在核函数处提示“invalid argument”,是不是我这样写不合适啊(global
void Phase(float p[N][N], float u[N][N]) ),参数一直没有传到核函数进行计算。。。麻烦帮忙解答一下!:handshake
楼主,新问题建议您新主题贴。
然后本次我接着回答。
在您已有的代码的中:
size_t size = N * N * sizeof(float);(define N 805) //写法无问题
float (*dev_p)[N]; //写法无问题
float (*dev_u)[N]; //写法无问题
// allocate device memory
cudaMalloc(&dev_p, size); //写法无问题, 但请确定此调用成功。
cudaMalloc(&dev_u, size); //写法无问题,但请确定此调用成功。
可能问题处1,请确保p是有效的,并p指向的缓冲区至少有size字节大小,否则cudaMemcpy将可能导致invalid argument。
cudaMemcpy((void*)dev_p, (void*)p, size, cudaMemcpyHostToDevice);
可能问题处2,请确保u是有效的,并u指向的缓冲区至少有size字节大小,否则cudaMemcpy将可能导致invalid argument。
cudaMemcpy((void*)dev_u, (void*)u, size, cudaMemcpyHostToDevice);
可能问题处3, 请确保你的卡至少是计算能力2.x以上,以让一个block容纳29个warp。
dim3 dimBlock(30,30);
dim3 dimGrid((N+dimBlock.x-1)/dimBlock.x, (N+dimBlock.y-1)/dimBlock.y); //形式上无问题
Phase<<<dimGrid, dimBlock>>>(dev_p, dev_u); //形式上无问题。
本回复不代表您的没有发表的其他代码不含有问题,但也不代表它们一定含有问题。
以及,您所提供的部分代码中,可能导致问题的地方有3(上文标注),请逐一排查。
EDIT: 将上文的“导致”修改为“可能导致”。避免楼主较真。
[
版主您好,我是初学者,也遇到了,同样的错误提示cudaError_enum,我查找到出错的代码是:
status = cublasCreate(&handle);
用cudaGetLastError得到的详情是,no error.
整个程序在ctrl +F5下是可以正常运行的,计算结果也正确,还有就是按F5不能得到exe文件。
我的系统是win2008server + VS2010中文版+CUDA5.0。
楼主您好,关于“最可能的异常“和“first-chance exception"已经在上述楼层解说,
并充分表达了我的观点(这个一般可以无视的,前者是后者的不恰当的中文翻译)。
这里将不再重复第二次。
关于您的第二个问题:
您直接使用F5默认不编译,是因为您曾经在调试的时候,弹出“代码已经改变,是否编译后再调试”,您选择了“否”,并选择了“不再提示”导致的,
您可以在VS的options里改掉它(tools菜单->options->项目和解决方案->build and run里,将“从不编译”改成“提示我”或者“总是编译”)
关于您的第三个问题,关于cublas, 这个不懂,无法进一步详细解说。
感谢您的来访,新问题请不要挖坟。建议新开主题。