并行快速傅里叶变换 mpi4py-fft

本文从本人简书博客同步过来

上一篇中我们介绍了一个使用 mpi4py 实现的并行日志工具 —— python-mpi-logger,下面将介绍一个并行的快速傅里叶变换库 —— mpi4py-fft。

快速傅里叶变换(FFT)简介

快速傅里叶变换(Fast Fourier Transform, FFT),是快速计算序列的离散傅里叶变换(DFT)或其逆变换的方法。傅里叶分析将信号从原始域(通常是时间或空间)转换到频域的表示或者逆过来转换。FFT 会通过把 DFT 矩阵分解为稀疏(大多为零)因子之积来快速计算此类变换。因此,它能够将计算 DFT 的复杂度从只用 DFT 定义计算需要的 O(n2)降低到 O(n log n),其中 n 为数据大小。

快速傅里叶变换广泛地应用于工程、科学和数学领域。1994年美国数学家吉尔伯特·斯特朗把 FFT 描述为“我们一生中最重要的数值算法”,它还被 IEEE 科学与工程计算期刊列入 20 世纪十大算法。

numpy.fft 模块提供了进行快速傅里叶变换的函数,可以对 1 维,2 维或更高维的数值进行快速傅里叶变换,不过 numpy.fft 只能对完整的数据集或者分布式数据集的某些完整的数据轴进行快速傅里叶变换操作,无法直接对一个分布在不同进程上的数据轴进行快速傅里叶变换。

下面是 numpy.fft 模块用于快速傅里叶变换的主要函数:

fft(a[, n, axis, norm])

计算数组 a 沿轴 axis 的 1 维快速傅里叶变换。

ifft(a[, n, axis, norm])

计算数组 a 沿轴 axis 的 1 维快速逆傅里叶变换。

fft2(a[, s, axes, norm])

计算数组 a 沿轴 axes 的 2 维快速傅里叶变换。

ifft2(a[, s, axes, norm])

计算数组 a 沿轴 axes 的 2 维快速逆傅里叶变换。

fftn(a[, s, axes, norm])

计算数组 a 沿轴 axes 的 n 维快速傅里叶变换。

ifftn(a[, s, axes, norm])

计算数组 a 沿轴 axes 的 n 维快速逆傅里叶变换。

关于 numpy.fft 模块的更多快速傅里叶变换相关的方法及其参数介绍请参加其文档

下面我们介绍一个使用 mpi4py 对(大的)多维数组(可以分布在多个 MPI 进程上)进行快速傅里叶变换的工具 —— mpi4py-fft。

mpi4py-fft

mpi4py-fft 是一个用于并行快速傅里叶变换计算的 Python 包。它可以分布及重新分布以多种方式分布在多个 MPI 进程上的多维数组,并对其沿任意指定轴(可以是多个轴,包括数据分布轴)进行快速傅里叶变换。mpi4py-fft 支持 FFTW 库(快速傅里叶变换的最快的自由软件实现)中的各种变换方法及它们的各种组合,它提供了 FFTW 库中各种变换方法的 Python 接口。另外,mpi4py-fft 也可以仅仅只对大的数组进行分布及重新分布(借助 mpi4py)而不做任何傅里叶变换操作。

mpi4py-fft 包含如下 4 个主要模块:

  • mpifft
  • pencil
  • libfft
  • fftw

mpifft.PFFT 类是做并行快速傅里叶变换的主要入口,这是一个功能强大而丰富的类,它能够自动完成沿各个轴的各种变换所需的(大)数组分布等任务。

pencil 具体完成数组的全局分布(通过 mpi4py)。一般情况下并不直接使用该模块,除非你仅仅只需进行数组的分布操作而不做任何傅里叶变换。mpifft.PFFT 在底层大量使用 pencil 模块的相关功能。

libfft 模块提供了一个(非并行)调用 FFTW 库中相关变换函数的通用的接口。

fftw 模块是对 FFTW 库中相应变换函数的具体包装。通过此模块,用户基本上可以直接在 Python 中使用 FFTW 库中的几乎任何功能。

下载和安装 mpi4py-fft

用下面的命令下载和安装 mpi4py-fft;

git clone https://bitbucket.org/mpi4py/mpi4py-fft.git
cd mpi4py-fft
export FFTW_ROOT=/path/to/your/FFTW
python setup.py install [--user] 

数组的全局分布

在高性能计算中,大的多维数组一般会分布在多个处理器上(这些处理器可以处于不同的物理机器上),我们称之为数组的全局分布。

mpi4py-fft 的 pencil 模块提供了 Pencil、 Subcomm 和 Transfer 三个类用来进行数组的全局分布。

下面是这三个类的定义及主要方法接口:

Pencil 类

class Pencil(object)

Pencil 类,表示一个分布式的数组。

def __init__(self, subcomm, shape, axis=-1)

初始化方法,subcomm 为 MPI 通信子或者一系列的 MPI 通信子。shape 为数组的 shape,axis 为数组对齐的轴(即不分布的轴)。

def pencil(self, axis)

返回一个在 axis 轴上对齐的 Pencil 对象。

def transfer(self, pencil, dtype)

返回一个 Transfer 类对象,该对象能进行当前的 Pencil 对象和参数 pencil 所表示的全局分布之间的相互转换。datatyp 为所使用的数据类型。

Subcomm 类

class Subcomm(tuple)

Subcomm 类,为表示多维数组分布的一系列通信子对象所组成的 tuple。

def __new__(cls, comm, dims=None, reorder=True)

构造方法,comm 为一个或一系列 MPI 通信子,dim 可为 None,一个整数或者一系列整数,指定分布在各维的进程数,对大于 0 的值会保持该值指定的进程数,对等于 0 的值所对应的维会根据总的进程数进行分配。所用应该使用 0 指定自动进程分配的分布轴,用 1 指定在该轴上不做分布,其它大于 0 的数值指定在该轴上分布的进程数。

Transfer 类

class Transfer(object)

Transfer 类,执行数组的全局分布操作。

def __init__(self, comm, shape, dtype, subshapeA, axisA, subshapeB, ax
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要基于软件仿真实现基4-FFT快速傅里叶变换,并使用 DSP 库函数对方波信号进行定点 FFT,您可以按照以下步骤进行操作: 1. 生成方波信号 首先,您需要生成一个方波信号,用于测试 FFT 算法的正确性。您可以使用 MATLAB 的 `square()` 函数生成一个方波信号,并将其保存到一个数组中。例如,以下代码生成一个周期为 16 个采样点的方波信号: ```matlab x = square(2*pi*(0:15)/8); ``` 2. 定义基4-FFT算法 接下来,您需要定义基4-FFT算法,以便对方波信号进行定点 FFT。您可以使用 MATLAB 中的函数来实现基4-FFT算法,并将其保存到一个 `.m` 文件中,以便在仿真中使用。 3. 调用 DSP 库函数 在仿真中,您可以使用 DSP 库中的函数来对方波信号进行定点 FFT。例如,可以使用 `fft()` 函数来计算方波信号的 FFT。为了将 FFT 结果转换为定点格式,您可以使用 `fi()` 函数将浮点数转换为定点数。例如,以下代码计算方波信号的 FFT,并将结果转换为 Q15 格式: ```matlab % 计算方波信号的 FFT y = fft(x); % 将 FFT 结果转换为定点格式(Q15) y_fixed = fi(y, 1, 15, 15); ``` 4. 仿真测试 最后,您可以对整个算法进行仿真测试,以验证其正确性。您可以使用 MATLAB 的仿真工具来模拟整个算法,并观察仿真结果。如果仿真结果与预期结果相一致,则表明算法实现正确。 总之,基于软件仿真的基4-FFT快速傅里叶变换,调用 DSP 库函数对方波信号进行定点 FFT,是一种简单而有效的方式,用于测试 FFT 算法的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值