[英]CUDA shows error as "Invalid Argument" for matrix - multiplication of N times
我正在嘗試將矩陣 A(n 次)與矩陣 B 相乘。我使用內核進行矩陣乘法並使用流進行 N 次乘法。 因此,我有 3 個條件要測試。 我的第一個條件運行成功。
我不知道為什么它在第二次條件迭代中顯示“無效參數”錯誤。 我猜我沒有正確清理我的記憶。 我已盡力釋放所有主機和設備變量。 還嘗試了 CUDA 設備重置,沒有任何幫助。 誰能幫我調試一下?
請在這里找到我的代碼部分:
int main(){
for (int i = 0; i < 3; i++) {
for (int ind = 0; ind < itr; ind++){
cudaStreamCreate(&(stream[ind]));
}
cudaCheckErrors("cudaStreamCreate fail");
for (int ind = 0; ind < itr; ind++){
cudaMemcpyAsync(d_a[ind], h_a[ind], bytes_a, cudaMemcpyHostToDevice, stream[ind]);
}
cudaDeviceSynchronize();
for (int ind = 0; ind < itr; ind++){
// Launch our kernel
matrixMul<<<BLOCKS, THREADS, 0, stream[ind]>>>(d_a[ind], b, d_c[ind], M, K, N);
}
cudaDeviceSynchronize();
cudaCheckErrors("kernel fail");
for (int ind = 0; ind < itr; ind++){
cudaMemcpyAsync(h_c[ind], d_c[ind], bytes_c, cudaMemcpyDeviceToHost, stream[ind]);
}
for (int ind = 0; ind < itr; ind++){
cudaStreamSynchronize(stream[ind]);
}
cudaEventRecord( stop, 0 );
cudaEventSynchronize( stop );
cudaEventDestroy( start );
cudaEventDestroy( stop);
// Free allocated memory ****The issue was here.******
cudaFreeHost(h_a);
cudaFree(b);
cudaFreeHost(h_c);
cudaFree(d_a);
cudaFree(d_c);
cudaDeviceReset();
}
return 0;
}
在第二次迭代中,我收到錯誤消息:
Fatal error: cudaStreamCreate fail (invalid argument at /tmp/tmpwgpzgk9m/73a7502c-7662-4e80-804e-4debff15dc45.cu:140)
*** FAILED - ABORTING
解決了:
由於內存泄漏而出現錯誤。 我正在分配數組指針,但只釋放了第一個指針。 根據羅伯特的以下回答的建議,內存應該用於數組的每個索引。 並且請始終像這樣在 cuda 中使用正確的錯誤
.
建議:實施適當的 CUDA 錯誤檢查。 在每次 cuda 調用中使用它。 您對錯誤檢查宏的隨意使用會導致令人困惑的輸出,這似乎表明流創建存在問題。
事實並非如此。 無效參數是由您在循環結束時的釋放操作引起的。 你有很多錯誤:
malloc
返回的指針或實際上是堆棧數組的指針上使用cudaFreeHost
。cudaFree
。cudaDeviceReset
(無論如何都會釋放所有設備分配),由於malloc
分配的釋放不當,您cudaDeviceReset
出現內存泄漏。通過如下修改代碼的結尾:
...
cudaEventDestroy( start );
cudaEventDestroy( stop);
for (int ind = 0; ind < itr; ind++){
free(h_a[ind]);
free(h_c[ind]);
cudaFree(d_a[ind]);
cudaFree(d_c[ind]);
}
// Free allocated memory
cudaFree(b);
cudaDeviceReset();
}
...
我能夠使上述錯誤消失。
順便說一句,應該沒有必要創建 5000 個流,但它似乎可以工作,所以我將保留它。 我通常會建議流重用。
流重用可能看起來像這樣。 與其創建 5000 個流,不如選擇一個較小的數字,例如 5(此處確切的數字應該無關緊要。很可能在 3 或更大范圍內的任何內容的行為都會相似)。
創建那么多流:
const int max_streams = 5; for (int ind = 0; ind < max_streams; ind++){ cudaStreamCreate(&(stream[ind])); }
在使用流時,使用模算術在流中“旋轉”:
for (int ind = 0; ind < itr; ind++){ cudaMemcpyAsync(d_a[ind], h_a[ind], bytes_a, cudaMemcpyHostToDevice, stream[ind%max_streams]); } cudaDeviceSynchronize(); for (int ind = 0; ind < itr; ind++){ // Launch our kernel matrixMul<<<BLOCKS, THREADS, 0, stream[ind%max_streams]>>>(d_a[ind], b, d_c[ind], M, K, N); } cudaDeviceSynchronize(); ...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.