【文档说明】第四讲消息传递编程接口MPI课件.ppt,共(40)页,548.155 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-45505.html
以下为本文档部分文字说明:
第四讲消息传递编程接口MPI主要内容◆MPI程序基本结构❑MPI编程基础❑MPI安装、程序编译与运行◆MPI数据类型◆消息发送和接收◆MPI一些常用函数MPI下载与安装❑MPICH下载http://www.mpich.org/❑MPIC
H的安装⚫参考MPICHInstallGuide❑MPICH的使用⚫参考MPICHUserGuideMPI编程基本概念❑MPI进程⚫MPI程序中一个独立参与通信的个体❑MPI进程组⚫MPI程序中由部分或全部进程构成的有序集合⚫每个进程都被赋予一个所在进程组中唯
一的序号(rank),用于在该组中标识该进程,称为进程号,取值从0开始MPI进程与通信器❑MPI通信器/通信子(Communicator)⚫MPI程序中进程间的通信必须通过通信器进行⚫通信器分为域内通信器(同一进程组内的通信)和域间通
信器(不同进程组的进程间的通信)◆MPI程序中,一个MPI进程由一个进程组和在该组中的进程号唯一确定;或由一个通信器和在该通信器中的进程号唯一确定◆进程号是相对进程组或通信器而言的,同一进程在不同的进程组或通信器中可以有不同的进程号⚫MPI程序启动时自动建立两个通信器:MPI
_COMM_WORLD:包含程序中所有MPI进程MPI_COMM_SELF:有单个进程独自构成,仅包含自己MPI消息◆进程号是在进程组或通信器被创建时赋予的◆空进程:MPI_PROC_NULL◆与空进程通信时不做任何操作❑消息(message)⚫一个消息指进程间进行的一次数据交换⚫一个
消息由通信器、源地址、目的地址、消息标签、和数据构成第一个MPIFortran程序programmaininclude'mpif.h'character*(MPI_MAX_PROCESSOR_NAME)proc_nameintegermyid,numprocs,
namelen,rc,ierrcallMPI_INIT(ierr)callMPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)callMPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)callMPI_GET_P
ROCESSOR_NAME(proc_name,namelen,ierr)write(*,10)myid,numprocs,proc_name10FORMAT('Hello,IamProc.',I2,'of',I
1,'on',20A)callMPI_FINALIZE(ierr)endmpif.h是MPI相对于FORTRAN的头文件MPI程序分析➢所有包含MPI调用的程序必须包含MPI头文件➢MPI_MAX_PROCESSOR_NAME是MPI预定义的宏,即MPI所允许的机器名字的最大长度➢MPI
程序的开始和结束必须是MPI_INIT和MPI_FINALIZE,分别完成MPI的初始化和结束工作➢MPI_COMM_RANK得到本进程的进程号➢MPI_COMM_SIZE得到所有参加运算的进程的个数➢MPI_GET_PROCESSOR_NAME得到运
行本进程所在的结点的主机名➢进程号取值范围为0,…,np-1MPI程序分析◆在单个结点(c1)上,开4个进程的运行结果Hello,IamProc.1of4onc1Hello,IamProc.0of4onc1Hello,IamProc.2of4o
nc1Hello,IamProc.3of4onc1◆在四个结点上,开4个进程的运行结果Hello,IamProc.1of4onc1Hello,IamProc.0of4onc2Hello,IamProc.2of4onc4Hel
lo,IamProc.3of4onc3MPI程序执行过程启动编译生成的可执行文件hello进程0MPI_INITMPI_COMM_RANKmyid=0MPI_GET_PROCESSOR_NAMEproc_name=c1namelen=2Writeh
ello,Iamproc.0of4onc1MPI_FINALIZE进程3MPI_INITMPI_COMM_RANKmyid=4MPI_GET_PROCESSOR_NAMEproc_name=c1namele
n=2Writehello,Iamproc.3of4onc1MPI_FINALIZE︰︰︰︰︰︰︰程序运行结束︰︰︰︰︰︰︰进程1进程2第一个MPIC程序#include"mpi.h"#include<stdio.h>#include<math.h>
intmain(argc,argv)intargc;char*argv[];{intmyid,np;intnamelen;charproc_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(proc_name,&namelen);fprintf(stderr,"Hello,Iamproc.%dof%don%s\n",
myid,np,proc_name);MPI_Finalize();}mpi.h是MPI相对于C语言的头文件MPI编程的一些惯例⚫MPI的所有常量、变量与函数/过程均以MPI_开头⚫MPI的C语言接口为函数,FORTRAN接口为SUBROUTINE,且
对应接口的名称相同⚫在C程序中,所有常数的定义除下划线外一律由大写字母组成,在函数和数据类型定义中,接MPI_之后的第一个字母大写,其余全部为小写字母,即MPI_Xxxx_xxx形式⚫对于FORTRAN程序,MPI函数全部以过程方式调用,一般全用大写字母
表示,即MPI_XXXX_XXX形式(FORTRAN不区分大小写)⚫除MPI_WTIME和MPI_WTICK外,所有C函数调用之后都将返回一个错误信息码,而MPI的所有FORTRAN子程序中都有一个哑元参数(IERR)代表错误码MPI编程的一些惯例
⚫由于C语言的函数调用机制是值传递,所以MPI的所有C函数中的输出参数用的都是指针⚫MPI是按进程组(ProcessGroup)方式工作:所有MPI程序在开始时均被认为是在通信器MPI_COMM_WORLD所拥有的进程组中工作,之后用户可以根据自己的需要,建立其它的进程
组⚫所有MPI的通信一定要在通信器中进行⚫FORTRAN的数组下标缺省以1开始,而C语言的数组是以0开始MPI数据类型◆MPI除了提供C语言函数和FORTRAN子程序之外,还定义了一组常量和C变量数据类型◼MPI常量命名规则:全部大写◼MPI变量数据类型命名规则:以MPI_开头,后面跟C语
言或FORTRAN原始数据类型名称◼MPI数据类型:原始数据类型和自定义数据类型MPI原始数据类型MPIdatatypeFortrandatatypeMPI_INTEGERINTEGERMPI_REALREALMPI_DOUBLE_PRECISIONDOUBL
EPRECISIONMPI_COMPLEXCOMPLEXMPI_DOUBLE_COMPLEXDOUBLECOMPLEXMPI_LOGICALLOGICALMPI_CHARACTERCHARACTER(1)MPI_BYTEMPI_PACKEDFORTRAN77数据类
型MPI原始数据类型C数据类型MPIdatatypeCdatatypeMPI_CHARsignedcharMPI_SHORTsignedshortintMPI_INTsignedintMPI_LONGsignedlongintMPI_UNSIGNED_CHARunsig
nedcharMPI_UNSIGNED_SHORTunsignedshortintMPI_UNSIGNED_INTunsignedintMPI_UNSIGNED_LONGunsignedlongintMPI_FLOATfloatMPI_D
OUBLEdoubleMPI_LONG_DOUBLElongdoubleMPI_BYTEMPI_PACKEDMPI原始数据类型附加的MPI数据类型相应的C数据类型MPI_LONG_LONG_INTlonglongint某些MPI系统还支持一些附加数据类型附加的MPI数据类型相
应的FORTRAN77数据类型MPI_REAL2REAL*2MPI_REAL4REAL*4MPI_REAL8REAL*8MPI_INTEGER1INTEGER*1MPI_INTEGER2INTEGER*2MPI_INTEGER4I
NTEGER*4MPI最常用的六个接口◆MPI_INIT◆MPI_FINALIZE◆MPI_COMM_RANK◆MPI_COMM_SIZE◆MPI_SEND◆MPI_RECVMPI_INIT◆MPI_INIT:MPI初始化参数无C
intMPI_Init(int*argc,char***argv)F77MPI_INIT(IERR)INTEGERIERR⚫该函数初始化MPI并行程序的执行环境,它必须在调用所有其它MPI函数(除MPI_INITIALIZED)之前被调用,并且在一个MPI程序中,只能被调用一次MP
I_FINALIZE◆MPI_FINALIZE:结束MPI系统参数无CintMPI_Finalize(void)F77MPI_FINALIZE(IERR)INTEGERIERR⚫该函数清除MPI环境的所有状态。即一但它被调用,所有MPI函数都不能再调用,其中包括
MPI_INITMPI_COMM_RANK◆MPI_COMM_RANK(comm,rank)参数INcomm通信器OUTrank本进程在通信器comm中的进程号CintMPI_Comm_rank(MPI_Commco
mm,int*rank)F77MPI_COMM_RANK(COMM,RANK,IERR)INTEGERCOMM,RANK,IERR⚫该函数返回本进程在指定通信器中的进程号MPI_COMM_SIZE◆MPI_COMM_SIZE(co
mm,size)参数INcomm通信器OUTsize该通信器comm中的进程数CintMPI_Comm_size(MPI_Commcomm,int*size)F77MPI_COMM_SIZE(COMM,SIZE,IERR)INTEGERCOMM,SIZE,IE
RR⚫该函数返回指定通信器所包含的进程数MPI_SEND点对点通信◆MPI_SEND(buf,count,datatype,dest,tag,comm)参数INbuf所发送消息的首地址INcount将发送的数据的个数INdatatype发送数据的数据类型INdest接收消息的进程的标识号INta
g消息标签INcomm通信器CintMPI_Send(void*buf,intcount,MPI_Datatypedatatype,intdest,inttag,MPI_Commcomm)F77MPI_SEND(BUF,COUNT,DATATYPE,DEST,TAG,
COMM,IERR)<type>BUF(*)INTEGERCOUNT,DATATYPE,DEST,TAG,COMM,IERRMPI_SEND点对点通信MPI_SEND(buf,count,datatype,des
t,tag,comm)⚫阻塞型消息发送接口⚫MPI_SEND将缓冲区中count个datatype类型的数据发给进程号为dest的目的进程。这里count是元素个数,即指定数据类型的个数,不是字节数,数据的
起始地址为buf。本次发送的消息标签是tag,使用标签的目的是把本次发送的消息和本进程向同一目的进程发送的其它消息区别开来。其中dest的取值范围为0~np-1(np表示通信器comm中的进程数)或MPI_PROC_NULL,tag的取值为0~MPI_TAG_UB⚫该函数可以发送各种类型的
数据,如整型、实型、字符等⚫点对点通信是MPI通信机制的基础MPI_RECV点对点通信◆MPI_RECV(buf,count,datatype,source,tag,comm,status)参数OUTbuf接收消息数据的首地址I
Ncount接收数据的最大个数INdatatype接收数据的数据类型INsource发送消息的进程的标识号INtag消息标签INcomm通信器OUTstatus返回状态CintMPI_Recv(void*buf,intcount
,MPI_Datatypedatatype,intsource,inttag,MPI_Commcomm,MPI_Status*status)F77MPI_RECV(BUF,COUNT,DATATYPE,SOURCE,TAG,COMM,STATUS,IERR)<
type>BUF(*)INTEGERCOUNT,DATATYPE,SOURCE,TAG,COMM,IERR,STATUS(MPI_STATUS_SIZE)MPI_RECV点对点通信MPI_RECV(buf,count,datatype,source,tag,comm,status)⚫阻塞型消
息接收接口⚫从指定的进程source接收不超过count个datatype类型的数据,并把它放到缓冲区中,起始位置为buf,本次消息的标识为tag。这里source的取值范围为0~np-1,或MPI_ANY_SOURCE,或MPI_PROC_NULL,tag的取值为0~MPI_TAG_
UB或MPI_ANY_TAG⚫接收消息时返回的状态STATUS,在C语言中是用结构定义的,在FORTRAN中是用数组定义的,其中包括MPI_SOURCE,MPI_TAG和MPI_ERROR。此外STATUS还包含接收消息元素的个数,但它不是显式给出的,需要用
到后面给出的函数MPI_GET_COUNTMPI程序示例例:将每个进程中某个数据发送给下一个进程,并从前一个进程接收一个数据,即0号进程给1号进程发送一个数据,并从np-1号进程接收一个数据,1号进程从0号进程接收一个数据,并向2号进程发送一个数据
,以此类推。⚫实现方式一:0号进程先发送后接收,其它进程先接收后发送⚫实现方式二:奇数号进程先发送后接收,偶数号进程先接收后发送例:ex4sendrecv01.f,ex4sendrecv02.f上机作业在使用阻塞型函数传递消息时要避免死锁!MPI发送接收MPI_SEND(b
uf,count,datatype,dest,tag,comm)MPI_RECV(buf,count,datatype,source,tag,comm,status)消息数据消息数据消息信封消息信封发送数据类型、通信函数中的数据类型、接收的数据类型要
一致!C:结构status.MPI_SOURCEstatus.MPI_TAGstatus.MPI_ERRORFORTRAN:数组status(MPI_SOURCE)status(MPI_TAG)status(MPI_
ERROR)发送与接收组合进行◆MPI_SENDRECV(sendbuf,sendcount,sendtype,dest,sendtag,recvbuf,recvcount,recvtype,source,r
ecvtag,comm,status)参数略CintMPI_Sendrecv(void*sendbuf,intsendcount,MPI_Datatypesendtype,intdest,intsendtag,void*recvbuf,intrecvcount,MPI_D
atatyperecvtype,intsource,intrecvtag,MPI_Commcomm,MPI_Status*status)F77MPI_SENDRECV(SENDBUF,SENDCOUNT,SENDTYPE,DEST,SENDTAG,REC
VBUF,RECVCOUNT,RECVTYPE,SOURCE,RECVTAG,COMM,STATUS,IERR)<type>SENDBUF(*),RECVBUF(*)INTEGERSENDCOUNT,SEND
TYPE,DEST,SENDTAG,RECVCOUNT,RECVTYPE,SOURCE,RECVTAG,COMM,IERR,STATUS(MPI_STATUS_SIZE)MPI_SENDRECV◆MPI_SENDRECV(send
buf,sendcount,sendtype,dest,sendtag,recvbuf,recvcount,recvtype,source,recvtag,comm,status)⚫这是发送消息和接收消息组合在一起的一个函数
,好处是不用考虑先发送还是先接收消息,从而可以避免消息传递过程中的死锁⚫sendbuf和recvbuf必须指向不同的缓冲区例:ex4sendrecv03.fMPI_SENDRECV_REPLACE◆MPI_SENDRECV
_REPLACE(buf,datatype,dest,sendtag,source,recvtag,comm,status)⚫功能与MPI_SENDRECV类似,但收发消息使用的是同一个缓冲区例:ex4sendrecv04.
fMPI程序示例例:计算的值。➢采用等步长中矩形公式,其中n为积分区间数,h=1/n为步长,xi=(i+0.5)h为积分区间的中点➢假设采用p的进程同时计算,各自计算其中的一部分,然后再将结果加起来。例:ex4p
i.f12014d()1niixhfxx==+mpif77-Wno-globals–oex4piex4pi.fMPI_GET_COUNT◆MPI_GET_COUNT(status,datatype,count)参数INstatus接收操作的返回状态INdatatype接收
操作使用的数据类型OUTcount接收到的数据个数CintMPI_Get_count(MPI_Status*status,MPI_Datatypedatatype,int*count)F77MPI_GET_COUNT(STATUS,DATATYPE,COUNT,IERR)INTE
GERDATATYPE,COUNT,IERR,STATUS(MPI_STATUS_SIZE)⚫查询实际接收到的数据信息MPI异常终止◆MPI_ABORT(comm,errorcode)参数INcomm
通信器OUTerrorcode错误码CintMPI_Abort(MPI_Commcomm,interrorcode)F77MPI_ABORT(COMM,ERRORCODE,IERR)INTEGERCOMM,ERRORCODE,IERR⚫异常终止MPI程序的执行,MPI系统会尽量设
法终止通信器中的所有进程MPI计时函数◆MPI_WTIME()参数无CdoubleMPI_Wtime(void)F77DOUBLEPRECISIONMPI_WTIME()⚫该函数返回当前的墙钟时间MPI计时函数◆MPI_WTICK()参数无CdoubleMPI_Wtick(
void)F77DOUBLEPRECISIONMPI_WTICK()⚫该函数返回MPI_WTIME的时钟精度,单位为秒MPI_WTIME和MPI_WTICK是C中仅有的两个返回双精度值而非整型错误码的MPI函数;
它们也是FORTRAN中仅有的两个FUNCTION形式的接口!获取结点主机名◆MPI_GET_PROCESSOR_NAME(name,namelen)⚫该函数返回进程所在结点的主机名参数OUTname结点主机
名OUTnamelen主机名的长度CintMPI_Get_processor_name(char*name,int*namelen)F77MPI_GET_PROCESSOR_NAME(NAME,NAMELEN,IERR)CHARACTER(*)NAMEINTEGERNAMELEN,IERR获取MP
I版本号◆MPI_MPI_GET_VERSION(version,subver)⚫该函数返回MPI的版本号参数OUTversion主版本号OUTsubver次版本号CintMPI_Get_version(int*ve
rsion,int*subver)F77MPI_GET_VERSION(VERSION,SUBVER,IERR)INTEGERVERSION,SUBVER,IERR