使用cuda常量内存时CUSPASE状态映射错误

使用cuda常量内存时CUSPASE状态映射错误,cuda,Cuda,我正在使用cuda cusparse库处理稀疏矩阵,我需要执行矩阵向量乘法(cusparseDcsrmv函数)。我有一个csr格式的稀疏矩阵d_a,当我调用这个函数时,在全局设备内存中分配向量d_x,一切都正常工作。但是,当我想使用驻留在恒定设备内存中的向量时,我遇到了一个错误:CUSPARSE\u STATUS\u MAPPING\u error 文档中说,通常的解决方案是取消绑定任何以前绑定的纹理,但这与我正在做的事情无关 有人知道发生了什么事吗 const int ONES_SIZE =

我正在使用cuda cusparse库处理稀疏矩阵,我需要执行矩阵向量乘法(cusparseDcsrmv函数)。我有一个csr格式的稀疏矩阵d_a,当我调用这个函数时,在全局设备内存中分配向量d_x,一切都正常工作。但是,当我想使用驻留在恒定设备内存中的向量时,我遇到了一个错误:CUSPARSE\u STATUS\u MAPPING\u error 文档中说,通常的解决方案是取消绑定任何以前绑定的纹理,但这与我正在做的事情无关

有人知道发生了什么事吗

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,and
cudaMemcpyToSymbol
未列出我可能会冒着猜测的风险:可能是cuSparse在执行稀疏矩阵x向量乘法时使用纹理从某种形式的缓存中获益。在这种情况下,它会将向量数据绑定到纹理以加速此操作。当然,您可能不会在上绑定指向常量内存的指针质地。