В настоящее время я реализую двумерное БПФ для реальных входных данных с использованием opencl (точнее, быструю двумерную свертку с использованием БПФ, поэтому мне нужно только что-то, что ведет себя аналогично достаточно, чтобы применить свертку). Двумерное БПФ реализуется с использованием одномерного БПФ по строкам, а затем одномерного БПФ по столбцам.
Чтобы сделать это более эффективным, я пытаюсь использовать симметрию БПФ с реальным вводом, чтобы иметь возможность вычислять меньшие БПФ. Я обнаружил, что могу объединить две строки в одну, используя первую как реальный компонент, второй как мнимый компонент, выполнить первое 1D БПФ в результирующей строке, а затем использовать свойства симметрии для построения результатов 1D БПФ отдельного человека. ряды от этого. Итак, я делаю в основном следующее:
Пусть f
и g
будут строками из матрицы.
x = f + i * g
F ( x) = F (f) + i * F (g)
F (f)
и F (g)
из F (x)
Однако я не могу просто ввести результаты непосредственно во 2-е 1D FFT, потому что в этом случае я бы преобразовал не всю матрицу, а две подматрицы. Однако извлечение данных между преобразованиями означает либо сохранение дополнительных данных ( n / 2 + 1
записей, необходимых для выражения результата одномерного БПФ на реальном вводе), либо объединение элементов с индексом 0
] и индекс n / 2
в один элемент (объединение с использованием того же трюка, поскольку оба числа гарантированно являются действительными) и используют один и тот же объем памяти, но в моей свертке необходимо сделать особый случай для этого.
Поскольку я стараюсь повторно использовать буферы в максимально возможной степени (из-за ограниченного объема ОЗУ, доступного gpu) с использованием большего объема памяти - не лучшее решение. Кроме того, мои алгоритмы не приспособлены для работы с размерами матриц, которые не являются степенью 2 / кратных 16 (варьируется от ядра к ядру). Я бы предпочел не вводить особые случаи, поскольку они усложнили бы мои ядра и снизили бы эффективность (у меня уже есть проблемы с минимизацией количества регистров, используемых каждым ядром).
Так что мой вопрос в том, есть ли элегантный подход к этой проблеме, что означает тот, который будет работать без использования дополнительной памяти или особых случаев для определенных элементов?
В идеале я хотел бы иметь возможность выполнять полное БПФ, не разделяя мои объединенные данные в середине БПФ, но я не уверен это возможно.