LINUX.ORG.RU

FFT на GPU, максимальный размер массива

 , ,


0

1

Всем здравствуйте! У меня есть самописанная программа для расчета кое-какой дифракции, смысл которой состоит в многократном взятии FFT от 2Д-массивов. Необходимо, чтобы массивы были размером 4k x 4k (или больше) и комплексные. Сейчас я использую fftw и MPI-параллелизацию, при разбрасывании на 100 процессоров на кластере выходит минут 20 на одну конфигурацию.

Конечно же, хочется это дело ускорить и упростить, и поговаривают что cuda поможет. Процесс переписывания может оказаться долгий и мучительный (у меня это всё на фортране пока что) и вовсе не обязательно, что он увенчается успехом ввиду больших массивов. Вот здесь в разделе 2.8.4 вообще написано что только до 2k при комплексных 2Д.

Может кто-нибудь подсказать, правильно ли я понимаю там по ссылке, что при 2Д и комплексных числах оно только до 2k x 2k? У меня комплексные вообще двойной точности. Не будет ли возня с cudo-й слишком долгой, из-за копирования туда-сюда больших массивов?

Размер зависит от памяти GPU, естественно.

Возьми число ячеек в исходной сетке, умножь на 4B или 8B (float/double), плюс примерно столько же заложи на буфер. Это если делать иin-place. Сколько у тебя в видеокарте, 8 гигов? Ну вот

Crocodoom ★★★★★
()
Ответ на: комментарий от Crocodoom

Точный размер требуемого буфера для внутренних нужд cuFFT можно получить специальной функцией, посмотри в доке

Crocodoom ★★★★★
()

Не будет ли возня с cudo-й слишком долгой, из-за копирования туда-сюда больших массивов?

А ты не копируй.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

спасибо за советы

всё-таки еще попробую поуточнять. У меня код следующего плана

for i=1,NN begin
  in=make_input(i);
  out=fft(in,forward);
  in=out*C1;
  out=fft(in,forward);
  in=out*C2;
  out=fft(in,forward);
  in=out*C3;
  total = total + in^2;
end

Соответственно in, out, C1, C2, C3 и total - двумерные массивы, там где умножение - там поэлементное. Процедура make_input достаточно хитрая, интерполирует численно рассчитанную функцию. Избавиться от переменных C1, C2 и C3 не выходит. Разбросать цикл по разным MPI процесса - уже сделал и работает (сейчас у меня NN может быть 20000), но как раз ищу другое решение. Вот и вопрос, правильно ли я понимаю что нужно будет in и out гонять из памяти в память и даст ли тут cufft прирост?

sshestov ★★
() автор топика
Ответ на: комментарий от Crocodoom

может ты опять что посоветуешь?

буду благодарен

sshestov ★★
() автор топика
Ответ на: спасибо за советы от sshestov

Фига у тебя embarrassingly parallel задачка

make_input может отработать на GPU? In-place FFT2D есть? Тогда тебе нужна из всего копирования только выгрузка с GPU финального out куда ты там его собрался выгружать.

t184256 ★★★★★
()
Ответ на: спасибо за советы от sshestov

Нет, гонять ничего не придётся. Но придётся написать собственный небольшой kernel, чтобы делать эти самые умножения внутри глобальной памяти. Такой kernel пишется тривиально, почитай туториалы

Crocodoom ★★★★★
()
Ответ на: комментарий от Crocodoom

а о прошлом годе изволил ...

... Федор Кузьмич, слава ему, сочинить шопенгауэр, а это вроде рассказа, только ни хрена ни разберешь.

sshestov ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.