2013-04-28 124 views
1

我有一个附有2个cuda卡的桌面,我尝试通过将一些断点放入内核行来调试cuda代码。不过,调试器仅显示内核函数的入口和终端。它没有提供在内核函数体上加载的能力。它只是无视。我已经读过,要调试GPU内核,您需要将代码运行到当前系统未使用的图形卡上。在此基础上,我还尝试通过将我的活动GPU设置为第二个(未由系统使用)来运行调试器,但仍然调试器忽略内核主体。我如何解决这个问题,使用CUDA调试器?否则,编写复杂的cuda内核是非常痛苦的。在Ubuntu Nsight上调试cuda内核代码?

可能与当前的304驱动程序版本相关联,位于bumblebee optimus卡上?

+0

您使用的是cuda-gdb吗?还是Nsight EE?你正在编译与-G开关?尝试在内核入口处设置一个断点(即发出'break mykernel'命令或任何内核名称),然后查看是否在命中该断点后,可以在内核代码中设置断点。 cuda-gdb手册还提供了可以尝试的示例练习。 – 2013-04-28 15:33:50

+0

使用cuda-gdb作为Nsight的默认设置。我也试着直接用cuda-gdb在终端上调试它,但仍然是同样的问题。 – erogol 2013-04-28 15:53:00

+0

如果您尝试了我的建议,我无法从您的回复中得知。你有没有尝试在内核名称处设置一个断点,然后运行,直到遇到该断点,然后在内核中设置断点?我建议在不驱动显示器的GPU上执行此操作,并配置该GPU以便X不使用它(即不会显示在“xorg.conf”文件中)。 – 2013-04-28 20:45:35

回答

1

这是完美的驱动程序问题。我从310.4更新到319.17,现在一切都很好。

+0

我和你有同样的问题。我的驱动程序是304.108,不能在设备代码中设置断点。这是否意味着内核不在gpu上运行?或者它是否与CUDA调试器相关的问题? – Madhatter 2014-06-12 16:12:25

0

这通常是由内核未在设备上启动造成的。确保你检查了所有的错误代码(并且在内核调用后尝试添加cudaDeviceSynchronize并且检查它的错误代码)。常见的错误是编译错误的SM版本的内核。也可以尝试从应用程序中打印出可用的CUDA设备。

请注意,您也可能会遇到一些设置问题 - 例如,确保Nouveau驱动程序已正确列入黑名单。在某些情况下,即使没有连接任何显示器,X也可能使用您的设备 - 尝试在xorg.conf中明确设置PCI ID。

要通过PCI ID指定适配器:

  1. 通过执行获得你的设备ID列表|从你的壳 “的lspci grep的NVI”。这是我得到我的系统上:

    03:00.0 VGA compatible controller: NVIDIA Corporation Device 103b (rev a1) 
    03:00.1 Audio device: NVIDIA Corporation Device 0e1a (rev a1) 
    05:00.0 VGA compatible controller: NVIDIA Corporation G98 [Quadro NVS 295] (rev a1) 
    
  2. 要使用的Quadro显示我添加BusID我的/etc/X11/xorg.conf。这是我在我的系统:

    Section "Device" 
        Identifier  "Device0" 
        Driver   "nvidia" 
        VendorName  "NVIDIA Corporation" 
        BoardName  "GeForce GTX 280" 
        BusID   "PCI:5:0:0" 
        #BusID   "PCI:3:0:0" 
    EndSection 
    

注意的字符串标识符和BoardName仅仅是UI标签 - 所有我必须做的,用不同的SM版本的设备之间进行切换是关闭桌面(用于Ubuntu GNOME - service lightdm stop),移动注释,启动DM(service lightdm start)。

另外,还要确保你只有一个设备部分在xorg.conf

+0

我怎样才能做到建议的第二部分 – erogol 2013-05-03 21:08:03

+0

我已经更新了关于为X指定PCI ID的答案。 – Eugene 2013-05-03 22:56:28

0

为了调试的错误,当你推出一个内核可以定义这个可能发生的:

#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
__host__ inline void gpuAssert(cudaError_t code, char *file, int line, bool abort) 
{ 
    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

,并打电话给你内核是这样的:

kernel<<<...>>>(...); 
gpuErrchk(cudaPeekAtLastError()); 
gpuErrchk(cudaDeviceSynchronize()); 

基本上你可以用与gpuErrchk每个CUDA函数调用。 希望有所帮助。

+0

这是现在的方式... – erogol 2013-04-30 10:09:33