VkFFT – Vulkan快速傅立叶变换库

2020-11-21 20:23:35

VkFFT是用于Vulkan项目的高效GPU加速的多维快速傅立叶变换库。 VkFFT旨在为社区提供Nvidia的cuFFT库的开源替代方案,同时实现更好的性能。 VkFFT用C语言编写。

我正在寻找对我的技能感兴趣的博士学位职位/工作。通过电子邮件与我联系:[email protected] | [email protected]

为基准添加了Windows可执行文件:具有CUDA基准的版本(需要CUDA 11),没有(仅需要图形驱动程序)的版本。两者都需要将着色器文件夹放置在与可执行文件相同的位置。使用约3.5GB的VRAM。位于Vulkan_FFT_CUDA_v1.0.5.zip和Vulkan_FFT_noCUDA_v1.0.5.zip中。内置VS2019。

支持较大的FFT尺寸。单精度和半精度的电流限制:C2C-(2 ^ 32,2 ^ 32,2 ^ 32)。寄存器过度使用的C2R / R2C-(2 ^ 14,2 ^ 32,2 ^ 32)。 (稍后会增加)。电流限制为双精度:C2C-(2 ^ 32,2 ^ 32,2 ^ 32),C2R / R2C-(2 ^ 11,2 ^ 32,2 ^ 32)无寄存器过度使用。内存应在一个堆中分配为单个缓冲区。

单精度,双精度和半精度支持。双精度使用CPU生成的LUT表。半精度仍然可以单次执行所有计算,并且仅使用半精度存储数据。

所有转换都就地执行,而不会降低性能。通过选择不同的输入/输出缓冲区,可以支持异位转换。

没有其他移调上传。注意:经过四步FFT算法后,可以使用额外的缓冲区(适用于大序列)重新整理数据。卷积无关紧要-卷积返回输入顺序(节省内存)。

复杂到复杂(C2C),实到复杂(R2C)和复杂到真实(C2R)转换。 R2C和C2R经过优化,运行速度比C2C快2倍(仅限2D和3D情况)

用于对开放系统进行建模的本机零填充(比简单地用零填充输入数组快2倍)

WHDCN布局-数据按以下顺序存储(按步幅增加排序):宽度,高度,深度,坐标(要素图的数量),批号

可在Nvidia,AMD和Intel GPU上运行(在Nvidia RTX 3080,GTX 1660 Ti,AMD Radeon VII和Intel UHD 620上测试)

具有Vulkan接口的仅标头(+预编译着色器)库,该库允许将VkFFT直接附加到用户的命令缓冲区

包括vkFFT.h文件,并在CMake中或从C接口指定着色器文件夹的路径。样本CMakeLists.txt文件基于Vulkan_FFT.cpp文件配置了项目,该文件包含有关如何使用VkFFT进行FFT,iFFT和卷积计算,使用零填充,多特征/批处理卷积,大型系统的C2C FFT,R2C / C2R的示例变换,双精度FFT,半精度FFT。对于单精度和双精度,需要Vulkan 1.0。对于半精度,需要Vulkan 1.1。

VkFFT具有带有以下命令集的命令行界面:-h:打印帮助-devices:打印可用GPU设备的列表-d X:选择GPU设备(默认0)-o NAME:指定输出文件路径-vkfft X:启动VkFFT示例X(0-9)-袖扣X:启动cuFFT示例X(0-3)(如果在CMakeLists.txt中启用)-test :(或没有其他键)启动所有VkFFT和cuFFT基准测试启动VkFFT和cuFFT的单精度基准测试并将命令保存到设备0上的log.txt文件的命令在Windows上将如下所示:。\ Vulkan_FFT.exe -d 0 -o output.txt -vkfft 0 -cufft 0用于双精度基准,将-vkfft 0 -cufft 0替换为-vkfft 1 -cufft1。对于半精度基准,请将-vkfft 0 -cufft 0替换为-vkfft 2 -cufft 2。

VkFFT.h是一个库,可以将FFT,iFFT或卷积计算附加到用户定义的命令缓冲区。它在用户分配的存储缓冲区上运行,并且本身不需要任何额外的内存。所有计算完全基于Vulkan计算着色器,除了FFT计划外,不占用CPU。 VkFFT自行创建和优化内存布局,并使用最佳选择的参数执行FFT。有关示例应用程序,请参见Vulkan_FFT.cpp文件,该文件具有解释VkFFT配置过程的注释。 VkFFT通过对附近的FFT(而不是转置)进行分组来实现跨步。

为了衡量与cuFFT相比Vulkan FFT的实现方式如何工作,我们将执行从小型系统到大型系统的一系列1D,2D和3D测试。该测试将包括连续执行C2C FFT和C2C逆FFT多次以计算所需的平均时间。结果是在没有其他GPU负载的Nvidia RTX 3080和AMD Radeon VII显卡上获得的。从Vulkan_FFT.cpp启动-test键执行VkFFT / cuFFT基准测试。总体基准分数是作为表示的一组系统上的平均性能分数来计算的(越大越好):sum(system_size / average_iteration_time)/ num_benchmark_samples

RTX 3080图形上显示的稳定平线表示时间与Nvidia GPU上的系统大小成线性比例,因此带宽越大,结果越好。当计算单元无法保存完整序列并将其拆分为较小序列的组合时,一旦传输量从增加到2x到3x,就会出现逐步下降。 Radeon VII由于具有更高带宽的HBM2内存,因此在2 ^ 17以下的速度比RTX 3080更快,但是,此GPU显然在较大的缓冲区大小上存在TLB丢失问题。在RTX 3080上,在2 ^ 7至2 ^ 28的整个范围内,单精度批处理1D FFT中的VkFFT均比cuFFT快:在双精度中,Radeon VII由于其双精度内核数高而能够获得优势:在半精度中在VkFFT模式下,VkFFT仅将其用于数据存储,所有计算都在单个步骤中进行,仍然证明足以在RTX 3080上获得稳定的2倍性能增益:对零填充的原生支持允许传输更少的数据并获得3倍的性能增强多维FFT:

为了测量VkFFT(单精度/双精度)与cuFFT(单精度/双精度)和FFTW(双精度)的比较,一组覆盖整个FFT范围的〜50个系统填充了[-1的随机复杂数据,1],并且在每个系统上执行一次C2C转换。 Benchmark_precision_scripts文件夹中的precision_cuFFT_VkFFT_FFTW.cu脚本包含比较代码,该代码为转换后的系统的每个值计算:

cuFFT / VkFFT结果与FFTW结果之差与FFTW结果的最大比值

cuFFT / VkFFT结果与FFTW结果之差与FFTW结果的平均比率

precision_cuFFT_VkFFT_FFTW.txt文件包含Nvidia的1660Ti GPU和AMD Ryzen 2700 CPU的单精度结果。平均而言,cuFFT和VkFFT的结果均出现波动,单精度没有明显的赢家。对于cuFFT和VkFFT,最大比例保持在2%的范围内,而平均比例保持在1e-6以下。 precision_cuFFT_VkFFT_FFTW_double.txt文件包含Nvidia的1660Ti GPU和AMD Ryzen 2700 CPU的双精度结果。平均而言,VkFFT在双精度方面比cuFFT更为精确(请参阅:max_difference和max_eps列),但也慢了约20%(vkfft_benchmark_double.png)。请注意,双精度仍在测试中,将来这些结果可能会更改。对于cuFFT和VkFFT,最大比例保持在5e-10%的范围内,而平均比例保持在1e-15以下。总体而言,双精度比Nvidia的1660Ti GPU慢约7倍。 precision_cuFFT_VkFFT_FFTW_half.txt文件包含Nvidia的1660Ti GPU和AMD Ryzen 2700 CPU的一半精度结果。平均而言,VkFFT的精度至少是cuFFT的一半,精度是cuFFT的两倍(请参见:max_difference和max_eps列),而平均速度则更快(vkfft_benchmark_half.png)。请注意,半精度仍在测试中,仅用于存储VkFFT中的数据。 cuFFT脚本也可能会得到改进。 cuFFT和VkFFT的平均比率都在0.2%的范围内。总体而言,VkFFT的半精度比Nvidia的1660Ti GPU的单精度快约50%-100%倍。

VkFFT的初始版本由Tolmachev Dmitrii PeterGrünberg和高级仿真研究所(ForschungszentrumJülich,D-52425Jülich,德国)开发。电子邮件1:[email protected]电子邮件2:dtolm96 @ gmail。 com