Ipopt在windows下的编译

原创
2021/10/03 14:28
阅读数 637

最近做一个最优化的东西,涉及到内点法非线性优化的开源库Ipopt。在linux下用起来非常简单,但要在windows下用,还颇费了一番功夫。在此简要记录一下,算是给做过的东西留个印记,也方便有需要的人。

 

Ipopt是一个大规模高性能非线性约束优化开源库,采用了内点法。简单来说就是选定初始点为可行集中的点,在约束边界处利用人为添加的对数项,确保求解过程不会超出边界,从而利用无约束优化的算法求解非线性约束条件下的最优化问题。其官网地址如下:

https://coin-or.github.io/Ipopt/

一些最优化的概念可参考如下网址的说明:

https://zhuanlan.zhihu.com/p/412395207

 

Ipopt至少有两个依赖:一个是blas库,我选的openblas;另一个是求解器,找了一番之后,还是决定用推荐的HSL。前者很有名了,就不多说,HSL是某个大学搞的一整套求解器,包含了各种各样的算法。其官网如下:

https://www.hsl.rl.ac.uk/

但为了和Ipopt整合,更方便的是下载下面地址的算法包。不过下载还需要申请,好在立马就能发邮件给出下载链接。

https://www.hsl.rl.ac.uk/ipopt/

 

除此以外,为了成功编译Ipopt,还需要一套类Unix环境,官方建议是msys2。很久以前用过msys和mingw,不过后来都在linux下,也就没继续跟进。现在发现msys2很方便了,可以利用arch linux下的工具pacman来实现类似apt-get的功能,安装软件非常方便快捷,确实很好用。而且该软件是绿色软件,虽然有安装包,但装完之后直接复制到其他机器上也能用。

 

安装msys2之后,运行msys2.exe(或者msys2_shell.cmd),执行如下指令即可安装相关工具,用于编译Ipopt。

pacman -S binutils diffutils make patch pkg-config mingw-w64-x86_64-gcc-fortran

由于我已经安装了git,故未在上面的语句中增加git,否则也可增加git。官网上还有grep,但实际上msys2已经自带了grep。注意此处仅安装了64位的mingw gfortran,因此只能编译64位的库,将来的VS程序也只能是64位的。另外,要在路径中找到gfortran,需要运行mingw64.exe而非msys2.exe。最后,为了找到微软的编译器及相关工具,以方便后面优先使用微软编译器的选项,需要打开VS命令行工具,在里面找到msys2_shell.cmd,执行如下指令。

msys2_shell.cmd -use-full-path
/mingw64.exe

第一句继承当前环境变量(也就是VS命令行工具cmd环境下的环境变量)并打开msys2,第二句运行mingw64.exe,即打开包含mingw64工具的shell。

 

接下来编译openblas。openblas有很多种编译方法,比如利用cmake生成VS解决方案。但既然有了类Unix环境,自然直接用最简单的方法,直接执行make/make install即可。

cd OpenBLAS
make
make PREFIX=/path/to/install install

此处/path/to/install代表想把openblas库安装到什么路径。

 

本来可以直接编译HSL,但貌似直接编译会出问题,需要利用Ipopt提供的第三方库编译工具,才能顺利。不过HSL是运行时依赖,貌似编译的时候不需要。为了完整性,还是先编译吧。在如下地址下载Ipopt提供的第三方编译环境。

https://github.com/coin-or-tools/ThirdParty-HSL

下载后将先前下载的HSL库包解压缩放入该文件夹,并改名为coinhsl,然后执行如下命令进行编译。

cd ThirdParty-HSL-stable-2.2
./configure --prefix=/path/to/install  --with-lapack-lflags="-L/path/of/openblas -lopenblas" --enable-msvc
make
make install

此处/path/to/install和前面一样,表示想把编译好的库安装到哪里,而/path/of/openblas则代表之前把openblas安装到哪里的路径。我的这两个路径是同一个,是某个目录下的FinalLib文件夹。

 

最后编译Ipopt,执行如下指令。

cd Ipopt-master
mkdir build
cd build
../configure --prefix=/path/to/install --with-lapack-lflags="-L/path/of/openblas -lopenblas" --enable-msvc
make
make install

 

我把所有编译好的库都放到FinalLib文件夹中,接下来就可以引用Ipopt库来写自己的代码了。新建VS工程,先把工程改成x64架构,然后在VC++ include附加包含目录中添加FinalLib/include/coin-or,在附加库目录中添加FinalLib/lib,输入库文件中添加libipopt.dll.a,这样即可成功编译。

 

但运行时会报一堆错,主要是找不到各种动态库dll。此时需要在VS工程属性的调试一栏中增加环境变量PATH=/path/to/msys2/mingw64/bin;%PATH%,这样即可找到运行时需要的动态库。

 

如果采用intel Parallel Studio XE套装,该过程将更加简单,因为intel MKL自带了blas和线性求解器Pardiso。所以不需要OpenBLAS和HSL,直接编译Ipopt即可。

 

值得注意的是,如果采用以上编译语句,编译出来的库是release版本,如果VS开发时选择debug,有可能会出现奇怪的运行时错误,换成release就好了。这块主要和 Ipopt 对计算中用到的 options 的设置有关,不过具体原因也没去深究。如果需要debug版本,configure时需要加上--enable-debug 项。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部