Ubuntu 14.04 LTS下配置MPICH、NetCDF、ifort环境
由于需要编写超算并行程序,为了本地测试的方便,我单机配了一下MPICH+ifort的环境,并安装了NetCDF等需要的库,现记录如下:
注意:安装完之后才发现我的那个程序不能用新版NetCDF且不能用gfortran跑,必须用旧版NetCDF+ifort,所以安装前一定要选好版本和编译器。
新版NetCDF安装过程写完舍不得删了,所以新旧版本的NetCDF安装过程在后面都写了。(在这里,新版指的是4.x,旧版指的是3.x)
总结一下:
- 如果是使用gfortran+新版NetCDF的组合,那么按照下面的步骤进行即可。
- 如果是使用ifort+旧版NetCDF的组合,下面也详细写了,按步骤进行即可。
- 如果是使用ifort+新版NetCDF的组合,可能与下面的安装过程有所出入,不过基本上就是编译时修改一下参数,可以参考NetCDF官方文档和Intel给出的教程。(文章最后有链接)
修改软件源
由于我是新装的系统,第一步当然是修改软件源了。执行sudo gedit /etc/apt/sources.list
,将文件的内容修改为
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-security main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-updates main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-backports main restricted universe multiverse
deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-proposed main restricted universe multiverse
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty main restricted universe multiverse
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-backports main restricted universe multiverse
deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ trusty-proposed main restricted universe multiverse
清华源的速度很快(北交也不错)。修改完之后执行sudo apt-get update
。
安装ifort
申请Intel的ifort编译器授权非常麻烦,我以学生身份申请,等待若干工作日之后,居然回复说我是以Educator身份申请,未提供课程名,授权数等等信息。我也同时申请了只有Linux版本的Open Source Contributor身份的方式,结果回复说没有具体的开源项目名、项目网站等。唉,用个编译器都这么难,大厂风范不过如此。
好在后来发现ifort有30天试用版,解决了一大麻烦。
在此页面申请30天试用版,我申请的是Linux+Fortran的Composer Edition。填完申请表之后邮箱会收到邮件,里面会给出激活码和下载链接。下载的时候最好选离线安装包,大概1.6G。
下载完成后解压,运行install_GUI.sh
,即有图形界面的安装程序。
选择Install as root,不过在这里要注意,安装程序需要填写root的密码,而Ubuntu的root密码原本是空的,即不允许root登录。因此在这里要先给root设置一下密码。执行sudo passwd root
即可修改root密码。
一路安装都很简单,中间要输入激活码。安装完成之后,修改~/.bashrc
,在最后加上(若为32位系统则需将intel64改成ia32)
source /opt/intel/compilers_and_libraries_2016.2.181/linux/bin/compilervars.sh intel64
重开终端,执行一下ifort,若出现ifort: command line error: no files specified; for help type "ifort -help"
则安装成功。
若30天到期,可以采取修改系统时间的方法继续使用ifort,只是需要注意一下可能会导致编译时make时间错乱的问题,建议先clean再make。
如果是虚拟机环境,则每次启动虚拟机都得改一下系统时间,因为虚拟机开机时会自动校准时间使其与宿主机相同。
MPICH安装准备
安装g++。为了后面的操作,再装个vim。(若不使用ifort则需安装gfortran)
执行sudo apt-get install g++ vim
即可。
需下载:
MPICH:下载页面 mpich-3.2.tar.gz
安装MPICH
我选择把MPICH安装在~/mpich
也就是/home/fz/mpich
。
解压mpich-3.2.tar.gz,位置随意,只要不是安装目录就行,之后进入解压后的目录,执行
./configure F77=ifort FC=ifort --prefix=/home/fz/mpich
make
sudo make install
注意:如果没装ifort,只用gfortran,第一句改成执行./configure --prefix=/home/fz/mpich
即可
接着,修改~/.bashrc
,在最后加上
export MPI_ROOT=/home/fz/mpich
export PATH=$MPI_ROOT/bin:$PATH
这样在每次启动终端时都会引入这些环境变量。注意:修改后需要重开终端!当然,执行一下source ~/.bashrc
更新一下bash配置也是可以的。
可以使用下面的方法测试一下MPICH是否安装成功。
新建hello.c:
#include "mpi.h"
#include <stdio.h>
#include <math.h>
int main (int argc, char **argv)
{
int myid, numprocs;
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &myid);
MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
MPI_Get_processor_name (processor_name, &namelen);
fprintf (stderr, "Hello World! Process %d of %d on %s\n", myid, numprocs, processor_name);
MPI_Finalize ();
return 0;
}
编译:mpicc -o hello hello.c
运行:mpirun -np 4 ./hello
(使用4个核模拟运行)
新版NetCDF安装准备
这是地球科学领域的一个库。在NetCDF 4.2版本之后,C与Fortran版本开始分离,以使两种语言版本的库独立发展。装Fortran版本前需装C版本,但是似乎在4.3.3之后也可以使用C的版本构建Fortran版本,只需在构建时加入相关参数。但是该方法还处于实验阶段,因此这里我们还使用传统方法来安装。
NetCDF:下载页面 netcdf-4.4.0.tar.gz 以及 netcdf-fortran-4.4.3.tar.gz
zlib:下载页面 zlib-1.2.8.tar.gz (NetCDF所需)
HDF5:下载页面 hdf5-1.8.16.tar.gz (NetCDF所需)
安装新版NetCDF
一开始我想像MPICH那样,把zlib、HDF5和NetCDF分别安装在/home/fz/zlib
,/home/fz/HDF5
和/home/fz/netcdf
,但是遇到了一些问题解决不了。
具体表现是在安装NetCDF-C时,提示找不到zlib,可能是某环境变量的问题。我用的是NetCDF官方文档的安装流程装的,应该不会出错才对。也有可能是官方文档漏掉了某个配置吧。
由于官方文档的不完整,出了问题不好解决,所以在这里我都让它们安装到了默认路径,即/usr/local
。
安装zlib
解压zlib-1.2.8.tar.gz并进入目录,执行:
./configure
make check
sudo make install
安装HDF5
解压hdf5-1.8.16.tar.gz并进入目录,执行:
./configure --with-zlib=/usr/local --prefix=/usr/local
make
make check
sudo make install
注意:这里为什么要手动指定安装路径,那是因为HDF5默认安装路径在源码根目录下的hdf5文件夹。而不是/usr/local
另外,为什么要多加个make语句,那是因为我之前在装的时候遇到了个问题,折腾半天才发现是HDF5官方的安装脚本有些小BUG。
即testh5dump.sh
在h5import
被编译前就使用了它导致找不到该文件。于是我进入h5import
目录先手动make一下,再make check就可以了。
为此我还邮件联系了开发者,他们给出的方法就是先make一下,当然像我这样手动编译一下h5import
也行。他们的回复如下:
> Hi,
>
> This looks like a dependency issue.
>
> If you build like this you should not encounter issues, because the
> tools will be built before the tests are run:
>
> ./configure ...
> make
> make check
> make install
>
> However, the way you are building should work, as well.
>
> We have had dependency issues in the past and fix them when they
> arise. I'll bring this up with the developers.
>
> Thanks!
> -Barbara
>--------------------------------------------------------------------------
> Hi.
>
> I talked to the developers about this. They are aware of this issue.
> We plan to fix the problem in the HDF5-1.10 software. (However, it will
> not be fixed in the HDF5-1.10.0 release which is due out at the end of
> this month.)
>
> So for HDF5-1.8 the only solution is to build the software first and then
> run the tests:
>
> ./configure
> make
> make check
>
> -Barbara
安装NetCDF-C
修改~/.bashrc
,在最后加上export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
,之后重开终端。
注:官方文档说最好加上这个环境变量,我之前没加,在装NetCDF-C的时候没问题,但是装NetCDF-Fortran的时候就报错了。应该是因为NetCDF-Fortran安装需要调用某些动态链接库文件。(文章最后会详细解释这个问题)
另:文档说使用sudo语句会导致这个环境变量失效,因此在make check
前不要使用sudo。但是我试了也没发现有什么问题。
解压netcdf-4.4.0.tar.gz并进入目录,执行:
sudo apt-get install m4
CPPFLAGS=-I/usr/local/include
LDFLAGS=-L/usr/local/lib
./configure
make check
sudo make install
安装NetCDF-Fortran
若中途关闭终端,需重新设置CPPFLAGS和LDFLAGS。
解压netcdf-fortran-4.4.3.tar.gz并进入目录,执行:
./configure
make check
sudo make install
安装旧版NetCDF
然而,悲伤的是那个程序并不能用新版NetCDF跑。于是我重装了个旧版。
netcdf-3.6.2:下载页面 netcdf-3.6.2.tar.gz
但是代码中有些问题,缺少头文件。(g++编译是这样,如果用icc的话可能会没问题吧,我这里没装Intel的C/C++编译器,所以没测试)
具体来说,要给cxx/ncvalues.cpp
、examples/CXX/sfc_pres_temp_rd.cpp
增加#include <cstring>
头文件。之后执行
./configure
make check
sudo make install
编译运行程序
环境配置到此结束。具体到我这个LETKF的程序,我遇到了下面的这些问题:
将使用bsub提交的脚本改写成直接使用mpiexec的,这里有个bsub的完整文档,可以参考。
报错forrtl: severe (174): SIGSEGV, segmentation fault occurred
。
一般是栈空间不足的问题,编译时加上-heap-arrays 64
参数即可,表示在编译时,把所有在栈中定义的、大小超过64KB的数组分配到堆中。
而在集群环境中一般不会遇到这个问题,因为集群一般不限制栈空间的大小。可以用ulimit -s
命令查询,单位为KB,集群环境一般是unlimited。
在编译中的一些问题,可以参考我的这篇文章关于程序编译时头文件、链接库文件目录的一些问题。
对于在集群上提交作业的相关事项,可以参考我的这篇文章PBS作业管理下集群环境的相关使用方法。
其他一些需要注意的问题
- 在编译mpi的Fortran程序时,一定要使用
mpifort
(也有可能是mpiifort
,得看具体的MPI环境),直接用ifort
进行编译会出现找不到mpi
库函数的情况,即使你已经指定了使用mpi
动态链接库。
感谢
http://www.cnblogs.com/liyanwei/archive/2010/04/26/1721142.html
http://www.mpich.org/static/downloads/3.2/mpich-3.2-installguide.pdf
http://www.unidata.ucar.edu/software/netcdf/docs/getting_and_building_netcdf.html#building
http://www.unidata.ucar.edu/software/netcdf/docs/building_netcdf_fortran.html