[英]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.