完成CESM的代码获取之后,要想能够运行起来,还需要将其进行“本地化”,也就是进行配置。因此,完成移植的下一步就是修改模式配置。
CESM中的配置文件格式为xml,xml为可扩展标记语言,如图所示
CESM2.1.3的配置中,个人理解包括全局配置与个性化配置,前者控制CESM整个模型以及后续产生的所有case的配置,后者则只在对应的case中发挥作用。本博文主要介绍全局配置修改的方法。
其中全局配置文件为三个xml文件,分别定义了机器类型、编译器信息、作业系统信息。其通常位于CESM目录下,具体路径为$CESMROOT/cesm2.1.3/cime/config/cesm/machines/。
笔者在学习过程中在这三个文件上花费了不少功夫,由于大家所使用的机器、编译器、作业系统种类、版本不尽相同,修改时无法照本宣科,因此推荐在这部分学习过程中,采取以下方法:
(1)结合官方文档与他人的xml配置文件,理解每一项配置的含义与修改方法
(2)进行case运行尝试,通过报错来debug
方法看起来很简单是吧,可是在打开这几个文件的时候,眼睛里不由得透出清澈的愚蠢~
为什么有这么多模块?为什么找不到我使用的机器?我咋知道我这是啥机器?应该从何下手?
一、config_machines.xml
使用vim编译器查看该文件时,整体来看、不难看出,xml文件中通过<>与缩进来控制从属关系。该文件中,第一层配置定义为CESM模型版本,第二层配置定义则为machine名称,并且默认文件中给出了多种并列的machine,可以在CESM官方网站中找到各版本支持的机器类型,也就是说,你只需要修改其中的一个就可以。
(1)首先,你需要知道自己用的是啥机器,在自己终端输入 hostname即可得到你的机器名称。然后,使用搜索命令查看默认文件中是否已经有了你的机器,有的话,去改对应的模块就行了。如果没有的话,可以随机挑选一个幸运观众、或者增加一个machine模块,将<machine MACH="aleph">引号中改为自己的机器名就可以啦。
题外话:CESM是怎么知道你用的啥机器的呢?主要是通过生成case时的命令来传输信息的,下次再讲~
(2)选好machine模块,就可以进行修改了。
<machine MACH="admin1">
<DESC>
Example port to centos7 linux system with gcc, netcdf, pnetcdf and mpich
using modules from http://www.admin-magazine.com/HPC/Articles/Environment-Modules
</DESC>
<NODENAME_REGEX>admin1</NODENAME_REGEX>
<OS>Linux</OS>
<PROXY> https://howto.get.out </PROXY>
<COMPILERS>intel</COMPILERS>
<MPILIBS>impi</MPILIBS>
<SAVE_TIMING_DIR> </SAVE_TIMING_DIR>
<CIME_OUTPUT_ROOT>/public/work/xxx/5.OUTPUT/CESM</CIME_OUTPUT_ROOT>
<DIN_LOC_ROOT>/public/work/xxx/2.INPUT/CESM</DIN_LOC_ROOT>
<DIN_LOC_ROOT_CLMFORC>/public/work/xxx/2.INPUT/CESM/lmwg</DIN_LOC_ROOT_CLMFORC>
<DOUT_S_ROOT>/public/work/xxx/5.OUTPUT/archive/$CASE</DOUT_S_ROOT>
<BASELINE_ROOT>/public/work/xxx/5.OUTPUT/CESM/cesm_baselines</BASELINE_ROOT>
<CCSM_CPRNC>/public/home/xxx/1.Model/cesm2.1.3/cime/tools/cprnc</CCSM_CPRNC>
<GMAKE>make</GMAKE>
<GMAKE_J>8</GMAKE_J>
<BATCH_SYSTEM>pbs</BATCH_SYSTEM>
<SUPPORTED_BY>me@my.address</SUPPORTED_BY>
<MAX_TASKS_PER_NODE>40</MAX_TASKS_PER_NODE>
<MAX_MPITASKS_PER_NODE>40</MAX_MPITASKS_PER_NODE>
<PROJECT_REQUIRED>FALSE</PROJECT_REQUIRED>
<mpirun mpilib="impi">
<executable>mpirun</executable>
<arguments>
<arg name="ntasks">-np {{ total_tasks }}</arg>
</arguments>
</mpirun>
<module_system type="none"/>
<!---<module_system type="module">
<init_path lang="perl">/usr/share/Modules/init/perl.pm</init_path>
<init_path lang="python">/usr/share/Modules/init/python.py</init_path>
<init_path lang="csh">/usr/share/Modules/init/csh</init_path>
<init_path lang="sh">/usr/share/Modules/init/sh</init_path>
<cmd_path lang="perl">/usr/bin/modulecmd perl</cmd_path>
<cmd_path lang="python">/usr/bin/modulecmd python</cmd_path>
<cmd_path lang="sh">module</cmd_path>
<cmd_path lang="csh">module</cmd_path>
<modules>
<command name="purge"/>
</modules>
<modules compiler="intel">
<command name="load">intel/17.0.5</command>
<command name="load">mkl</command>
</modules>
</module_system>-->
<environment_variables>
<env name="OMP_STACKSIZE">1024M</env>
<env name="NETCDF_HOME">/public/home/xxx/0.library/intel/mytool</env>
<env name="NETCDF_PATH">/public/home/xxx/0.library/intel/mytool</env>
<env name="MPI_PATH">/public/software/mpi/intelmpi/2017.5.239/intel64</env>
<!--env name="PNETCDF_PATH">/public/home/wangyuexuanzi/libraries/icc</env>
<env name="PNETCDF_HOME">/public/home/xxx/libraries/icc</env-->
</environment_variables>
<resource_limits>
<resource name="RLIMIT_STACK">-1</resource>
</resource_limits>
</machine>
说明:1. 编译器以及batch system与另外两个config文件一致
2. mpi的选择和使用,根据自己的安装情况而定,如果使用intel编译器,推荐使用impi;如果使用gnu编译器,推荐使用mpich。可参考其他博文
MPI(OpenMPI和MPICH(IntelMPI、MVAPICH))和OpenMP_weixin_44004788的博客-CSDN博客_mpich网路通信协议
3. 注释掉的modules部分,当所使用服务器上有合适的modules时可使用,我学习的时候不是很懂,因此没有用,可以参考一些其他博文。
(1条消息) Linux下Moudle工具的介绍与使用_程序员小乐的博客-CSDN博客
4. pnetcdf在CESM运行中可装可不装,这里的路径也是可写可不行,如果你自信装的没问题,就写。我在运行测试case的时候出现了相关报错,因此干脆就没有用pnetcdf。如果测试case出错可以注释掉pentcdf试一下。
二、config_compilers.xml
与上一config文件相似,该文件同样给出了多个平行的编译器。一般使用的编译器就是gnu、intel,因此直接修改对应的模块即可~
<compiler COMPILER="intel">
<CFLAGS>
<base> -qno-opt-dynamic-align -fp-model precise -std=gnu99 </base>
<append compile_threaded="true"> -qopenmp </append>
<append DEBUG="FALSE"> -O2 -debug minimal </append>
<append DEBUG="TRUE"> -O0 -g </append>
</CFLAGS>
<CPPDEFS>
<!-- http://software.intel.com/en-us/articles/intel-composer-xe/ -->
<append> -DFORTRANUNDERSCORE -DCPRINTEL</append>
</CPPDEFS>
<CXX_LDFLAGS>
<base> -cxxlib </base>
</CXX_LDFLAGS>
<CXX_LINKER>FORTRAN</CXX_LINKER>
<FC_AUTO_R8>
<base> -r8 </base>
</FC_AUTO_R8>
<FFLAGS>
<base> -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source </base>
<append compile_threaded="true"> -qopenmp </append>
<append DEBUG="TRUE"> -O0 -g -check uninit -check bounds -check pointers -fpe0 -check noarg_temp_created </append>
<append DEBUG="FALSE"> -O2 -debug minimal </append>
</FFLAGS>
<FFLAGS_NOOPT>
<base> -O0 </base>
<append compile_threaded="true"> -qopenmp </append>
</FFLAGS_NOOPT>
<FIXEDFLAGS>
<base> -fixed -132 </base>
</FIXEDFLAGS>
<FREEFLAGS>
<base> -free </base>
</FREEFLAGS>
<LDFLAGS>
<append compile_threaded="true"> -qopenmp </append>
</LDFLAGS>
<MPICC> mpiicc </MPICC>
<MPICXX> mpiicpc </MPICXX>
<MPIFC> mpiifort </MPIFC>
<SCC> icc </SCC>
<SCXX> icpc </SCXX>
<SFC> ifort </SFC>
<SLIBS>
<base>-L$ENV{NETCDF_PATH}/lib -lnetcdff -lnetcdf -lhdf5_hl -lhdf5 -ldl -lm -lz -lcurl</base>
<append MPILIB="mpich"> -mkl=cluster </append>
<append MPILIB="mpich2"> -mkl=cluster </append>
<append MPILIB="mvapich"> -mkl=cluster </append>
<append MPILIB="mvapich2"> -mkl=cluster </append>
<append MPILIB="mpt"> -mkl=cluster </append>
<append MPILIB="openmpi"> -mkl=cluster </append>
<append MPILIB="impi"> -mkl=cluster </append>
<!--append MPILIB="mpi-serial"> -mkl </append-->
</SLIBS>
<SUPPORTS_CXX>TRUE</SUPPORTS_CXX>
</compiler>
这一块要改的并不多,主要改一下mpicc,mpicxx那几个就行。
三、config_batch.xml
这个更简单,就不多说了~但是需要比较了解自己的作业系统
<batch_system type="pbs" >
<batch_query args="-f" >qstat</batch_query>
<batch_submit>qsub </batch_submit>
<batch_cancel>qdel</batch_cancel>
<batch_env>-v</batch_env>
<batch_directive>#PBS</batch_directive>
<jobid_pattern>^(\S+)$</jobid_pattern>
<depend_string> -W depend=afterok:jobid</depend_string>
<depend_allow_string> -W depend=afterany:jobid</depend_allow_string>
<depend_separator>:</depend_separator>
<walltime_format>%H:%M:%S</walltime_format>
<batch_mail_flag>-M</batch_mail_flag>
<batch_mail_type_flag>-m</batch_mail_type_flag>
<batch_mail_type>, bea, b, e, a</batch_mail_type>
<submit_args>
<arg flag="-q" name="$JOB_QUEUE"/>
<arg flag="-l walltime=" name="$JOB_WALLCLOCK_TIME"/>
<arg flag="-A" name="$PROJECT"/>
</submit_args>
<directives>
<directive>-N {{ job_id }}</directive>
<directive default="n">-r {{ rerunnable }}</directive>
<!-- <directive> -j oe {{ job_id }} </directive> -->
<directive>-j oe</directive>
<directive>-V</directive>
<directive>-l nodes=1:ppn=40</directive>
</directives>
<queues>
<queue nodemin="1" nodemax="20" default="true">normal</queue>
</queues>
</batch_system>
下面就可以开始,通过测试case运行来debug了~下一篇讲case运行的工作流!
有什么错漏请多多指教!