Я пытаюсь использовать предварительно обусловленный сопряженный градиент для разрешения 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.
РЕДАКТИРОВАТЬ: я не вижу никаких особых требований. Я не думаю, что это из-за памяти, у меня больше 2Гб и я не использую большую матрицу (48Мб).
Я попробовал предварительно обусловленный сопряженный градиент с предварительным условием Якоби, и он тоже работает правильно, но если я попытаюсь проанализировать с помощью cusparse, он не сработает в половине случаев.
Я хочу использовать алгоритм Максима Нумова (http://developer.download.nvidia.com/compute/DevZone/docs/html/CUDALibraries/doc/Precondition_Iterative_Methods_White_Paper.pdf) с использованием cusparse и cublas.
EDIT2:
Мне нужно некоторое объяснение о curspace. Если я вставлю в дескриптор эту строчку: cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_SYMMETRIC);
анализ работает, но странно то, что я храню всю матрицу, а не только верхнюю или нижнюю часть. Если я поставлю cusparseSetMatType(descr,CUSPARSE_MATRIX_TYPE_GENERAL);
, это не сработает. Более того, я не понимаю, почему я должен хранить dev_row_ptr
m+1 элементов, где m — номер строки. Что мне вставить в последний элемент?
Другой вопрос: функция cusparseScsric0
принимает на вход/выход значение матрицы (csrValM в документации), которое является всей матрицей на входе и неполным верхним или нижним треугольником Чолесского только на выходе. Как это работает ?