2014-03-04 112 views
1

我遇到以下問題。我想讓我的用戶選擇運行哪個GPU。所以我在只有一個GPU(設備0)的機器上測試,如果他們選擇不存在的設備會發生什麼情況。CUDA:無效的設備序號

如果我這樣做cudaSetDevice(0);它將很好地工作。

如果我這樣做:cudaSetDevice(1);就會死機與invalid device ordinal(我可以處理這個作爲函數返回一個錯誤)。

如果我這樣做:cudaSetDevice(0); cudaSetDevice(1);它會崩潰invalid device ordinal(我可以處理這個函數返回一個錯誤)。

但是!如果我做的:cudaSetDevice(1); cudaSetDevice(0);第二個命令返回成功,但在第一次計算我嘗試計算在我的GPU將與invalid device ordinal崩潰。我無法處理這個問題,因爲第二個命令不會返回錯誤!

在我看來,像第cudaSetDevice留下一些躺在附近這影響了第二個命令?

非常感謝!

解決方案:(!感謝羅伯特Crovella)。 我處理這樣的錯誤:

error = cudaSetDevice(1); 
if (error) { blabla } 

但很顯然,你需要調用cudaSetDevice後cudaGetLastError()(1),否則該錯誤信息不會從一些錯誤堆棧中刪除,它只是後來崩潰的,我正在爲另一個函數做cudaGetLastError(),即使此時沒有錯誤。

回答

3

你必須檢查多少GPU在你的系統中還提供第一。這可以通過使用cudaGetDeviceCount

int deviceCount = 0; 
cudaGetDeviceCount(&deviceCount); 

比檢查是否用戶輸入是大於可用的設備更大。

if (userDeviceInput < deviceCount) 
{ 
    cudaSetDevice(userDeviceInput); 
} 
else 
{ 
    printf("error: invalid device choosen\n"); 
} 

提醒cudaSetDevice是基於0索引的!爲此我檢查userDeviceInput < deviceCount

+0

是的,這是一個很好的避免它的方法。我想知道爲什麼它不起作用。 – Stefan

+2

如果您顯示*完整*示例,它會有所幫助。你的錯誤檢查可能使用'cudaPeekAtLastError()',它不*清除錯誤代碼。它會返回最後一個錯誤 - 每次你要求它時(就像在你的內核啓動後)。相反,'cudaGetLastError()'將清除它返回的錯誤(即未來的檢查不會再返回該錯誤,如果沒有新錯誤發生,它將返回'cudaSuccess')。這與API返回錯誤代碼不同。如果您希望內核啓動不失敗,請在它之前的某個位置執行'cudaGetLastError',但在非法的'cudaSetDevice(1)'調用之後。 –

+0

我應該說「如果你想內核啓動不*出現*失敗......」 –