FFTW库安装(Linux系统)
https://zhuanlan.zhihu.com/p/600161033
本文主要介绍在Linux系统下使用GCC和OpenMPI安装FFTW库。
一、什么是FFTW
FFTW意为Faster Fourier Transform in the West,是一个C语言的快速计算离散傅里叶变换库,它是由MIT的M.Frigo和S. Johnson开发的,可计算一维或多维实和复数据以及任意规模的DFT。目前最新版本为3.3.10,其官网地址为:https://www.fftw.org/。
大量测试结果表明,FFTW库要比其它开源傅里叶变换库或软件要快,因此如果你的程序中包含傅里叶变换的相关计算,FFTW库是一个很好的选择。
二、环境要求
本安装教程的系统要求为Linux,需要读者已经安装好了GCC和OpenMPI。
三、安装流程
1、下载安装包
本文以3.3.8版本为例,读者可以去官网寻找相应的压缩包,也可以直接点击下面的链接进行下载。
下载完成文件是.tar.gz格式的压缩包。
2、安装前准备
先创建一个新的文件夹用来放置安装完成后的库文件:
mkdir /home/xxx/usr/fftw
上面语句中的/home/xxx代表个人用户的主目录或者root账户的根目录。
然后解压之前下载的安装包:
tar -xzvf fftw-3.3.8.tar.gz
关于tar解压命令可以看我的另一篇文章:
进入解压后的文件夹:
cd fftw-3.3.8/
3、安装
FFTW的编译分为三步:
./configure #进行安装配置
make #编译
make install #安装
下面逐步进行讲解。
(1)进行安装配置
./configure --prefix=/home/xxx/usr/fftw --enable-mpi --enable-openmp --enable-threads --enable-shared MPICC=mpicc CC=gcc F77=gfortran
输入完成后按回车键进行配置。
下面对这里用到的参数做简单介绍:
- --prefix:设定安装目录
- --enable-mpi:是否编译mpi版的fftw库
- --enable-openmp:是否使用OpenMP指令进行并行
- --enable-threads:是否编译FFTW SMP线程库
- --enable-shared:是否编译动态库
- MPICC:指定C语言的MPI编译器
- CC:指定C语言的编译器
- F77:指定Fortran 77的编译器
除了以上参数外,还有许多其他参数读者可通过./configure --help命令来查看具体含义,然后根据自己的需求来进行配置。
(2)编译
make
输入之后按回车键进行编译。
(3)安装
make install
输入完成后按回车键进行安装。
执行完以上3个步骤后即完成安装。
4、设置环境变量
安装完成后还需要在.bashrc中设置FFTW库相关的环境变量,打开~/.bashrc,在其中添加如下代码:
export LD_LIBRARY_PATH=/home/xxx/usr/fftw/lib:$LD_LIBRARY_PATH
保存并退出后用source ~/.bashrc命令更新环境变量。
四、测试
以下附上一段测试代码:
#include<iostream>
#include<iomanip>
#include<fftw3.h>
using namespace std;
int main(){
int N=10;
fftw_complex *in,*out;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
if((in==NULL)||(out==NULL)){
printf("Error:insufficient available memory\n");
}
else{
for(int i=0; i<N; i++){
in[i][0] = i+1;
in[i][1] = 0;
}
}
fftw_plan p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD,FFTW_ESTIMATE);
fftw_execute(p); /* repeat as needed */
fftw_destroy_plan(p);
fftw_cleanup();
for(int i=0;i<N;i++){/*OUTPUT*/
cout<<setprecision(6)<<setiosflags(ios::fixed);
cout<<in[i][0]<<", "<<in[i][1]<<"i"<<endl;
}
cout<<endl;
for(int i=0;i<N;i++){/*OUTPUT*/
cout<<setprecision(6)<<setiosflags(ios::fixed);
cout<<out[i][0]<<", "<<out[i][1]<<"i"<<endl;