CuFFT не работает стабильно при изменении размера ввода [закрыто]C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 CuFFT не работает стабильно при изменении размера ввода [закрыто]

Сообщение Anonymous »

Я работаю над использованием CuFFT (CUDA версии 12.6.77 CuFFT версии 11.3.0.4) для преобразования вектора (

Код: Выделить всё

std::vector
) в пространство Фурье. Вектор используется для представления двумерной матрицы (основной по строкам) с одинаковыми размерами строки и столбца. Этот вектор инициализируется с использованием созданного мной базового класса под названием Data, который имеет вектор в качестве атрибута, но за пределами конструктора и нескольких методов, которые я создал для личного использования, все функции действуют так, как если бы это был просто переданный вектор. Конструктор этого класса позволяет мне указать размер в МБ, к которому я хотел бы, чтобы вектор был как можно ближе, и помещает широкую точку со значением 1 в середину «матрицы», чтобы результат выглядел так: гауссиан после преобразования. Я считаю, что причины создания этого класса в настоящее время не имеют отношения к моей проблеме.
Мне удалось добиться стабильной работы при использовании cudaMalloc и cufftPlan2d для размещения данных и планирования. память устройства (NVIDIA RTX 2000 Ada Generation GPU Laptop GPU с 8 ГБ ОЗУ), где преобразование выполняется в реальном времени, поэтому входная и выходная переменная совпадают.
Когда я масштабировал вектор размер, мне пришлось перейти к использованию cudaMallocHost и назначить рабочую область для плана вручную в памяти хоста, иначе устройству не хватит памяти для выполнения преобразования. Этот предел составлял ~3 ГБ для размера векторной памяти, поскольку, насколько я понимаю, для функционирования плана требуется примерно такой же объем рабочей области (заявление основано на выводах cufftEstimate2d и cufftGetSize2d). Это работало с теми же размерами ниже 3 ГБ и работает с размерами выше 3 ГБ, в отличие от исходной версии, как и ожидалось, за счет производительности. Однако некоторые размеры просто не работают, даже если работают большие размеры.
Для настройки и выполнения преобразования я использую следующий код:

Код: Выделить всё

// Creates vector with 187553025 elements, i.e. 13695 x 13695 matrix
// Takes up 3000.848424 MB of RAM as I requested 3001[MB] be used at max
Data source = Data( 3001 );

// Create cufftDoubleComplex pointer as it was the simplest way to achieve what I
// wanted, I intend on refining this to not require two copies of the data to be
// present.
cufftDoubleComplex *x{};
// full_size() is a method to return the number of elements in the vector
// in this case that is 187553025
cudaMallocHost(&x, source.full_size() * sizeof(cufftDoubleComplex));
// The data() method returns the pointer from vector.data() .
cudaError_t in_status = cudaMemcpy(
x,
reinterpret_cast(source.data()),
(std::size_t)(source.full_size() * sizeof(cufftDoubleComplex)),
cudaMemcpyHostToHost);
if (in_status != cudaSuccess)
throw std::invalid_argument( "CUDA Memory Copy error." );

// Create the cufftHandle that will become the plan but make it so
// no workArea is assigned by default
cufftHandle p;
cufftSetAutoAllocation(p, false);

// The size() method returns the length of one side of the matrix being represented
// in this case 13695
cufftPlan2d(&p, source.size(), source.size(), CUFFT_Z2Z);

size_t *workArea;
// get_memory_size() is a method to return the memory size the vector requires.
// This size is chosen as cufftGetSize2d returns a value equal to or lower than
// this, most of the time.
cudaMallocHost(&workArea, size_t(source.get_memory_size()));
cufftSetWorkArea(p, workArea);

// using Z2Z as I am using double precision.
cufftExecZ2Z(p, x, x, CUFFT_FORWARD);
cudaDeviceSynchronize();
cufftDestroy(p);
cudaError_t out_status = cudaMemcpy(
source.data(),
reinterpret_cast(x),
(std::size_t)(source.full_size() * sizeof(cufftDoubleComplex)),
cudaMemcpyHostToHost);
if (out_status != cudaSuccess)
throw std::invalid_argument( "CUDA Memory Copy error." );
cudaFree(x);
После этого я строю график, чтобы убедиться, что все работает так, как ожидалось. Опять же, для большинства размеров он работает нормально, но время от времени возникают пробелы в размере матрицы, когда он действует так, как если бы он выполнил преобразование, но выходные данные представляют собой просто вектор нулей, а время выполнения составляет менее 1 мс. Например, если установить максимальный объем памяти равным 3000 [МБ], в результате чего получится матрица размером 13693 x 13693, то при использовании 2999,972008 [МБ] памяти на выходе будут только нули. Увеличение этого значения до 3001 [МБ], в результате чего получается матрица размером 13695 x 13695 с использованием 3000,848424 [МБ] памяти, внезапно дает именно тот результат, который я ожидал. Есть и другие размеры, где они тоже терпят неудачу, но я не понимаю, почему они терпят неудачу. Я также проверил предполагаемый размер рабочей области для неудачных преобразований, и они кажутся примерно в 4 раза больше, чем те, где это удалось. Таким образом, для случая 3000 [МБ] по оценкам, потребуется ~ 12 [ГБ] рабочей области, даже если я дам ему запрошенный размер рабочей области, это все равно не удастся. Кто-нибудь случайно знает, что может быть причиной такого поведения?

Подробнее здесь: https://stackoverflow.com/questions/793 ... input-size
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»