MPI并行程序设计

上传人:沈*** 文档编号:241944865 上传时间:2024-08-07 格式:PPTX 页数:218 大小:1.59MB
返回 下载 相关 举报
MPI并行程序设计_第1页
第1页 / 共218页
MPI并行程序设计_第2页
第2页 / 共218页
MPI并行程序设计_第3页
第3页 / 共218页
点击查看更多>>
资源描述
八月 24MPI并行程序设计1/217参考文献黄铠,徐志伟著,陆鑫达等译.可扩展并行计算技术可扩展并行计算技术,结构与编程结构与编程.北京:机械工业出版社,P.3356,P.227237,2000.陈国良著.并行计算并行计算结构、算法、编程结构、算法、编程.北京:高等教育出版社,1999.Barry Wilkinson and Michael Allen.Parallel Programming(Techniques and Applications using Networked Workstations and Parallel Computers).Prentice Hall,1999.李晓梅,莫则尧等著.可扩展并行算法的设计与分析可扩展并行算法的设计与分析.北京:国防工业出版社,2000.张宝琳,谷同祥等著.数值并行计算原理与方法数值并行计算原理与方法.北京:国防工业出版社,1999.都志辉著.高性能计算并行编程技术高性能计算并行编程技术MPI并行程序设计并行程序设计.北京:清华大学出版社,2001.八月 24MPI并行程序设计2/217相关网址MPI:http:/ww.mpi-forum.org,http:/www.mcs.anl.gov/mpiPthreads:http:/PVM:http:/www.epm.ornl.gov/pvm/OpemMP:http:/www.openmp.org网上搜索:八月 24MPI并行程序设计3/217MPI并行程序设计并行程序设计Parallel Programming with theMassage Passing Interface(MPI)八月 24MPI并行程序设计4/217多线程库标准多线程库标准Win32 API.POSIXthreads.编译制导标准编译制导标准OpenMP 可移植共享存储并行编程标准.消息传递库标准消息传递库标准MPI PVM并行编程标准并行编程标准本讨论的重点本讨论的重点八月 24MPI并行程序设计5/217消息传递并行程序设计消息传递并行程序设计消息传递并行程序设计消息传递并行程序设计指用户必须通过显式地发送和接收消息来实现处理机间的数据交换。在这种并行编程中,每个并行进程均有自己独立的地址空间,相互之间访问不能直接进行,必须通过显式的消息传递来实现。这种编程方式是大规模并行处理机(MPP)和机群(Cluster)采用的主要编程方式。并行计算粒度大,特别适合于大规模可扩展并行算法并行计算粒度大,特别适合于大规模可扩展并行算法由于消息传递程序设计要求用户很好地分解问题,组织不同进程间的数据交换,并行计算粒度大,特别适合于大规模可扩展并行算法.消息传递是当前并行计算领域的一个非常重要的并行程序消息传递是当前并行计算领域的一个非常重要的并行程序设计方式设计方式八月 24MPI并行程序设计6/217什么是什么是MPI?Massage Passing Interface:是消息传递函数库的标准规范,由MPI论坛开发,支持Fortran和C一种新的库描述,不是一种语言。共有上百个函数调用接口,在Fortran和C语言中可以直接对这些函数进行调用MPI是一种标准或规范的代表,而不是特指某一个对它的具体实现MPI是一种消息传递编程模型,并成为这种编程模型的代表和事实上的标准八月 24MPI并行程序设计7/217MPI的发展过程的发展过程发展的两个阶段MPI 1.1:1995MPICH:是MPI最流行的非专利实现,由Argonne国家实验室和密西西比州立大学联合开发,具有更好的可移植性.MPI 1.22.0:动态进程,并行 I/O,支持F90和C+(1997).八月 24MPI并行程序设计8/217为什么要用MPI?高可移植性高可移植性MPI已在IBM PC机上、MS Windows上、所有主要的Unix工作站上和所有主流的并行机上得到实现。使用MPI作消息传递的C或Fortran并行程序可不加改变地运行在IBM PC、MS Windows、Unix工作站、以及各种并行机上。八月 24MPI并行程序设计9/217讲座内容提示基本的基本的MPI基本概念基本概念点到点通信点到点通信(Pointtopoint)MPI中中API的主要内容,为的主要内容,为MPI最基本,最重要的内容最基本,最重要的内容MPI程序的编译和运行程序的编译和运行深入深入MPI用户自定义用户自定义(/派生派生)数据类型数据类型(User-defined(Derived)datatype)事实上事实上MPI的所有数据类型均为的所有数据类型均为MPI自定义类型自定义类型支持异构系统支持异构系统允许消息来自不连续的或类型不一致的存储区允许消息来自不连续的或类型不一致的存储区(结构结构,数组散元数组散元)集合通信集合通信(Collective)数据移动数据移动,数据聚集,同步数据聚集,同步基于基于pointtopoint构建构建MPI环境管理函数环境管理函数组组,上下文和通信空间上下文和通信空间/通信子的管理通信子的管理实例实例八月 24MPI并行程序设计10/217从简单入手!下面我们首先分别以C语言和Fortran语言的形式给出一个最简单的MPI并行程序Hello(下页).该程序在终端打印出Hello World!字样.“Hello World”:一声来自新生儿的问候.八月 24MPI并行程序设计11/217Hello world(C)#include#include mpi.h“main(int argc,char*argv)MPI_Init(&argc,&argv);printf(Hello,world!n);MPI_Finalize();八月 24MPI并行程序设计12/217Hello world(Fortran)program maininclude mpif.hinteger ierrcall MPI_INIT(ierr)print*,Hello,world!call MPI_FINALIZE(ierr)end八月 24MPI并行程序设计13/217C和和Fortran中中MPI函数约定函数约定C必须包含mpi.h.MPI 函数返回出错代码或 MPI_SUCCESS成功标志成功标志.MPI-前缀,且只有MPI以及MPI_标志后的第一个字母大写,其余小写.Fortran必须包含mpif.h.通过子函数形式调用MPI,函数最后一个参数为返回值.MPI-前缀,且函数名全部为大写.MPI函数的参数被标志为以下三种类型:IN:参数在例程的调用中不会被修正.OUT:参数在例程的调用中可能会被修正.INOUT:参数在一些例程中为IN,而在另一些例程中为OUT.八月 24MPI并行程序设计14/217MPI初始化-MPI_INITint MPI_Init(int*argc,char*argv)MPI_INIT(IERROR)MPI_INIT是MPI程序的第一个调用,它完成MPI程序的所有初始化工作。所有的MPI程序的第一条可执行语句都是这条语句。启动MPI环境,标志并行代码的开始.并行代码之前,第一个mpi函数(除MPI_Initialize()外).要求main必须带参数运行,否则出错.八月 24MPI并行程序设计15/217MPI结束-MPI_FINALIZEint MPI_Finalize(void)MPI_FINALIZE(IERROR)MPI_FINALIZE是MPI程序的最后一个调用,它结束MPI程序的运行,它是MPI程序的最后一条可执行语句,否则程序的运行结果是不可预知的。标志并行代码的结束,结束除主进程外其它进程.之后串行代码仍可在主进程(rank=0)上运行(如果必须).八月 24MPI并行程序设计16/217MPI程序的的编译与运行mpif77 hello.f 或 mpicc hello.c 默认生成a.out的可执行代码.mpif77 o hello hello.f 或mpicc o hello hello.c生成hello的可执行代码.mpirun np 4 a.outmpirun np 4 hello4 指定np的实参,表示进程数,由用户指定.a.out/hello 要运行的MPI并行程序.%小写o%np:The number of process.八月 24MPI并行程序设计17/217:运行我们的MPI程序!dairnode01$mpicc-o hello hello.cdairnode01$./hello ()0 Aborting program!Could not create p4 procgroup.Possible missing fileor program started without mpirun.dairnode01$mpirun-np 4 hello ()Hello World!Hello World!Hello World!Hello World!dairnode01$计算机打印字符我们输入的命令八月 24MPI并行程序设计18/217:Hello是如何被执行的?SPMD:Single Program Multiple Data(SPMD):#includempi.h#includemain(intargc,char*argv)MPI_Init(&argc,&argv);printf(Hello,world!n);MPI_Finalize();#includempi.h#includemain(intargc,char*argv)MPI_Init(&argc,&argv);printf(Hello,world!n);MPI_Finalize();#includempi.h#includemain(intargc,char*argv)MPI_Init(&argc,&argv);printf(Hello,world!n);MPI_Finalize();#includempi.h#includemain(intargc,char*argv)MPI_Init(&argc,&argv);printf(Hello,world!n);MPI_Finalize();Hello World!Hello World!Hello World!Hello World!#includempi.h#includemain(intargc,char*argv)MPI_Init(&argc,&argv);printf(Hello,world!n);MPI_Finalize();八月 24MPI并行程序设计19/217:开始写MPI并行程序在写MPI程序时,我们常需要知道以下两个问题的答案:任务由任务由多少多少个进程来进行并行计算?个进程来进行并行计算?我是我是哪一个哪一个进程进程?八月 24MPI并行程序设计20/217:开始写MPI并行程序MPI 提供了下列函数来回答这些问题:用用MPI_Comm_size 获得进程个数 p int MPI_Comm_size(MPI_Comm comm,int*size);用用MPI_Comm_rank 获得进程的一个叫rank的值,该 rank值为0到p-1间的整数,相当于进程的IDint MPI_Comm_rank(MPI_Comm comm,int*rank);八月 24MPI并行程序设计21/217更新的Hello World(c)#include#include mpi.hmain(int argc,char*argv)int myid,numprocs;MPI_Init(&argc,&argv);MPI_Comm_rank(MPI_COMM_WORLD,&myid);MPI_Comm_size(MPI_COMM_WORLD,&numprocs);printf(“I am%d of%dn,myid,numprocs);MPI_Finalize();八月 24MPI并行程序设计22/217更新的Hello World(Fortran)program maininclude mpif.hinteger ierr,myid,numprocscall MPI_INIT(ierr)call MPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)call MPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)print*,I am,myid,of,numprocscall MPI_FINALIZE(ierr)end八月 24MPI并行程序设计23/217:运行结果dairnode01$mpicc o hello1 hello1.cdairnode01$mpirun-np 4 hello1I am 0 of 4I am 1 of 4I am 2 of 4I am 3 of 4dairnode01$计算机打印字符我们输入的命令八月 24MPI并行程序设计24/217有消息传递 Greeting八月 24MPI并行程序设计25/217greetings(c)#include#include mpi.hmain(int argc,char*argv)int numprocs,myid,source;MPI_Status status;char message100;MPI_Init(&argc,&argv);MPI_Comm_rank(MPI_COMM_WORLD,&myid);MPI_Comm_size(MPI_COMM_WORLD,&numprocs);八月 24MPI并行程序设计26/217有消息传递greetings(c)if(myid!=0)strcpy(message,Hello World!);MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);else/*myid=0*/for(source=1;source numprocs;source+)MPI_Recv(message,100,MPI_CHAR,source,99,MPI_COMM_WORLD,&status);printf(%sn,message);MPI_Finalize();/*end main*/八月 24MPI并行程序设计27/217解剖greetings程序头文件:mpi.h/mpif.h.intMPI_Init(int*argc,char*argv)启动MPI环境,标志并行代码的开始.并行代码之前,第一个mpi函数(除MPI_Initialize()外).要求main必须带能运行,否则出错.通信子(通信空间):MPI_COMM_WORLD:一个通信空间是一个进程组和一个上下文的组合.上下文可看作为组的超级标签,用于区分不同的通信子.在执行函数MPI_Init之后,一个MPI程序的所有进程形成一个缺省的组,这个组的通信子即被写作MPI_COMM_WORLD.该参数是MPI通信操作函数中必不可少的参数,用于限定参加通信的进程的范围.八月 24MPI并行程序设计28/217解剖greetings程序intMPI_Comm_size(MPI_Commcomm,int*size)获得通信空间comm中规定的组包含的进程的数量.指定一个communicator,也指定了一组共享该空间的进程,这些进程组成该communicator的group.intMPI_Comm_rank(MPI_Commcomm,int*rank)得到本进程在通信空间中的rank值,即在组中的逻辑编号(从0开始).intMPI_Finalize()标志并行代码的结束,结束除主进程外其它进程.之后串行代码仍可在主进程(rank=0)上运行(如果必须).八月 24MPI并行程序设计29/217消息传送(先可不关心参数含义)MPI_Send(A,10,MPI_DOUBLE,1,99,MPI_COMM_WORLD);MPI_Recv(B,20,MPI_DOBULE,0,99,MPI_COMM_WORLD,&status);数据传送数据传送+同步操作同步操作l需要发送方与接收方合作完成.DataProcess 0Process 1发送请求YesDataDataDataDataDataDataDataDataTime八月 24MPI并行程序设计30/217最基本的MPIMPI调用借口的总数虽然庞大,但根据实际编写MPI的经验,常用的MPI调用的个数确实有限。下面是6个最基本的MPI函数。1.MPI_Init();2.MPI_Comm_size();3.MPI_Comm_rank();4.MPI_Send();5.MPI_Recv();6.MPI_Finalize();MPI_Init();并行代码并行代码;MPI_Fainalize();只能有串行代码只能有串行代码;八月 24MPI并行程序设计31/217讲座内容提示基本的MPI基本概念点到点通信(Point to point)MPI中API的主要内容,为MPI最基本,最重要的内容MPI程序的编译和运行深入MPI用户自定义(/派生)数据类型(User-defined(Derived)data type)事实上MPI的所有数据类型均为MPI自定义类型支持异构系统允许消息来自不连续的或类型不一致的存储区(结构,数组散元)集合通信(Collective)数据移动,数据聚集,同步基于point to point 构建MPI环境管理函数组,上下文和通信空间/通信子的管理实例八月 24MPI并行程序设计32/217Point to Point单个进程对单个进程的通信,重要且复杂术语Blocking(阻塞):一个例程须等待操作完成才返回,返回后用户可以重新使用调用中所占用的资源.Non-blocking(非阻塞):一个例程不必等待操作完成便可返回,但这并不意味着所占用的资源可被重用.Local(本地):不依赖于其它进程.Non-local(非本地):依赖于其它进程.八月 24MPI并行程序设计33/217Blocking Sendint MPI_Send(void*buf,int count,MPI_Datatype datatype,intdest,inttag,MPI_Commcomm);IN buf 发送缓冲区的起始地址发送缓冲区的起始地址 IN count 要发送信息的要发送信息的元素元素个数个数 IN datatype 发送信息的数据类型发送信息的数据类型 IN dest 目标进程的目标进程的rank值值 IN tag 消息标签消息标签 IN comm 通信子通信子八月 24MPI并行程序设计34/217Blocking Receiveint MPI_Recv(void*buf,int count,MPI_Datatype datatype,intsource,inttag,MPI_Commcomm,MPI_Status*status);OUT buf 接收接收缓冲区的起始地址缓冲区的起始地址 IN count 要接收信息的要接收信息的元素元素个数个数 IN datatype 接收信息的数据类型接收信息的数据类型 IN source 源进程的源进程的rank值值 IN tag 消息标签消息标签 IN comm 通信子通信子OUT statusstatus对象对象,包含实际接收到的消息的有关信息包含实际接收到的消息的有关信息八月 24MPI并行程序设计35/217MPI消息MPI消息包括信封和数据两个部分,信封指出了发送或接收消息的对象及相关信息,而数据是本消息将要传递的内容数据:信封:八月 24MPI并行程序设计36/217消息数据由count个类型为datatype的连续数据空间组成,起始地址为buf不是以字节数,而是以元素的个数指定消息的长度count可以是零,这种情况下消息的数据部分是空的MPI基本数据类型相应于宿主语言的基本数据类型 八月 24MPI并行程序设计37/217什么是缓冲区?1.应用程序中说明的变量,在消息传递语句中又用作缓冲区的起始位置.2.也可表示由系统(不同用户)创建和管理的某一存储区域,在消息传递过程中用于暂存放消息.也被称为系统缓冲区.3.用户可设置一定大小的存储区域,用作中间缓冲区以保留可能出现在其应用程序中的任意消息.进程PAM进程QB进程PAMS进程QB进程PAMT进程QB系统缓冲区用户指定缓冲区用户缓冲区八月 24MPI并行程序设计38/217MPI标识一条消息的信息包含四个域标识一条消息的信息包含四个域:Source:发送进程隐式确定,由进程的rank值唯一标识Destination:Send函数参数确定Tag:Send函数参数确定,用于识别不同的消息(0,UB),UB:MPI_TAG_UB=32767.Communicator:缺省MPI_COMM_WORLDGroup:有限/N,有序/Rank 0,1,2,N-1Contex:Super_tag,用于标识该通讯空间.消息信封八月 24MPI并行程序设计39/217八月 24MPI并行程序设计40/217消息匹配接收buffer必须至少可以容纳count个由datatype参数指明类型的数据.如果接收buf太小,将导致溢出、出错.消息匹配参数匹配 dest,tag,comm/source,tag,commSource=MPI_ANY_SOURCE:接收任意处理器来的数据(任意消息来源).Tag=MPI_ANY_TAG:匹配任意tag值的消息(任意tag消息).在阻塞式消息传送中不允许Source=Dest,否则会导致deadlock.消息传送被限制在同一个communicator.在send函数中必须指定唯一的接收者(Push/pull通讯机制).八月 24MPI并行程序设计41/217status参数当使用当使用MPI_ANY_SOURCE或或/和和MPI_ANY_TAG接收消接收消息时如何确定消息的来源息时如何确定消息的来源source和和tag值呢值呢?在C中,status.MPI_SOURCE,status.MPI_TAG.在Fortran中,source=status(MPI_SOURCE),tag=status(MPI_TAG).Status还可用于返回实际接收到消息的长度还可用于返回实际接收到消息的长度int MPI_Get_count(MPI_Status status,MPI_Datatype datatype,int*count)IN status 接收操作的返回值.IN datatype 接收缓冲区中元素的数据类型.OUT count 接收消息中的元素个数.八月 24MPI并行程序设计42/217分析greetings#include#includempi.h“main(intargc,char*argv)intnumprocs;/*进程数进程数,该变量为各处理器中的同名变量该变量为各处理器中的同名变量,存储是分布的存储是分布的*/intmyid;/*我的进程我的进程ID,存储也是分布的存储也是分布的*/MPI_Statusstatus;/*消息接收状态变量消息接收状态变量,存储也是分布的存储也是分布的*/charmessage100;/*消息消息buffer,存储也是分布的存储也是分布的*/*初始化初始化MPI*/MPI_Init(&argc,&argv);/*该函数被各进程各调用一次该函数被各进程各调用一次,得到自己的进程得到自己的进程rank值值*/MPI_Comm_rank(MPI_COMM_WORLD,&myid);/*该函数被各进程各调用一次该函数被各进程各调用一次,得到进程数得到进程数*/MPI_Comm_size(MPI_COMM_WORLD,&numprocs);八月 24MPI并行程序设计43/217分析greetingsif(myid!=0)/*建立消息建立消息*/sprintf(message,Greetings from process%d!,myid);/*发送长度取发送长度取strlen(message)+1,使使0也一同发送出去也一同发送出去*/MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);else/*my_rank=0*/for(source=1;source count=0p0p1p2P(n-1)pi空进程空进程八月 24MPI并行程序设计53/217空进程应用示意MPI_Statusstatus;intdest=(rank+1)%p;intsource=(rank+p-1)%p;if(source=p-1)source=MPI_PROC_NULL;if(dest=0)dest=MPI_PROC_NULL;MPI_Sendrecv(&a,1,MPI_INT,dest,99,&b1,MPI_INT,source,99,MPI_COMM_WORLD,&status);八月 24MPI并行程序设计54/217阻塞与非阻塞的差别用户发送缓冲区的重用:非阻塞的发送:仅当调用了有关结束该发送的语句后才能重用发送缓冲区,否则将导致错误;对于接收方,与此相同,仅当确认该接收请求已完成后才能使用。所以对于非阻塞操作,要先调用等待MPI_Wait()或测试MPI_Test()函数来结束或判断该请求,然后再向缓冲区中写入新内容或读取新内容。阻塞发送将发生阻塞,直到通讯完成.非阻塞可将通讯交由后台处理,通信与计算可重叠.发送语句的前缀由MPI_改为MPI_I,I:immediate:标准模式:MPI_Send()-MPI_Isend()Buffer模式:MPI_Bsend()-MPI_Ibsend()八月 24MPI并行程序设计55/217非阻塞发送与接收int MPI_Isend(void*buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm,MPI_Request*request)IN buf 发送缓冲区的起始地址IN count 发送缓冲区的大小(发送元素个数)IN datatype 发送缓冲区数据的数据类型IN dest 目的进程的秩IN tag 消息标签IN comm 通信空间/通信子OUT request 非阻塞通信完成对象(句柄)int MPI_Irecv(void*buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Request*request)八月 24MPI并行程序设计56/217非阻塞标准发送和接收八月 24MPI并行程序设计57/217通信的完成(常用于非阻塞通信)发送的完成:代表发送缓冲区中的数据已送出,发送缓冲区可以重用。它并不代表数据已被接收方接收。数据有可能被缓冲;接收的完成:代表数据已经写入接收缓冲区。接收者可访问接收缓冲区。通过MPI_Wait()和MPI_Test()来判断通信是否已经完成;八月 24MPI并行程序设计58/217MPI_Wait()及应用示例int MPI_Wait(MPI_Request*request,MPI_Status*status);当当request标识的通信结束后,标识的通信结束后,MPI_Wait()才返回才返回。如果通信是非阻塞的,返回时request=MPI_REQUEST_NULL;函数调用是非本地的;MPI_Request request;MPI_Status status;int x,y;if(rank=0)MPI_Isend(&x,1,MPI_INT,1,99,comm,&request)MPI_Wait(&request,&status);elseMPI_Irecv(&y,1,MPI_INT,0,99,comm,&request)MPI_Wait(&request,&status);八月 24MPI并行程序设计59/217MPI_Test()及应用示例/int MPI_Test(MPI_Request*request,int*flag,MPI_Status*status);MPI_Request request;MPI_Status status;int x,y,flag;if(rank=0)MPI_Isend(&x,1,MPI_INT,1,99,comm,&request)while(!flag)MPI_Test(&request,&flag,&status);elseMPI_Irecv(&y,1,MPI_INT,0,99,comm,&request)while(!flag)MPI_Test(&request,&flag,&status);八月 24MPI并行程序设计60/217消息探测-Probe函数(适用于阻塞与非阻塞)MPI_Probe()和MPI_Iprobe()函数探测接收消息的内容。用户根据探测到的消息内容决定如何接收这些消息,如根据消息大小分配缓冲区等。前者为阻塞方式,即只有探测到匹配的消息才返回;后者为非阻塞,即无论探测到与否均立即返回.int MPI_Probe(int source,int tag,MPI_Comm comm,MPI_Status*status)int MPI_Iprobe(int source,int tag,MPI_Comm comm,int*flag,MPI_Status*status)IN source 数据源的rank,可以是MPI_ANY_SOURCEIN tag 数据标签,可以是MPI_ANY_TAGIN comm 通信空间/通信子OUT flag 布尔值,表示探测到与否(只用于非阻塞方式)OUT status status对象,包含探测到消息的内容 八月 24MPI并行程序设计61/217MPI_Probe应用示例intx;floaty;MPI_Comm_rank(comm,&rank);if(rank=0)/*0-2发送一发送一int型数型数*/MPI_Send(100,1,MPI_INT,2,99,comm);elseif(rank=1)/*1-2发送一发送一float型数型数*/MPI_Send(100.0,1,MPI_FLOAT,2,99,comm);else/*根进程接收根进程接收*/for(inti=0;i2;i+)MPI_Probe(MPI_ANY_SOURCE,0,comm,&status);/*Blocking*/if(status.MPI_SOURCE=0)MPI_Recv(&x,1,MPI_INT,0,99,&status);elseif(status.MPI_SOURCE=1)MPI_Recv(&y,1,MPI_FLOAT,0,99,&status);八月 24MPI并行程序设计62/217讲座内容提示基本的MPI基本概念点到点通信(Point to point)MPI中API的主要内容,为MPI最基本,最重要的内容MPI程序的编译和运行深入MPI用户自定义(/派生)数据类型(User-defined(Derived)data type)事实上MPI的所有数据类型均为MPI自定义类型支持异构系统允许消息来自不连续的或类型不一致的存储区(结构,数组散元)集合通信(Collective)数据移动,数据聚集,同步基于point to point 构建MPI环境管理函数组,上下文和通信空间/通信子的管理实例八月 24MPI并行程序设计63/217MPI程序的编译mpicc编译并连接用C语言编写的MPI程序mpiCC编译并连接用C+编写的MPI程序mpif77编译并连接用FORTRAN 77编写的MPI程序mpif90编译并连接用Fortran 90编写的MPI程序这些命令可以自动提供MPI需要的库,并提供特定的开关选项(用-help查看)。八月 24MPI并行程序设计64/217MPI程序的编译用mpicc编译时,就像用一般的C编译器一样。还可以使用一般的C的编译选项,含义和原来的编译器相同例如:./mpicc-cfoo.c./mpicc-ofoofoo.o八月 24MPI并行程序设计65/217MPI程序的运行MPI程序的执行步骤一般为:编译以得到MPI可执行程序(若在同构的系统上,只需编译一次;若系统异构,则要在每一个异构系统上都对MPI源程序进行编译)将可执行程序拷贝到各个节点机上通过mpirun命令并行执行MPI程序八月 24MPI并行程序设计66/217最简单的MPI运行命令mpirun np N 其中:N:同时运行的进程数:可执行MPI程序名例如:mpirun np 6 cpimpirun np 4 hello八月 24MPI并行程序设计67/217一种灵活的执行方式mpirunp4pg为配置文件,其格式为:为配置文件,其格式为:例如例如:(注:第一行的注:第一行的0并不表示在并不表示在node0上没有上没有进程,这里的进程,这里的0特指在特指在node0上启动上启动MPI程序程序)node00/public0/dair/mpi/cpinode11/public0/dair/mpi/cpinode21/public0/dair/mpi/cpi这种方式允许可执行程序由不同的名字和不同的这种方式允许可执行程序由不同的名字和不同的路径路径八月 24MPI并行程序设计68/217另一种灵活的执行方式mpirunmachinefile-np为配置文件,其格式为:为配置文件,其格式为:例如例如:node0node1node2node3八月 24MPI并行程序设计69/217完整的MPI运行方式MPI程序的一般启动方式:程序的一般启动方式:mpirun np 完整的完整的MPI运行方式:运行方式:mpirun mpirun_options options详细参数信息执行mpirun-help八月 24MPI并行程序设计70/217讲座内容提示基本的MPI基本概念点到点通信(Point to point)MPI中API的主要内容,为MPI最基本,最重要的内容MPI程序的编译和运行深入MPI用户自定义(/派生)数据类型(User-defined(Derived)data type)事实上MPI的所有数据类型均为MPI自定义类型支持异构系统允许消息来自不连续的或类型不一致的存储区(结构,数组散元)集合通信(Collective)数据移动,数据聚集,同步基于point to point 构建MPI环境管理函数组,上下文和通信空间/通信子的管理实例八月 24MPI并行程序设计71/217MPI数据类型if(my_rank!=0)/*建立消息建立消息*/sprintf(message,Greetings from process%d!,my_rank);/*发送长度取发送长度取strlen(message)+1,使使0也一同发送出去也一同发送出去*/MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);else/*my_rank=0*/for(source=1;source p;source+)MPI_Recv(message,100,MPI_CHAR,source,99,MPI_COMM_WORLD,&status);printf(“%sn,message);/*关闭关闭MPI,标志并行代码段的结束标志并行代码段的结束*/MPI_Finalize();/*main*/八月 24MPI并行程序设计72/217用户自定义数据类型/派生数据类型目的目的异构计算:不同系统有不同的数据表示格式。MPI预先定义一些基本数据类型,在实现过程中在这些基本数据类型为桥梁进行转换。派生数据类型:允许消息来自不连续的和类型不一致的存储区域,如数组散元与结构类型等的传送。MPI中所有数据类型均为中所有数据类型均为MPI自定义类型自定义类型基本数据类型,如MPI_INT,MPI_DOUBLE用户定义数据类型或派生数据类型.八月 24MPI并行程序设计73/217MPI基本数据类型八月 24MPI并行程序设计74/217数据类型图八月 24MPI并行程序设计75/217Derived Datatype(派生)常用MPI_Type_contiguousMPI_Type_vectorMPI_Type_indexedMPI_Type_struct八月 24MPI并行程序设计76/217MPI_Type_contiguous将原数据类型,按顺序进行多次复制八月 24MPI并行程序设计77/217在FORTRAN中定义矩阵的一列REAL A(1000,1000)INTEGER F_COLMPI_TYPE_CONTIGUOUS(1000,MPI_REAL,F_COL)MPI_SEND(A,1,F_COL,right,tag,MPI_COMM_WORLD)在C中定义矩阵的一行float a10001000;MPI_Datatype C_R;MPI_Type_contiguous(1000,MPI_FLOAT,&C_R);MPI_SEND(&(a00),1,C_R,right,tag,MPI_COMM_WORLD)八月 24MPI并行程序设计78/217用MPI_Vector进行矩阵的行列置换以C语言的数组表示为例:将矩阵的一列送到另一数组的一行中八月 24MPI并行程序设计79/217MPI_Vector函数原型MPI_Vector()MPI_Vector()函函数数首首先先通通过过连连续续复复制制若若干干个个旧旧数数据据类类型型形形成成一一个个“块块”,然然后后通通过过等等间间隔隔地地复复制制该该块块儿儿形形成成新新的的数数据据类类型。型。块与块之间的空间时旧数据类型的倍数块与块之间的空间时旧数据类型的倍数。#include mpi.hint MPI_Type_vector (int count,/*数据块个数数据块个数(非负整数非负整数)*/int blocklen,/*块中元素个数块中元素个数(非负整数非负整数)*/int stride,/*块间块间起始地址间隔起始地址间隔(非负整数非负整数)*/MPI_Datatype old_type,/*原始数据类型原始数据类型(句柄句柄)*/MPI_Datatype *newtype/*派生数据类型指针派生数据类型指针*/)八月 24MPI并行程序设计80/217MPI_Type_vector应用示意用用MPI_Vector进行矩阵的行列置换进行矩阵的行列置换 float A1010;MPI_Datatype column_mpi_t;MPI_Type_vector(10,1,10,MPI_FLOAT,&column_mpi_t);MPI_Type_commit(&column_mpi_t);if(my_rank=0)MPI_Send(&(A00),1,column_mpi_t,1,0,MPI_COMM_WORLD);else /*my_rank=1*/MPI_Recv(&(A00),10,MPI_FLOAT,0,0,MPI_COMM_WORLD,&status);八月 24MPI并行程序设计81/217用MPI_Type_indexed发送矩阵的上三角部分以C语言表示的数组为例,数组按行连续存储八月 24MPI并行程序设计82/217MPI_Type_indexed函数原型#include mpi.hint MPI_Type_indexed (int count,/*数据块的个数,数据块间不连续数据块的个数,数据块间不连续*/int blocklens,/*每一数据块中元素的个数,为一个非负整型数组每一数据块中元素的个数,为一个非负整型数组*/int indices,/*每一块数据在每一块数据在原始数据类型原始数据类型中的起始位置中的起始位置,整型数组整型数组*/MPI_Datatype old_type,/*原始数据类型原始数据类型(名柄名柄)*/MPI_Datatype*newtype/*派生数据类型指针派生数据类型指针*/)八月 24MPI并行程序设计83/217MPI_Type_indexed应用示意应用示意(将将A矩阵的上三角矩阵的上三角部分送到另一个处理器中的部分送到另一个处理器中的T矩阵的对应位置矩阵的对应位置)floatAnn;/*Complete Matrix*/float Tnn;/*Upper Triangle */int displacementsn;int block_lengthsn;MPI_Datatype index_mpi_t;for(i=0;i n;i+)block_lengthsi=n-i;displacementsi=(n+1)*i;MPI_Type_indexed(n,block_lengths,displacements,MPI_FLOAT,&index_mpi_t);MPI_Type_commit(&index_mpi_t);if(my_rank=0)MPI_Send(A,1,index_mpi_t,1,0,MPI_COMM_WORLD);else/*my_rank=1*/MPI_Recv(T,1,index_mpi_t,0,0,MPI_COMM_WORLD,&status);八月 24MPI并行程序设计84/217MPI_Type_struct允许每个块包含不同数据类型的拷贝八月 24MPI并行程序设计85/217MPI_Type_struct的例子struct partstruct char class;double d6;char b7;struct partstruct particle1000;int i,dest,rank;MPI_Datatype particletype,type3=MPI_CHAR,MPI_DOUBLE,MPI_CHARint blocklen3=1,6,7;MPI_Aint disp3=0,sizeof(double),7*sizeof(double);MPI_Type_struct(3,blocklen,disp,type,&particletype);八月 24MPI并行程序设计86/217其它派生类型MPI_HvectorMPI_HindexedMPI_Pack/MPI_Unpack:数据打包/解包是其它数据派生数据类型的基础,MPI不建议用户进行显式的数据打包为了与早期其它并行库兼容八月 24MPI并行程序设计87/217MPI_Pack()int MPI_Pack(void*inbuf,/*输入缓冲区起始地址*/int incount,/*输入数据项个数*/MPI_Datatypedatatype,/*输入数据项的数据类型*/void*outbuf,/*输出缓冲区起始地址*/intoutcount,/*输出缓冲区大小*/int*position,/*输出缓冲区当前位置*/MPI_Commcomm/*通信域*/)例:packsize=0;MPI_Pack(&a,1,MPI_INT,packbuf,100,&packsize,MPI_COMM_WORLD);MPI_Pack(&b,1,MPI_DOUBLE,packbuf,100,&packsize,MPI_COMM_WORLD);八月 24MPI并行程序设计88/217MPI_Unpack()int MPI_Unpack(void*inbuf,/*输入缓冲区起始地址*/int incount,/*输入数据项大小*/int*position,/*缓冲区当前位置*/void*outbuf,/*输出缓冲区起始地址*/intoutcount,/*输出缓冲区大小*/MPI_Datatypedatatype,/*输出数据项的数据类型*/MPI_Commcomm/*通信域*/)例:pos=0;MPI_Unpack(packbuf,packsize,&pos,&a,1,MPI_INT,MPI_COMM_WROLD);MPI_Unpack(packbuf,packsize,&pos,&b,1,MPI_FLOAT,MPI_COMM_WROLD);八月 24MPI并行程序设计89/217派生数据类型的应用提交:int MPI_Type_commit(MPI Datatype*datatype)将数据类型映射进行转换或“编译”一种数据类型变量可反复定义,连续提交释放:int MPI_Type free(MPI_Datatype*datatype)将数据类型设为MPI_DATATYPE_NULL八月 24MPI并行程序设计90/217讲座内容提示基本的MPI基本概念点到点通信(Point to point)MPI中API的主要内容,为MPI最基本,最重要的内容MPI程序的编译和运行深入MPI用户自定义(/派生)数据类型(User-defined(Derived)data type)事实上MPI的所有数据类型均为MPI自定义类型支持异构系统允许消息来自不连续的或类型不一致的存储区(结构,数组散元)集合通信(Collective)数据移动,数据聚集,同步基于point to point 构建MPI环境管理函数组,上下文和通信空间/通信子的管理实例八月 24MPI并行程序设计91/217集合通信Collective Communication特点通信空间中的所有进程都参与通信操作每一个进程都需要调用该操作函数一到多多到一同步八月 24MPI并行程序设计92/217类型函数功能数据移动MPI_Bcast一到多,数据广播MPI_Gather多到一,数据汇合MPI_GathervMPI_Gather的一般形式MPI_AllgatherMPI_Gather的一般形式MPI_AllgathervMPI_Allgather的一般形式MPI_Scatter一到多,数据分散MPI_ScattervMPI_Scatter的一般形式MPI_Alltoall多到多,置换数据(全互换)MPI_AlltoallvMPI_Alltoall的一般形式数据聚集MPI_Reduce多到一,数据归约MPI_Allreduce上者的一般形式,结果在所有进程MPI_Reduce_scatter结果scatter到各个进程MPI_Scan前缀操作同步MPI_Barrier同步操作MPI集合通信函数All:表示结果到所有所有进程.V:Variety,被操作的数据对象和操作更为灵活.%八月 24MPI并行程序设计93/217数据移动BroadcastScatterGatherAllgatherAlltoall八月 24MPI并行程序设计94/217数据聚集ReduceAllreduceReduce-scatterScanMPI预定义全局数据运算符:MPI_MAX/MPI_MIN;MPI_SUM求和MPI_PROD求积MPI_LAND逻辑与MPI_LOR逻辑或MPI_MAXLOC/MPI_MINLOC最大/小值求下相应位置八月 24MPI并行程序设计95/217intp,myrank;floatbuf;MPI_Commcomm;MPI_Init(&argc,&argv);/*得进程编号得进程编号*/MPI_Comm_rank(comm,&my_rank);/*得进程总数得进程总数*/MPI_Comm_size(comm,&p);if(myrank=0)buf=1.0;MPI_Bcast(&buf,1,MPI_FLOAT,0,comm);Broadcast-数据广播databuf.MPI_Bcast();.data.MPI_Bcast();.data.MPI_Bcast();.Process 0myrank=0Process 1myrank=1Process p-1myrank=
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!