Использование памяти в линейном решателе cuda cusp

Я использую cusp::bicgstab для решения линейной системы Ax=b, в которой A представляет собой трехмерную пуассоновскую сетку MxNxP, x — неизвестно, а b — правая сторона. У меня есть K40m Tesla с 12 ГБ памяти.

Я тестировал с M=2000, N=2000, P=20 (80 миллионов неизвестных), тип переменной double; поэтому общий объем используемой памяти (для A, x, b и других) составляет приблизительно 5,5 ГБ. Код работает нормально.

Затем я увеличил значение M или N до 2500 (используемая память по-прежнему намного меньше 12 ГБ), программа обнаружила следующую ошибку:

завершение вызывается после создания экземпляра 'thrust::system::detail::bad_alloc'

what(): std::bad_alloc: out of memory
Прервано (сброшено ядро)

Я вижу, что ошибка недостаточно памяти устройства. Поэтому меня интересует управление памятью в библиотеке cusp. Использует ли он примерно такое же пространство памяти для дополнительных переменных (как используется для A,x,b) во время итераций для решения системы?

Ниже мой код:

#include <iostream>
#include <cuda.h>
#include <cuda_runtime_api.h>

#include <cusp/monitor.h>
#include <cusp/krylov/bicgstab.h>
#include <cusp/gallery/poisson.h>
#include <cusp/print.h>

// where to perform the computation
typedef cusp::device_memory MemorySpace;

// which floating point type to use
typedef double ValueType;

int main(int argc, char **argv)
{
    size_t avail, total;                // Available and Total memory count
    int N = 2500, M = 2000, P = 20;     // Dimension
    
    // create a matrix for a 3D Poisson problem on a MxNxP grid
    cusp::dia_matrix<int, ValueType, MemorySpace> A;
    cusp::gallery::poisson7pt(A, N, M, P);

    // allocate storage for solution (x) and right hand side (b)
    cusp::array1d<ValueType, MemorySpace> x(N*M*P, 0.0);
    cusp::array1d<ValueType, MemorySpace> b(N*M*P, 1.0);
    
    // set preconditioner (identity)
    cusp::identity_operator<ValueType, MemorySpace> ID(A.num_rows, A.num_rows);
    
    // Set stopping criteria:
    // ... iteration_limit    = 100
    // ... relative_tolerance = 1e-9
    // ... absolute_tolerance = 0
    cusp::default_monitor <ValueType> monitor(b, 100, 1e-9);

    // solve the linear system A x = b
    cusp::krylov::bicgstab(A, x, b, monitor, ID);

    // Get device memory usage
    cudaMemGetInfo( &avail, &total );
    size_t used = total - avail;
    std::cout << "Device memory used: " << used/(1024.*1024.*1024.) << " Gb " << std::endl;
    
    return 0;
}

person PLe    schedule 04.11.2015    source источник


Ответы (1)


Вы можете прочитать исходный код для bicgstab решателя сами, но похоже, что есть восемь временных массивов, в каждом из которых столько же записей, сколько строк в вашей матрице. Если я правильно прочитал ваш код, это означает, что вам потребуется не менее 8 * N * M * P * sizeof(double) байтов свободной памяти графического процессора при входе в вызов bicgstab для запуска решателя.

person Community    schedule 04.11.2015
comment
Ты прав. В bicgstab используется 8 дополнительных временных массивов. Трехмерные задачи Пуассона имеют 9 массивов (A:7, b:1, x:1), поэтому используемая пиковая память составляет около 17 * N * M * P * sizeof(double). Теперь все понятно. - person PLe; 04.11.2015