Notices in deploying Intel MKL and MPI in VS environment

“遇到一些bug,尤其像Fortran这种老旧的语言,多半会让人像斯金纳的鸽子,迷信式祈祷自己不要遇到这些问题。但现实永远是墨菲定律,所以你需要熟悉这些基本操作1。”

问题描述

在Visual Studio(VS)上配置Intel Visual Fortran并调用MKL这种计算库,实际上会遇到一些莫名其妙的问题,这里主要记录一些踩坑的经历。

oneAPI or Intel Parallel Studio XE in VS

目前主流的Fortran编译环境是Intel旗下的Intel Visual Fortran,主要集成在parallel studio或者现在的oneAPI中,这里基础套件的安装过程就不再详述,具体参看官网的介绍。问题集中在VS 的配置上,所以以下详细介绍整个配置过程。

编译环境

安装完oneAPI的基础套件或者旧版本的Parallel Studio之后,Fortran的编译环境会自动集成到VS上,就能在VS界面的菜单栏新建项目里找到相应的开发选项。


红框中显示了IDE界面下的Fortran的开发选项

集成开发环境可以很方便把Fortran的编写纳入VS的工作流。

MKL和MPI的配置

像Fortran这类面向过程的编译型语言,其编译实现需要编译器将写好的目标代码转换为中间代码,链接器将此中间代码与其他代码相结合生成可执行文件(.exe后缀,即二进制机器码)。编译部分是编译器对源代码的检查和转换,而链接过程就是把转换之后的源代码和系统的标准启动代码以及库代码结合在一起,形成最终的可执行文件。


在win系统平台,Fortran的文件目录下编译过程会涉及图中几种后缀的文件生成。
注意到,除了一些可执行文件的修饰文件和日志文件,上图展示的是一个叫Console4的项目编译生成了.obj、.mod、.exe这三种后缀的文件。.exe是可执行文件,.mod即module模块文件,.obj是object的缩写,即工程文件,也就是刚才提到的中间文件,它是链接器操作的对象。

作为对比,在超算集群Linux平台下的编译文件和win平台略微有所区别。

和win平台有所区别的是,Linux下工程文件从.obj后缀变成了.o后缀,可执行文件没有后缀名(图中绿色显示)。

项目配置

在经过第一节的新建开发项目之后,我们需要对新建的项目做相应的配置。


在VS界面可以找到解决方案一栏,这里有详细的项目文件层级,只需要选定任意项目名称右键即可在属性选项下找到项目配置的页面。
可选择地,

菜单栏项目下亦可找到该项目属性选项。

属性页面的设置

属性页面是一系列涉及项目源码编译的选项,也是VS作为一个著名的集成开发平台在项目管理上的便易性体现,如果单纯通过命令行展开项目开发,将会是一个相当繁杂而艰难的任务。经过一定的项目配置,可以傻瓜式地实现一个大型项目的开发和编译过程。


项目编译的若干选项设置。
可以看到项目属性页左侧集成了Fortran编译和调试的各种选项设置。其中General是编译输出位置和输出名设置等基本编译操作,而debuging一项则是调试的基本设置。我们重点关注的是Fortran编译器和Linker链接器的设置,尤其关于第三方库的配置。

配置选项和平台。

而属性页面上方是平台配置,出现了Debug和Release以及平台架构的选择,这也是初学者很容易在IDE设置上混淆的地方。

Debug和Release

“Debug”,顾名思义,调试,是编译过程重要的步骤,而“Release”即发布,是调试结束后的事。之所以配置选项专门给了debug和release这两种设置,也是意在把调试任务和程序最终的发布区分开。因此,如果配置器选择了Debug,整个编译过程会额外地记录编译的细节,以便调试程序的运行。换句话说,Debug的配置器会把调试放在第一位,包括我们可能需要的单步断定调试或异步调试,这些都依赖Debug配置下的设置。而Release配置器则倾向于程序稳定运行和移植,所以会裁除调试信息,降低程序冗余,以便开发者发布最终的成品。


Debug的生成文件大小在同样配置下要远大于Release。

编译器的选项设置

Fortran选项一栏:
在Fortran选项下有以下需要注意的地方。对于General一项,主要涉及一些调试优化,对于不同配置器,这些优化选项有必要区分。我们需要关注的是下图箭头指向的两项,对于Release配置器,大可不必做调试,优化也可选择速度最优,以节省计算机编译和执行的时间。


Fortran选项下General一项需要注意箭头指向的设置。
对于Libaries一项,则需要注意另外两个地方。运行时库的选择如果如图所示,可以大大降低程序的体积,因为这里选择的库文件类型是动态库类型,在Linux系统下Fortran编译和链接第三方库一文中,我简单提到过这个特点,对于调用动态库,无需将所需要的库文件集成到可执行文件中。从而可以降低可执行文件的体积。 另外需要注意的是,Intel的数学核心库调用要选择为并行版本。

Fortran选项下Liberies一项需要注意箭头指向的设置。

Linker选项一栏:
Linker链接器选项设置仍然需要注意两个地方,第一就是input选项下附加依赖项要键入mkl_lapack95_ilp64.lib impi.lib。这里要稍加解释,因为网上一部分方案都是以讹传讹的设置,盲目地参考这些教程键入奇怪的库文件名会导致难以排查的编译错误。这里我仅仅需要这两项就可以完成MKL和MPI库的调用,而我需要lapack95计算包的函数以及实现并行计算的任务。


Linker选项下Input一项需要注意箭头指向的设置。

另外,在system选项下,同样是第一项需要选择“console”


子系统需要选择console,以匹配系统程序启动入口。
不然会出现没有定义程序入口点的错误。

这个错误相当低级,但是对于初学者是致命的,因为很难检索到解决方案。

区分编译平台

这里涉及32位平台和64位平台的选择问题,稍懂计算机的都知道这里“位”是信息的单位,CPU在早期有32位架构,一部分早期的计算机语言在编译处理上就遗留了寄存器信息处理位宽的历史问题。所以对于Fortran而言,一部分早期可靠的源代码依赖32位平台的处理,而后来源码的编译都是在更先进信息吞吐量更大的64位架构的计算机上完成的,同样也遗留了编译平台的问题。这些底层的代码决定了有些运行库对编译平台有特别的要求,比如IntelMPI的库文件就只能在64位平台下编译运行,不清楚这些问题,错选32位平台,会出现难以排查的编译问题。


可以通过箭头所指设置不同配置器的架构,一般是win32和x64。

VS上的一些重要设置

说了这么多项目配置,实质上一开始我们还需要熟悉VS基本的设置,它涉及Fortran第三方库调用的环境配置。


在菜单栏“工具”下找到选项,在Intel编译工具下可以找到编译器设置,这里我们需要设置头文件地址和库文件地址,对应箭头所示

Intel套件安装位置可以找到头文件地址和库文件地址。图示是MKL的头文件和库文件地址,其他第三方库的设置与此类似。

在我们设置好这些环境变量之后,便可以直接在上节项目配置中直接指定库文件名就可以实现对应库文件和头文件的调用


MKL的lapack95库文件和对应地址。

MPI的impi.lib。值得注意的是,这里仍然有Debug版本和Release版本的库文件。

参考

[1]. 海量的试错


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!