2012-08-28 110 views
3

我的問題非常像這樣one。我運行最簡單的CUDA程序,但內核不啓動。不過,我確信我的CUDA安裝是可以的,因爲我可以運行復雜的CUDA項目,這些項目由多個文件組成(我從其他人那裏獲得),沒有任何問題。在這些項目中,編譯和鏈接是通過帶有許多標誌的makefile來完成的。我認爲問題出在編譯時使用正確的標誌。我簡單地使用這樣的命令: nvcc -arch=sm_20 -lcudart test.cu具有這樣的程序(在Linux機器上運行的):CUDA內核不啓動

__global__ void myKernel() 
{ 

    cuPrintf("Hello, world from the device!\n"); 


} 
int main() 
{ 
    cudaPrintfInit(); 
    myKernel<<<1,10>>>(); 
    cudaPrintfDisplay(stdout, true);  
    cudaPrintfEnd(); 
} 

程序正確編譯。當我添加cudaMemcpy()操作時,它不返回錯誤。任何有關爲什麼內核不能啓動的建議?

+1

我相信對於計算能力的設備2。0或更高,你可以簡單地調用'printf'。你可能想要做一些錯誤檢查,看看你是否從你的調用中收到任何錯誤消息。 – Bart

+0

另請參閱:http://stackoverflow.com/questions/6565759/cuda-cuprintf-causes-unspecified-launch-failure –

+1

還要注意您鏈接到的問題中的第一條評論:http://stackoverflow.com/問題/ 9519272/cuda-kernel-not-launching - 你上面的代碼完全沒有錯誤檢查 - 這些函數返回一個原因的狀態,你知道。 –

回答

3

您確定您的CUDA設備支持SM_20架構嗎?

從您的nvcc命令行中刪除arch =選項並重建所有內容。此編譯適用於所有CUDA設備將支持的1.0 CUDA體系結構。如果仍然無法運行,請執行構建清理並確保沒有任何目標文件留在任何地方。然後重建並運行。

另外,arch =指的是虛擬架構,應該像compute_10一樣。 sm_20是真正的體系結構,我相信應該使用code = switch,而不是arch =。

+0

謝謝。我刪除它,最後使用cuPrintf打印內核。 – Tarek

+0

我現在想起我必須首先使用'-arch = sm_20',因爲我對float變量執行了atomicAdd操作,而這不能用sm_10來完成。有其他選擇嗎? – Tarek

+2

找出你的硬件的能力。運行硬件不支持的代碼很困難。 ;> – dthorpe

11

使用printf時不打印的原因是內核啓動是異步的,並且在printf緩衝區被刷新之前程序正在退出。 CUDA(5.0)C編程指南的B.16節對此進行了說明。

在內核啓動之前,printf()的輸出緩衝區設置爲固定大小(請參閱 關聯的主機端API)。它是循環的,如果在內核執行期間產生的輸出比在緩衝區中可以容納的更多,那麼舊的輸出將被覆蓋。它只 刷新當執行這些操作之一:

  • 內核啓動通過< < < >>>或cuLaunchKernel()(在啓動的開始,如果 CUDA_LAUNCH_BLOCKING環境變量設置爲如圖1所示,在發射如 孔)的端部,
  • 經由cudaDeviceSynchronize(),的cuCtxSynchronize()同步, cudaStreamSynchronize(),的cuStreamSynchronize(),cudaEventSynchronize(), 或cuEventSynchronize(),
  • 內存拷貝通過經由cuModuleLoad()或cuModuleUnload()經由cudaDeviceReset()或cuCtxDestroy cudaMemcpy *()或cuMemcpy *()中的任何阻塞版本,
  • 模塊的裝載/卸載,
  • 上下文破壞()。

出於這個原因,這個程序打印什麼: 「你好,世界從設備\ n」 個

#include <stdio.h> 

__global__ void myKernel() 
{ 
    printf("Hello, world from the device!\n"); 
} 

int main() 
{ 
    myKernel<<<1,10>>>(); 
} 

但這個程序打印十倍。

#include <stdio.h> 

__global__ void myKernel() 
{ 
    printf("Hello, world from the device!\n"); 
} 

int main() 
{ 
    myKernel<<<1,10>>>(); 
    cudaDeviceSynchronize(); 
} 
+1

'cudaPrintfDisplay'隱式地同步上下文,所以這不是原始代碼中的問題。 – talonmies

+0

謝謝,我從我的答案中刪除了最後一行,因此不再指出其他情況。 – harrism