使用cuda常量内存时CUSPASE状态映射错误
我正在使用cuda cusparse库处理稀疏矩阵,我需要执行矩阵向量乘法(cusparseDcsrmv函数)。我有一个csr格式的稀疏矩阵d_a,当我调用这个函数时,在全局设备内存中分配向量d_x,一切都正常工作。但是,当我想使用驻留在恒定设备内存中的向量时,我遇到了一个错误:CUSPARSE\u STATUS\u MAPPING\u error 文档中说,通常的解决方案是取消绑定任何以前绑定的纹理,但这与我正在做的事情无关 有人知道发生了什么事吗使用cuda常量内存时CUSPASE状态映射错误,cuda,Cuda,我正在使用cuda cusparse库处理稀疏矩阵,我需要执行矩阵向量乘法(cusparseDcsrmv函数)。我有一个csr格式的稀疏矩阵d_a,当我调用这个函数时,在全局设备内存中分配向量d_x,一切都正常工作。但是,当我想使用驻留在恒定设备内存中的向量时,我遇到了一个错误:CUSPARSE\u STATUS\u MAPPING\u error 文档中说,通常的解决方案是取消绑定任何以前绑定的纹理,但这与我正在做的事情无关 有人知道发生了什么事吗 const int ONES_SIZE =
const int ONES_SIZE = 5400;
__constant__ static double ONES_DEV[ONES_SIZE];
const cusparseDirection_t dirA_row = CUSPARSE_DIRECTION_ROW;
const cusparseOperation_t NON_TRANS = CUSPARSE_OPERATION_NON_TRANSPOSE;
int main(){
cudaSetDevice(0);
int m = ONES_SIZE; int n = 2500;
double * HOST_ONES, *A, *d_A, *d_result;
HOST_ONES = (double*) malloc(ONES_SIZE*sizeof(double));
for (int i=0; i<ONES_SIZE; i++)
HOST_ONES[i] = 1.0;
cudaMemcpyToSymbol(ONES_DEV, HOST_ONES, ONES_SIZE*sizeof(double), 0, cudaMemcpyHostToDevice);
A = (double *) calloc(m*n, sizeof(double));
// populate matrix A
for(int i=0;i<1000; i++)
A[i*2] = 1.5;
cudaMalloc((void**)&d_A, m*n*sizeof(double));
cudaMemcpy(d_A, A, m*n*sizeof(double), cudaMemcpyHostToDevice);
cusparseHandle_t cusparse_handle = 0;
cusparseMatDescr_t descrA=0;
int *nnzTotal, *nnzPerRow, *csrRowPtrA, *csrColIndA;
double* csrValA;
int lda = m;
const double positive = 1.0;
const double zero = 0.0;
cusparseCreate(&cusparse_handle);
cusparseCreateMatDescr(&descrA);
cusparseSetMatType(descrA, CUSPARSE_MATRIX_TYPE_GENERAL);
cusparseSetMatIndexBase(descrA, CUSPARSE_INDEX_BASE_ZERO);
nnzTotal = (int*)malloc(sizeof(int));
cudaMalloc((void**)&nnzPerRow, m*sizeof(int));
cusparseDnnz(cusparse_handle, dirA_row, m, n, descrA, d_A, lda, nnzPerRow, nnzTotal);
cudaMalloc((void**)&csrValA, (*nnzTotal)*sizeof(double));
cudaMalloc((void**)&csrRowPtrA, (m+1)*sizeof(int));
cudaMalloc((void**)&csrColIndA, (*nnzTotal)*sizeof(int));
cudaMalloc((void**)&d_result, n*sizeof(double));
// MATRIX CONVERSE FROM DENSE TO SPARSE
cusparseDdense2csr(cusparse_handle, m, n, descrA, d_A, lda, nnzPerRow, csrValA, csrRowPtrA, csrColIndA);
// MATRIX VECTOR MULTIPLICATION
cusparseDcsrmv(cusparse_handle, NON_TRANS, m, n, *nnzTotal, &positive, descrA, csrValA, csrRowPtrA, csrColIndA, ONES_DEV, &zero, d_result);
const int one_SIZE=5400;
__常数uuu静态双1 u DEV[1 u SIZE];
const cusparseDirection\u t dirA\u row=cusparseDirection\u row;
const cusparseOperation\u t NON\u TRANS=cusparseu OPERATION\u NON\u TRANSPOSE;
int main(){
cudaSetDevice(0);
int m=一个尺寸;int n=2500;
双倍*HOST_ONES,*A,*d_A,*d_结果;
主机大小=(双*)malloc(一个大小*sizeof(双));
对于(int i=0;i,在跟踪API调用的同时,获取代码样本并使用Visual Profiler运行它,我得到以下结果:
其中cusparse方法正在调用cudaBindTexture。常量内存是一种特殊类型的内存,将纹理绑定到它似乎是不可能的,即使没有文档记录。您不希望对x
使用常量内存。常量内存需要统一访问才能发挥作用。向量的底层访问模式>x
执行矩阵向量积时,Ax
将不统一。统一意味着扭曲中的所有线程将在任何给定循环中访问同一位置。稀疏矩阵向量积不是这种情况。通常情况下,将常量内存用于cuSparse不是预期的使用情况。列出了预期的复制API,andcudaMemcpyToSymbol
未列出我可能会冒着猜测的风险:可能是cuSparse在执行稀疏矩阵x向量乘法时使用纹理从某种形式的缓存中获益。在这种情况下,它会将向量数据绑定到纹理以加速此操作。当然,您可能不会在上绑定指向常量内存的指针质地。