状态:执行失败,从 CUDA 库调用 cusolverDnDgeqrf 时
Status: execution failed, when invoking cusolverDnDgeqrf from CUDA library
我尝试使用 CUDA 的 cusolver 库在 GPU 上执行 QR 分解。
我将我的问题简化为以下示例。
基本上,几个步骤是:
- 我分配内存并初始化一个 [5x3] 矩阵,其中 1s
主持人,
- 我在设备上分配内存并复制矩阵
- 我用
cusolverDnCreate
初始化求解器处理程序
- 我用
cusolverDnDgeqrf_bufferSize
确定所需工作的大小 space
- 最后,尝试使用
cusolverDnDgeqrf
进行 QR 因式分解
不幸的是,最后一个命令由于返回 CUSOLVER_STATUS_EXECUTION_FAILED
(int 值 = 6)而系统地失败,我不知道出了什么问题!
错误代码如下:
#include <cusolverDn.h>
#include <cuda_runtime_api.h>
int main(void)
{
int N = 5, P = 3;
double *hostData;
cudaMallocHost((void **) &hostData, N * sizeof(double));
for (int i = 0; i < N * P; ++i)
hostData[i] = 1.;
double *devData;
cudaMalloc((void**)&devData, N * sizeof(double));
cudaMemcpy((void*)devData, (void*)hostData, N * sizeof(double), cudaMemcpyHostToDevice);
cusolverStatus_t retVal;
cusolverDnHandle_t solverHandle;
retVal = cusolverDnCreate(&solverHandle);
std::cout << "Handler creation : " << retVal << std::endl;
double *devTau, *work;
int szWork;
cudaMalloc((void**)&devTau, P * sizeof(double));
retVal = cusolverDnDgeqrf_bufferSize(solverHandle, N, P, devData, N, &szWork);
std::cout << "Work space sizing : " << retVal << std::endl;
cudaMalloc((void**)&work, szWork * sizeof(double));
int *devInfo;
cudaMalloc((void **)&devInfo, 1);
retVal = cusolverDnDgeqrf(solverHandle, N, P, devData, N, devTau, work, szWork, devInfo); //CUSOLVER_STATUS_EXECUTION_FAILED
std::cout << "QR factorization : " << retVal << std::endl;
int hDevInfo = 0;
cudaMemcpy((void*)devInfo, (void*)&hDevInfo, 1 * sizeof(int), cudaMemcpyDeviceToHost);
std::cout << "Info device : " << hDevInfo << std::endl;
cudaFree(devInfo);
cudaFree(work);
cudaFree(devTau);
cudaFree(devData);
cudaFreeHost(hostData);
cudaDeviceReset();
}
您是否在我的代码中看到任何明显的错误,请告诉我!
非常感谢。
任何时候你在使用 cuda 代码时遇到问题,你应该总是使用 proper cuda error checking 和 运行 你的代码 cuda-memcheck
, before 寻求帮助。
您可能还想知道 relevant CUDA/cusolver sample code and there is also sample code in the documentation.
中给出了完整的 QR 因式分解示例这一事实
通过适当的错误检查,您可能已经发现:
这是不正确的:
cudaMalloc((void **)&devInfo, 1);
第二个参数是以字节为单位的大小,所以它应该是 sizeof(int)
,而不是 1。这个错误导致 cudaMemcpyAsync
调用内部的 cusolverDnDgeqrf
操作出错,这将显示在 cuda-memcheck
输出中。
这是不正确的:
cudaMemcpy((void*)devInfo, (void*)&hDevInfo, 1 * sizeof(int), cudaMemcpyDeviceToHost);
指针参数的顺序是目标先,然后是源。所以你把这些参数颠倒了,这个调用会抛出一个 运行time API 错误,如果你进行了正确的错误检查(或者在 cuda-memcheck
输出中可见),你可以观察到这个错误。
修复这些错误后,qrf 调用实际上会 return 零状态(无错误)。但是我们还没有完全完成(同样,适当的错误检查会让我们知道我们还没有完全完成。)
除了上述错误外,您还犯了一些尺寸错误。您的矩阵大小为 N*P
,因此它有 N*P
个元素,并且您在此处初始化那么多元素:
for (int i = 0; i < N * P; ++i)
hostData[i] = 1.;
但您并未为主机上的那么多元素分配:
cudaMallocHost((void **) &hostData, N * sizeof(double));
或在此处的设备上:
cudaMalloc((void**)&devData, N * sizeof(double));
而且你没有在这里传输那么多元素:
cudaMemcpy((void*)devData, (void*)hostData, N * sizeof(double), cudaMemcpyHostToDevice);
所以在上面的 3 种情况下,如果您将 N*sizeof(double)
更改为 N*P*sizeof(double)
,您将能够修复这些错误,然后代码 运行s 不会报告任何错误cuda-memcheck
,并且 return 任何 API 调用都没有错误。
我尝试使用 CUDA 的 cusolver 库在 GPU 上执行 QR 分解。
我将我的问题简化为以下示例。
基本上,几个步骤是:
- 我分配内存并初始化一个 [5x3] 矩阵,其中 1s 主持人,
- 我在设备上分配内存并复制矩阵
- 我用
cusolverDnCreate
初始化求解器处理程序
- 我用
cusolverDnDgeqrf_bufferSize
确定所需工作的大小 space
- 最后,尝试使用
cusolverDnDgeqrf
进行 QR 因式分解
不幸的是,最后一个命令由于返回 CUSOLVER_STATUS_EXECUTION_FAILED
(int 值 = 6)而系统地失败,我不知道出了什么问题!
错误代码如下:
#include <cusolverDn.h>
#include <cuda_runtime_api.h>
int main(void)
{
int N = 5, P = 3;
double *hostData;
cudaMallocHost((void **) &hostData, N * sizeof(double));
for (int i = 0; i < N * P; ++i)
hostData[i] = 1.;
double *devData;
cudaMalloc((void**)&devData, N * sizeof(double));
cudaMemcpy((void*)devData, (void*)hostData, N * sizeof(double), cudaMemcpyHostToDevice);
cusolverStatus_t retVal;
cusolverDnHandle_t solverHandle;
retVal = cusolverDnCreate(&solverHandle);
std::cout << "Handler creation : " << retVal << std::endl;
double *devTau, *work;
int szWork;
cudaMalloc((void**)&devTau, P * sizeof(double));
retVal = cusolverDnDgeqrf_bufferSize(solverHandle, N, P, devData, N, &szWork);
std::cout << "Work space sizing : " << retVal << std::endl;
cudaMalloc((void**)&work, szWork * sizeof(double));
int *devInfo;
cudaMalloc((void **)&devInfo, 1);
retVal = cusolverDnDgeqrf(solverHandle, N, P, devData, N, devTau, work, szWork, devInfo); //CUSOLVER_STATUS_EXECUTION_FAILED
std::cout << "QR factorization : " << retVal << std::endl;
int hDevInfo = 0;
cudaMemcpy((void*)devInfo, (void*)&hDevInfo, 1 * sizeof(int), cudaMemcpyDeviceToHost);
std::cout << "Info device : " << hDevInfo << std::endl;
cudaFree(devInfo);
cudaFree(work);
cudaFree(devTau);
cudaFree(devData);
cudaFreeHost(hostData);
cudaDeviceReset();
}
您是否在我的代码中看到任何明显的错误,请告诉我! 非常感谢。
任何时候你在使用 cuda 代码时遇到问题,你应该总是使用 proper cuda error checking 和 运行 你的代码 cuda-memcheck
, before 寻求帮助。
您可能还想知道 relevant CUDA/cusolver sample code and there is also sample code in the documentation.
中给出了完整的 QR 因式分解示例这一事实通过适当的错误检查,您可能已经发现:
这是不正确的:
cudaMalloc((void **)&devInfo, 1);
第二个参数是以字节为单位的大小,所以它应该是
sizeof(int)
,而不是 1。这个错误导致cudaMemcpyAsync
调用内部的cusolverDnDgeqrf
操作出错,这将显示在cuda-memcheck
输出中。这是不正确的:
cudaMemcpy((void*)devInfo, (void*)&hDevInfo, 1 * sizeof(int), cudaMemcpyDeviceToHost);
指针参数的顺序是目标先,然后是源。所以你把这些参数颠倒了,这个调用会抛出一个 运行time API 错误,如果你进行了正确的错误检查(或者在
cuda-memcheck
输出中可见),你可以观察到这个错误。
修复这些错误后,qrf 调用实际上会 return 零状态(无错误)。但是我们还没有完全完成(同样,适当的错误检查会让我们知道我们还没有完全完成。)
除了上述错误外,您还犯了一些尺寸错误。您的矩阵大小为
N*P
,因此它有N*P
个元素,并且您在此处初始化那么多元素:for (int i = 0; i < N * P; ++i) hostData[i] = 1.;
但您并未为主机上的那么多元素分配:
cudaMallocHost((void **) &hostData, N * sizeof(double));
或在此处的设备上:
cudaMalloc((void**)&devData, N * sizeof(double));
而且你没有在这里传输那么多元素:
cudaMemcpy((void*)devData, (void*)hostData, N * sizeof(double), cudaMemcpyHostToDevice);
所以在上面的 3 种情况下,如果您将
N*sizeof(double)
更改为N*P*sizeof(double)
,您将能够修复这些错误,然后代码 运行s 不会报告任何错误cuda-memcheck
,并且 return 任何 API 调用都没有错误。