windows下利用Mingw和msmpi编译运行mpi并行程序_hu_shidong的博客-程序员宅基地

技术标签: 科学计算  编译器  mingw  msmpi  mpi  windows  

windows下利用Mingw和msmpi编译运行mpi并行程序

目前windows下mpi实现版本已经由微软负责,软件名为msmpi。而原来mpi标准团队的windows下的mpich2实现已经很久没有更新了,当然使用以前下载的mpich2来构建mpi并行程序是没有问题的,但如果要使用mpi-3的一些新特性,那么就需要使用微软提供的msmpi。msmpi可以与intel,pgi编译器配合使用,但这些编译器都不是开源的,那么能否使用开源的gnu编译器呢?答案自然是可以的。

构建mpi并行程序主要是两种语言c/c++和fortran。其中c/c++程序的构建要简单很多,fortran则比较复杂。windows系统也分32位和64位系统,两种环境也存在差别,先将一一介绍。

软件准备

mingw

mingw的gcc编译系统是一整套的编译器,包含gcc,g++,gfortran等分别编译c,c++,fortran程序。

下载一套mingw,地址:mingw。不用安装,直接解压到某个位置,把mingw下的bin目录加入环境变量。

msmpi

msmpi是微软提供的mpi实现。介绍?

下载msmpi,地址:msmpi

安装两个文件后,打开cmd窗口,输入set MSMPI可以看到安装路径,如果有如下输出,表示已经安装成功。

32位系统下:

MSMPI_BIN=C:\Program Files\Microsoft MPI\Bin\
MSMPI_INC=C:\Program Files\Microsoft SDKs\MPI\Include\
MSMPI_LIB32=C:\Program Files\Microsoft SDKs\MPI\Lib\x86\
MSMPI_LIB64=C:\Program Files\Microsoft SDKs\MPI\Lib\x64\

64位系统下:

MSMPI_BIN=C:\Program Files\Microsoft MPI\Bin\
MSMPI_INC=C:\Program Files (x86)\Microsoft SDKs\MPI\Include\
MSMPI_LIB32=C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\
MSMPI_LIB64=C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64\

简单并行程序代码

最终要实现对代码的编译,因此需要准备简单的测试程序代码,分c,c++,fortran代码如下:

hello.c

#include "stdint.h" //重点是这一句
#include "mpi.h"

#include <stdio.h>
#include <math.h>

void main(argc,argv)
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();
}

hello.cpp

#include "stdint.h" //重点是这一句
#include "mpi.h" //

#include <iostream>

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);
    std::cout<<"Hello World! Process"<<myid<<"of"<<numprocs<<" on "<<processor_name<<std::endl;
    MPI_Finalize();
    return 0;
}

hello.f90

program hello_parallel

use mpi
!implicit none
!include 'mpif.h'

integer::procs,rank,ierr
character(MPI_MAX_PROCESSOR_NAME)::host
integer::hostlen
call MPI_INIT(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,procs,ierr) 
call MPI_COMM_RANK(MPI_COMM_WORLD,rank,ierr)
call MPI_GET_PROCESSOR_NAME(host,hostlen,ierr)

print '(a,i3,a,i4,a,a)','hello mpi&fortran from rank',rank,' of  ',procs,' processes on ',trim(host)

call MPI_FINALIZE(ierr)
end program

windows环境

测试环境包括32位和64位windows7系统,可以直接安装在电脑上或者在虚拟机中。

32位windows 7系统的c/c++语言mpi并行程序

在安装完成软件并准备好程序代码之后,我们开始进行测试,注意到一般情况下,c和c++的mpi程序代码中会仅包含mpi.h头文件用于处理MPI函数。如果是这样的话,直接进行编译,那么会提示错误:

error: '__int64'
does not name a type; did you mean '__divtc3'?
typedef __int64 MPI_Aint;

这是因为__int64未定义,这个问题有两种方法解决:

  1. 是修改mpi.h文件找到__int64定义语句前面,加入#include “stdint.h”
  2. 是不修改mpi.h文件,而如上面的程序代码一般,直接在源代码中mpi.h前面加入stdint.h

解决了这个问题以后,那么就可以正常的进行编译和运行了。

c程序的编译命令和运行命令为:

gcc -o hello.exe hello.c -l msmpi -L "C:\Program Files\Microsoft SDKs\MPI\Lib\x86" -I "C:\Program Files\Microsoft SDKs\MPI\Include"

mpiexec -n hello.exe 3

结果为:

Hello World! Process 0 of 3 on PC-20171009XBQH
Hello World! Process 1 of 3 on PC-20171009XBQH
Hello World! Process 2 of 3 on PC-20171009XBQH

c++程序的编译和运行命令类似:

g++ -o hello.exe hello.cpp -l msmpi -L "C:\Program Files\Microsoft SDKs\MPI\Lib\x86" -I "C:\Program Files\Microsoft SDKs\MPI\Include"

mpiexec -n hello.exe 3

结果为:

Hello World! Process 0 of 3 on PC-20171009XBQH
Hello World! Process 1 of 3 on PC-20171009XBQH
Hello World! Process 2 of 3 on PC-20171009XBQH

32位windows 7系统的fotran语言mpi并行程序

fortran程序的编译要复杂很多,根据miroi的研究表明,不能直接进行编译,源代码中包含的文件也不是mpif.h,而需要使用mpi模块,该模块需要手动编译。并且因此,需要利用dlltool工具重新生成一个静态链接库,而不是使用原来的msmpi.lib。步骤如下:

  1. 编译生成mpi模块

复制msmpi库目录下的mpi.f90文件到存放源代码的当前目录下改名为mpi.F90,复制库目录下x86目录的mpifptr.h到当前目录下,进入命令行,采用如下命令编译:

gfortran -c -D INT_PTR_KIND()=8 -fno-range-check mpi.F90

其中INT_PTR_KIND()=8是因为fortran中没有INT_PTR_KIND()定义,所以这里直接指定,还有用-fno-range-check消除长整数的问题。

编译得到mpi.mod,mpi_base.mod,mpi_constants.mod,mpi_sizeofs.mod等文件,fortran源代码中只要价值mpi模块即可。

  1. 重新生成静态链接库

复制系统32位库目录下的msmpi.dll到当前目录下,利用gendef工具得到其中的函数信息:

gendef msmpi.dll

得到msmpi.def,接着利用dlltool工具生成一个libmsmpi.a的链接库,dlltool工具mingw套件里面有提供,命令为:

dlltool -d msmpi.def -l libmsmpi.a -D msmpi.dll

得到libmsmpi.a文件。

  1. 编译fortran源代码并运行

现在所有的准备都已经完成,利用gfotran和生成的链接库进行编译:

gfortran -o hello.exe hello.f90 libmsmpi.a -D INT_PTR_KIND()=8 -fno-range-check

运行使用mpiexec命令:

mpiexec -n hello.exe 3

结果为:

hello mpi&fortran from rank  1 of     3 processes on PC-20171009XBQH
hello mpi&fortran from rank  2 of     3 processes on PC-20171009XBQH
hello mpi&fortran from rank  0 of     3 processes on PC-20171009XBQH

64位windows 7系统的c/c++语言mpi并行程序

64位系统下的c/c++程序编译与32位下类似,只是需要把库文件的路径修改一下,因此编译命令为:

c程序的编译命令和运行命令为:

gcc -o hello.exe hello.c -l msmpi -L "C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64" -I "C:\Program Files (x86)\Microsoft SDKs\MPI\Include"

mpiexec -n hello.exe 3

结果为:

Hello World! Process 0 of 3 on PC-20171009XBQH
Hello World! Process 1 of 3 on PC-20171009XBQH
Hello World! Process 2 of 3 on PC-20171009XBQH

c++程序的编译和运行命令类似:

g++ -o hello.exe hello.cpp -l msmpi -L "C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x64" -I "C:\Program Files (x86)\Microsoft SDKs\MPI\Include"

mpiexec -n hello.exe 3

64位windows 7系统的fotran语言mpi并行程序

64位系统下的fotran程序编译与32位下类似,只是需要编译mpi模块和libmsmpi.a库时用的需要是x64目录下的文件,即:

  1. 编译生成mpi模块时,复制库目录下x64目录的mpifptr.h,即C:\Program Files (x86)\Microsoft SDKs\MPI\Include\x64\mpifptr.h

  2. 重新生成静态链接库时,复制64位库目录下的msmpi.dll,即C:\Windows\SysWOW64\msmpi.dll

  3. 编译fortran源代码并运行完全相同。

小结

通过上述步骤,实现了windows32位和64位系统下,利用msmpi和mingw的gcc编译器构建mpi并行程序。对于c/c++程序只要注意头文件就可以直接编译运行。对于fortran程序则需要重新编译mpi模块和链接库,然后利用生成的模块和链接库进行编译。

ps

注意上述测试的软件版本为msmpi8.1,mingw 6.3.0。还要注意因为64位环境和32位环境本身是隔离的,因此不需要像miroi那样在代码中加入区分64位和32位的预编译命令,编译也不需要使用_WIN64选项了。

参考文献

  1. TUTORIAL: Adapting MS-MPI for MinGW64 #85
  2. Linking MS-MPI with MinGW (gfortran)
  3. MinGW coding under Windows (C, C++, OpenMP, MPI)
  4. How to Configure MSMPI for the MinGW-w64 Cross-Compiler
  5. Microsoft MPI
  6. How to compile and run a simple MS-MPI program
  7. MPI在windows上的扯淡
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xenonhu/article/details/78196443

智能推荐

unity3d 求两个点长度_开源项目OEIP 游戏引擎与音视频多媒体(UE4/Unity3D)_weixin_39684995的博客-程序员宅基地

现开源一个项目 oeip​github.com项目实现的功能Demo展示UE4/Unity3D 互相推拉流https://www.zhihu.com/video/1204753418495311872这个项目演示了在UE4中,接入摄像机通过OEIP直接输出到UE4纹理上,并直接把UE4里的RenderTarget当做输入源通过OEIP里GPU管线处理后推流出去,而另一边Unity3D也是把Rend...

Android之init.rc文件语法介绍_Helloooooworldddddd的博客-程序员宅基地_rc文件语法

init.rc由许多的Action和Service组成。每一个语句占据一行,并且各个关键字被空格分开.由 # (前面允许有空格)开始的行都是注释行(comment)一个actions 或 services 的开始隐含声明了一个新的段,所有commands 或 options 属于最近的声明。在第一个段之前的 commands 或 options 都会被忽略每一个actions 和 se

【c#】object to string 转换的注意事项及string的空和null判断_鐵血柔情��的博客-程序员宅基地_c# object tostring

c# object to string 转换的注意事项及string的空和null判断1、object to string2、string的null和empty判断3、string的保险处理1、object to string1.1 使用.ToString()使用.ToString()是非常简单方便的。但如果是null的话无法对null进行处理。会报NullPoint异常1.2 使用...

Commons pool 数据库连接池实现 _pterodactyl2007的博客-程序员宅基地

  Commons pool 数据库连接池实现 收藏 1,首先我们要实现一个工厂类,用于处理验证,创建对象等方法。view plaincopy to clipboardprint?package net.chinacsharp.jdf.pool.connectionpool;     import java.sql.Connection;   import java.sql.DriverMan...

转载 单点登录(1)_whaohaoxuexi02的博客-程序员宅基地

原文:http://soft-app.iteye.com/blog/928295 近来搞了一下单点登录。我们弄的单点登录估计是最简单的。【概要原理】:假设有2个应用站点A和B,都需要登录才可以访问,另外有一个专门负责登录的站点SSO。现在有个用户访问站点A,站点A会先检查该用户是否已经登录,如果已经登录,则返回相应页面;否则转向SSO进行登录,登录成功后,转回站点A,返回请...

随便推点

centos7安装docker_杨杨小朋友的博客-程序员宅基地

简单版:1.执行命令curl -sSL https://get.daocloud.io/docker | sh前提:a.虚拟机可以上网b.Centos为64位c.要用root用户2.看docker版本 docker -v3.从HelloWorld开始a.service docker startb.docker run hello-world出现HelloWorld就说明成功啦~带具体结果的版本:1.执行命令DaoCloud的安装本(是好的,哈哈):curl -sSL htt

.Net中把图片等文件放入DLL中,并在程序中引用_ObjectOriented的博客-程序员宅基地

有时我们需要隐藏程序中的一些资源,比如游戏,过关后才能看到图片,那么图片就必须隐藏起来,否则不用玩这个游戏就可以看到你的图片了,呵呵。 本文就讲述了如何把文件(比如图片,WORD文档等等) 隐藏到DLL中,然后在程序中可以自己根据需要导出图片进行处理。第1步:我们要生成一个资源文件,先把要隐藏的文件放入到这个资源文件中(资源文件大致可以存放三种数据资源:字节数组、各种对象和字符串)首先创建

TypeScript:弱类型_风静如云的博客-程序员宅基地_typescript弱引用

类型系统按照“是否允许隐式类型转换”来分类,可以分为强类型和弱类型。强类型strongly typed:偏向于不容忍隐式类型转换,比如Pyhon中无法完成整数与字符的相加运算:&gt;&gt;&gt; 1+"2"Traceback (most recent call last):File "&lt;stdin&gt;", line 1, in &lt;module&gt;TypeError: unsupported operand type(s) for +: 'int' and 'str'

JDBC,使用DBUtils工具类完成增删改、查【通用的】_jay编程的博客-程序员宅基地

标题:JDBC,使用DBUtils工具类完成增删改、查***通用的***与上一篇【https://blog.csdn.net/weixin_45986454/article/details/106407741】的区别在于增加了泛型,注:测试DBUtils 出现 Can’t create Boys 解决方案,在Boys中加入无参构造器@author dell功能:封装了和数据库存储相关的一些方法通用的增删改查QueryRunner类:update(connection,sql,params)

使用 Shell 脚本来处理 JSON_隔壁老瓦的博客-程序员宅基地_shell 处理json

使用 Shell 脚本来处理 JSON,有以下三种方法:使用awksed 使用第三方库 调用其他脚本解释器JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language,Standard ECMA-262 3rd Edition - December 1999的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习...

响应式网页应用-PWA_chunwudu8469的博客-程序员宅基地

一、响应式网页应用-PWA介绍 响应式网页应用-PWA是Progressive Web App的英文缩写,渐进式增强WEB应用。一个为响应式设计的“保护伞”式的术语,是 Google 在2015年提出的概念,2017年落地的web技术。目的就是在移动端利用提供的标准化框架,在网页应用中实现和...

推荐文章

热门文章

相关标签