我正在尝试使用preconditoned共轭渐变来解析Ax = b。
所以我用cuda-sdk给出了样本。
有时,当我调用函数cusparseScsrsv_analysis
时,它会返回错误6,即“执行失败”。有时,它有效。
矩阵A是对称正定。
此外,共轭梯度在相同数据上正常工作。
这是我的代码:
/* Get handle to the CUSPARSE context */
cusparseHandle_t cusparseHandle = 0;
cusparseStatus_t cusparseStatus;
cusparseStatus = cusparseCreate(&cusparseHandle);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseCreate returned error code %d !\n", cusparseStatus);
cusparseMatDescr_t descr = 0;
cusparseStatus = cusparseCreateMatDescr(&descr);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseCreateMatDescr returned error code %d !\n", cusparseStatus);
// create the analysis info object for the A matrix
cusparseSolveAnalysisInfo_t infoA = 0;
cusparseStatus = cusparseCreateSolveAnalysisInfo(&infoA);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseCreateSolveAnalysisInfo returned error code %d !\n", cusparseStatus);
// Perform the analysis for the Non-Transpose case
cusparseStatus = cusparseScsrsv_analysis(cusparseHandle, CUSPARSE_OPERATION_NON_TRANSPOSE, N, nnz, descr, dev_val, dev_row_ptr, dev_colInd, infoA);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseScsrsv_analysis 1 returned error code %d !\n", cusparseStatus);
N是列数和行数,nnz是非零元素的数量。我的矩阵采用csr格式。
编辑: 我没有看到任何特殊要求。我不认为这是记忆,我有超过2GB,我没有使用大矩阵(48MB)。
我用jacobi precondionner尝试了预处理的共轭梯度,它也可以正常工作,但如果我尝试用cusparse进行分析,它会失败一半。
我想要的是使用cusparse和cublas的Maxim Noumov算法(http://developer.download.nvidia.com/compute/DevZone/docs/html/CUDALibraries/doc/Preconditioned_Iterative_Methods_White_Paper.pdf)。
EDIT2 :
我需要一些关于curspace的解释。如果我在描述符中放入这一行:cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_SYMMETRIC);
分析有效,但奇怪的是我不仅存储整个矩阵的上部或下部。如果我放cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_GENERAL);
,它就不起作用。此外,我不明白为什么我必须存储在dev_row_ptr
m + 1个元素中,其中m是行数。我在最后一个元素中放了什么?
其他问题:
函数cusparseScsric0
将矩阵值(文档中的csrValM)作为输入/输出,它是作为输入的整个矩阵,而不完整的CHolesky上部或下部三角形仅作为输出。它是如何工作的?
答案 0 :(得分:1)
关于cusparseScsric0
的cusparse文档是错误的,它需要CUSPARSE_MATRIX_TYPE_SYMMETRIC
作为输入。此功能使cusparseScsrsv_analysis
崩溃。
这是一个正确的代码:
cusparseMatDescr_t descrR = 0;
cusparseStatus = cusparseCreateMatDescr(&descrR);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseCreateMatDescr returned error code %d !\n", cusparseStatus);
cusparseSetMatFillMode(descrR,CUSPARSE_FILL_MODE_UPPER); // It can also be lower side
cusparseSetMatType(descrR,CUSPARSE_MATRIX_TYPE_SYMMETRIC);
cusparseSetMatIndexBase(descrR,CUSPARSE_INDEX_BASE_ZERO);
cusparseSolveAnalysisInfo_t infoR = 0;
cusparseStatus = cusparseCreateSolveAnalysisInfo(&infoR);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseCreateSolveAnalysisInfo returned error code %d !\n", cusparseStatus);
cusparseStatus = cusparseScsrsv_analysis(cusparseHandle, CUSPARSE_OPERATION_NON_TRANSPOSE, 27, 153, descrR, dev_valR, dev_row_ptrR, dev_colIndR, infoR);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseScsrsv_analysis returned error code %d !\n", cusparseStatus);
// generate the Incomplete Cholesky factor H for the matrix R using cusparseScsric0
cusparseStatus = cusparseScsric0(cusparseHandle, CUSPARSE_OPERATION_NON_TRANSPOSE, 27, descrR, dev_valR, dev_row_ptrR, dev_colIndR, infoR);
if(cusparseStatus!=CUSPARSE_STATUS_SUCCESS)
fprintf(stderr, "cusparseScsric0 returned error code %d !\n", cusparseStatus);
同样dev_row_ptrR
是行数+ 1。