CUSP CG конвергенция

Я использую метод сопряженных градиентов CUSP для решения моей симметричной разреженной матрицы. И я понятия не имею, почему это не сходится. Размеры используемых мной матриц не так велики (от 1К до 100К). Такие же линейные системы легко решаются с помощью MKL, поэтому матрица не является плохо обусловленной. Однако я попытался добавить предварительный кондиционер, но он не дал результатов:

Диагональный прекондиционер и AINV (неполный Cholesky) дали неограниченный рост остатка (пока cg и bicgstab)

Вот мой код:

cusp::csr_matrix <int, float, cusp::device_memory> A (n, n, nnz);

for (i = 0; i < n + 1; i++)
    A.row_offsets[i] = csrRowPtr[i] - 1;
for (i = 0; i < nnz; i++)
    A.values[i] = csrVal[i];
for (i = 0; i < nnz; i++)
    A.column_indices[i] = csrColInd[i] - 1;

cusp::array1d <float, cusp::device_memory> x (A.num_rows, 0);
cusp::array1d <float, cusp::device_memory> b (A.num_rows, 1);

for (i = 0; i < n; i++)
    b[i] = b_host[i];

cusp::verbose_monitor<float> monitor(b, 100, 1e-3);
cusp::identity_operator<float, MemorySpace> M(A.num_rows, A.num_rows);
    /*
    cusp::precond::diagonal<float, MemorySpace> M(A);
    cusp::precond::scaled_bridson_ainv<float, MemorySpace> M(A, .1);
    */
cusp::krylov::cg(A, x, b, monitor, M);

for (i = 0; i < n; i++)
    x_host[i] = x[i];

Почему это не работает правильно?

PS Как я понимаю, CUSP предполагает нулевой индекс, поэтому я уменьшаю csrRowPtr и csrColInd. Когда я использовал библиотеку nVidia cuSparse, была возможность установить другие параметры, такие как тип матрицы и режим заполнения. Как я могу быть уверен, что они правильно установлены в CUSP?

1 ответ

Только элементы из верхнего треугольника хранятся в формате CSR MKL, но все элементы должны храниться в формате CSR CUSP, даже если вы решаете симметричную линейную систему.

Также я думаю

for (i = 0; i < n; i++)
    x_host[i] = x[i];

не очень хорошая идея; сначала перенесите его обратно в host_memory

cusp::array1d<float, cusp::host_memory> _x = x;

затем скопируйте его обратно в x_host или любой другой массив результатов

for (i = 0; i < n; i++)
    x_host[i] = _x[i];
Другие вопросы по тегам