cuSparse 三对角求解器的限制?
Limits on the cuSparse tridiagonal solver?
我决定将我的一个串行代码重写为 CUDA。代码的很大一部分是为不同的右手边反转一个大的三对角矩阵。然后我从 cuSparse 库中遇到了 cusparseSgtsv
。我得到了一个适用于小矩阵的示例代码,但是当矩阵大小超过 1024 时,只有 nan。我是否遗漏了文档中的内容?
这是示例代码。对于 N=1024
,代码工作正常。对于N=1025
,它一直是nan
。
#include<iostream>
#include<cuda_runtime.h>
#include<cusparse_v2.h>
using namespace std;
__global__ void assignMat(float *a,float *b,float *c,float *r)
{
int tid=threadIdx.x+blockDim.x*blockIdx.x;
a[tid]=0;
b[tid]=1;
c[tid]=0;
r[tid]=tid;
}
int main()
{
float *d_a,*d_b,*d_c,*d_r;
float *h_r;
int N=1025;
cusparseStatus_t status;
cusparseHandle_t handle=0;
status=cusparseCreate(&handle);
h_r=(float *)malloc(N*sizeof(float));
cudaMalloc((void **)&d_a,N*sizeof(float));
cudaMalloc((void **)&d_b,N*sizeof(float));
cudaMalloc((void **)&d_c,N*sizeof(float));
cudaMalloc((void **)&d_r,N*sizeof(float));
assignMat<<<1,N>>>(d_a,d_b,d_c,d_r);
status=cusparseSgtsv(handle,N,1,d_a,d_b,d_c,d_r,N);
if (status != CUSPARSE_STATUS_SUCCESS)
{
cout << status << endl;
}
else
{
cudaMemcpy(h_r,d_r,N*sizeof(float),cudaMemcpyDeviceToHost);
for (int i=0;i<N;i++)
cout << i << " " << h_r[i] << endl;
}
free(h_r);
cudaFree(d_a);cudaFree(d_b);cudaFree(d_c);cudaFree(d_r);
}
Did I miss something in the documentation?
不在 cuSparse 文档中,不。
但是,每个块的线程数有硬性限制,因此一旦 N > 1024,您的 assignMat
内核就会停止工作。您可以阅读如何 select 合法的内核启动参数here. If your code contained error checking 或者你 运行 使用 cuda-memcheck 的程序,你可能已经能够在运行时自己检测到问题。
我决定将我的一个串行代码重写为 CUDA。代码的很大一部分是为不同的右手边反转一个大的三对角矩阵。然后我从 cuSparse 库中遇到了 cusparseSgtsv
。我得到了一个适用于小矩阵的示例代码,但是当矩阵大小超过 1024 时,只有 nan。我是否遗漏了文档中的内容?
这是示例代码。对于 N=1024
,代码工作正常。对于N=1025
,它一直是nan
。
#include<iostream>
#include<cuda_runtime.h>
#include<cusparse_v2.h>
using namespace std;
__global__ void assignMat(float *a,float *b,float *c,float *r)
{
int tid=threadIdx.x+blockDim.x*blockIdx.x;
a[tid]=0;
b[tid]=1;
c[tid]=0;
r[tid]=tid;
}
int main()
{
float *d_a,*d_b,*d_c,*d_r;
float *h_r;
int N=1025;
cusparseStatus_t status;
cusparseHandle_t handle=0;
status=cusparseCreate(&handle);
h_r=(float *)malloc(N*sizeof(float));
cudaMalloc((void **)&d_a,N*sizeof(float));
cudaMalloc((void **)&d_b,N*sizeof(float));
cudaMalloc((void **)&d_c,N*sizeof(float));
cudaMalloc((void **)&d_r,N*sizeof(float));
assignMat<<<1,N>>>(d_a,d_b,d_c,d_r);
status=cusparseSgtsv(handle,N,1,d_a,d_b,d_c,d_r,N);
if (status != CUSPARSE_STATUS_SUCCESS)
{
cout << status << endl;
}
else
{
cudaMemcpy(h_r,d_r,N*sizeof(float),cudaMemcpyDeviceToHost);
for (int i=0;i<N;i++)
cout << i << " " << h_r[i] << endl;
}
free(h_r);
cudaFree(d_a);cudaFree(d_b);cudaFree(d_c);cudaFree(d_r);
}
Did I miss something in the documentation?
不在 cuSparse 文档中,不。
但是,每个块的线程数有硬性限制,因此一旦 N > 1024,您的 assignMat
内核就会停止工作。您可以阅读如何 select 合法的内核启动参数here. If your code contained error checking 或者你 运行 使用 cuda-memcheck 的程序,你可能已经能够在运行时自己检测到问题。