2013-04-28 123 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