簡體   English   中英

CUDA 將錯誤顯示為矩陣的“無效參數” - 乘以 N 次

[英]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 調用中使用它。 您對錯誤檢查宏的隨意使用會導致令人困惑的輸出,這似乎表明流創建存在問題。

事實並非如此。 無效參數是由您在循環結束時的釋放操作引起的。 你有很多錯誤:

  1. 我們不會在malloc返回的指針或實際上是堆棧數組的指針上使用cudaFreeHost
  2. 您不會在實際上是堆棧數組的指針上使用cudaFree
  3. 如果您在循環中進行了分配,則可能必須在循環中進行自由操作。
  4. 即使您使用了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 或更大范圍內的任何內容的行為都會相似)。

  1. 創建那么多流:

     const int max_streams = 5; for (int ind = 0; ind < max_streams; ind++){ cudaStreamCreate(&(stream[ind])); }
  2. 在使用流時,使用模算術在流中“旋轉”:

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM