Эффективное двухмерное БПФ для реальных входных данных?

В настоящее время я реализую двумерное БПФ для реальных входных данных с использованием opencl (точнее, быструю двумерную свертку с использованием БПФ, поэтому мне нужно только что-то, что ведет себя аналогично достаточно, чтобы применить свертку). Двумерное БПФ реализуется с использованием одномерного БПФ по строкам, а затем одномерного БПФ по столбцам.

Чтобы сделать это более эффективным, я пытаюсь использовать симметрию БПФ с реальным вводом, чтобы иметь возможность вычислять меньшие БПФ. Я обнаружил, что могу объединить две строки в одну, используя первую как реальный компонент, второй как мнимый компонент, выполнить первое 1D БПФ в результирующей строке, а затем использовать свойства симметрии для построения результатов 1D БПФ отдельного человека. ряды от этого. Итак, я делаю в основном следующее:

Пусть f и g будут строками из матрицы.

  1. Построить x = f + i * g
  2. Преобразовать, чтобы получить F ( x) = F (f) + i * F (g)
  3. Используйте симметрии, чтобы извлечь F (f) и F (g) из F (x)

Однако я не могу просто ввести результаты непосредственно во 2-е 1D FFT, потому что в этом случае я бы преобразовал не всю матрицу, а две подматрицы. Однако извлечение данных между преобразованиями означает либо сохранение дополнительных данных ( n / 2 + 1 записей, необходимых для выражения результата одномерного БПФ на реальном вводе), либо объединение элементов с индексом 0 ] и индекс n / 2 в один элемент (объединение с использованием того же трюка, поскольку оба числа гарантированно являются действительными) и используют один и тот же объем памяти, но в моей свертке необходимо сделать особый случай для этого.

Поскольку я стараюсь повторно использовать буферы в максимально возможной степени (из-за ограниченного объема ОЗУ, доступного gpu) с использованием большего объема памяти - не лучшее решение. Кроме того, мои алгоритмы не приспособлены для работы с размерами матриц, которые не являются степенью 2 / кратных 16 (варьируется от ядра к ядру). Я бы предпочел не вводить особые случаи, поскольку они усложнили бы мои ядра и снизили бы эффективность (у меня уже есть проблемы с минимизацией количества регистров, используемых каждым ядром).

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

В идеале я хотел бы иметь возможность выполнять полное БПФ, не разделяя мои объединенные данные в середине БПФ, но я не уверен это возможно.

6
задан Grizzly 19 October 2010 в 00:27
поделиться