版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Fortran语言MPI并行计算程式设计编着:郑守成期间:民国92年2月12日电话:(03)5776085x305E-mail:c00tch00@.tw
TOC\o"1-4"\h\zFortran語言 1MPI并行計算程式設計 1第一章前言 51.1MPI并行計算軟體 61.2國家高速網路與計算中心的并行計算環境 71.3在IBM電腦系統上如何使用MPI 81.3.1IBM電腦系統的MPIFortran程式編譯指令 81.3.2IBM電腦系統的Jobcommandfile 81.3.3IBM電腦系統的并行程式的執行指令 111.4在PCCluster上如何使用MPI 131.4.1PCCluster上的MPIFortran程式編譯指令 131.4.2PCCluster上的Jobcommandfile 141.4.3PCCluster上的并行程式執行指令 15第二章無邊界資料交換的并行程式 162.1MPI基本指令 172.1.1mpif.hincludefile 172.1.2MPI_INIT,MPI_FINALIZE 172.1.3MPI_COMM_SIZE,MPI_COMM_RANK 182.1.4MPI_SEND,MPI_RECV 192.2無邊界資料交換的循序程式T2SEQ 212.3資料不切割的并行程式T2CP 232.4MPI_SCATTER,MPI_GATHER,MPI_REDUCE 282.4.1MPI_SCATTER,MPI_GATHER 282.4.2MPI_REDUCE,MPI_ALLREDUCE 302.5資料切割的并行程式T2DCP 32第三章需要邊界資料交換的并行程式 363.1MPI_SENDRECV,MPI_BCAST 373.1.1MPI_SENDRECV 373.1.2MPI_BCAST 373.2邊界資料交換的循序程式T3SEQ 393.3資料不切割的邊界資料交換并行程式T3CP 403.4資料切割的邊界資料交換并行程式(一)T3DCP_1 473.5資料切割的邊界資料交換并行程式(二)T3DCP_2 52第四章格點數不能整除的并行程式 574.1格點數不能整除的循序程式T4SEQ 584.2.MPI_SCATTERV、MPI_GATHERV 604.3MPI_PACK、UNPACK、BARRIER、WTIME 624.3.1MPI_PACK、MPI_UNPACK 624.3.2MPI_BARRIER、MPI_WTIME 654.4資料切割的并行程式T4DCP 67第五章多維陣列的并行程式 725.1多維陣列的循序程式T5SEQ 735.2多維陣列資料不切割的并行程式T5CP 765.3多維陣列末維資料切割的并行程式T5DCP 855.4與二維切割有關的MPI副程式 925.4.1垂直座標圖示法則(CartesianTopology) 925.4.2界定二維切割的MPI副程式MPI_CART_CREATE、 93MPI_CART_COORDS、MPI_CART_SHIFT 935.4.3定義固定間隔資料的MPI副程式 96MPI_TYPE_VECTOR、MPI_TYPE_COMMIT 965.5多維陣列末二維切割的并行程式T5_2D 98第六章MPI程式的效率提昇 1126.1Nonblocking資料傳送 1136.2資料傳送的合併 1226.3以邊界資料計算取代邊界資料交換 1266.4 輸出入資料的安排 1286.4.1事先切割輸入資料 1286.4.2事後收集切割過的輸出資料 131第七章導出的資料類別 1337.1 導出的資料類別 1347.2 陣列的轉換 1397.3 兩方迴歸與管線法 149第八章多方依賴及SOR解法 1558.1 四方依賴及SOR解法 1568.2 黑白點間隔SOR解法 1598.3 斑馬線SOR解法 1688.4 八方依賴與四色點間隔SOR解法 175第九章有限元素法程式 1839.1 有限元素法的循序程式 1849.2 有限元素法的并行程式 187附錄一撰寫C語言的MPI程式 197參考書目 200ParallelProcessingwithoutPartitionof1-DArrays 201ParallelProcessingwithPartitionof1-DArrays 202Parallelonthe2ndDimensionof2-DArrayswithoutPartition 203Parallelonthe2ndDimensionof2-DArrayswithPartition 204Partitiononthe3rddimensionof3-DArrays 205第一章前言本章将介绍MPI并行计算软体、国家高速网路与计算中心现有的并行计算环境、以及在各型机器上如何使用MPI。第一节简单介绍MPI并行计算软体。第二节介绍国家高速网路与计算中心现有的并行计算环境。第三节介绍如何在IBM电脑系统上使用MPI,包括路径的设定、并行程式的编译、及并行程式的执行等。第四节介绍如何在PCcluster上使用MPI,包括路径的设定、并行程式的编译、及并行程式的执行等。1.1MPI并行计算软体MPI(MessagePassingInterface)是第一个标准化的MessagePassing并行语言。可以使用在Fortran、C、C++等语言撰写的程式上。MPI并行程式可以在分散式记忆体并行系统上执行,也可以在共用记忆体并行系统上执行。目前系统厂商所提供的MPI软体是属于MPI1.2版。它提供了一百多个副程式,让程式人员来选用。MPI协会在1998年公布了MPI2.0版的规格,数年之后就会有MPI2.0版的软体可用了。日前美国的ArgonneNationalLab已经公布了MPICH1.2.0版的整套软体,该版含有MPI2.0版的部份功能。有兴趣的读者可以免费自网路下载该软体,其网址是/mpi/mpich也可以用anonymousftp下载该软体,其网址是其下目录(directory)pub/mpi里档名mpich-1.2.0.tar.Z或mpich-1.2.0.tar.gz,在该目录之下还有许多与MPI相关的资讯可供参考。1.2国家高速网路与计算中心的并行计算环境目前国家高速网路与计算中心的IBMSP2、IBMSP2SMP、IBMp690、HPSPP2200、SGIOrigin2000和FujitsuVPP300等系统上均有该公司自备的MPI并行软体,PCcluster上是装用MPICH公用并行软体,也都有能力执行并行程式。但是到目前为止,只有PCcluster、IBMSP2、IBMSP2SMP和IBMp690设有一个CPU只执行一个程式的并行环境,其他机器上则无此种设定。例如,若有一个用户要用四个CPU来执行其并行程式,他在IBMSP2上取得四个CPU之后,这四个CPU就仅只执行这个并行程式直到它执行完毕为止,不会有其他程式进来跟他抢CPU时间。但他在其他机器(如HPSPP2000)上取得四个CPU之后,如果所有使用者对CPU的需求数量超过该系统的CPU总数时,他所取得四个CPU之中的每一个CPU,都有可能要跟其他程式以分时方式(timesharing)共用一个CPU。HPSPP2000和SGIORIGIN2000为共用记忆体并行系统,这种电脑系统是16颗CPU共用一组记忆体。SP2和VPP300是属于分散式记忆体并行系统,每一个CPU备有它独用的记忆体。IBMSP2SMP及IBMp690是共用记忆体及分散式记忆体混合的并行系统,SP2SMP每一个node备有4颗CPU共用一组记忆体,目前备有42个node的SMPcluster。p690每一个node备有32颗CPU共用一组记忆体,目前备有8个node的SMPcluster。SP2、SP2SMP和p690是采用该系统专属的工作排程软体(jobscheduler)LoadLeveler来安排用户的批次工作(batchjob)。使用者必须备妥LoadLeveler的jobcommandfile,使用llsubmit指令把该批次工作交给该系统来执行。SPP2000、ORIGIN2000和VPP300是采用NQS(NetworkQueueSystem)工作排程软体来安排用户的批次工作。使用者必须备妥NQS的jobcommandfile,使用qsub指令把该批次工作交给各该系统来执行。PCcluster是采用DQS(DistributedQueueSystem)工作排程软体来安排用户的批次工作,其使用方式类似NQS。1.3在IBM电脑系统上如何使用MPI首先,Cshell用户要在自己homedirectory的.cshrc档里加入下列路径,这样才能够抓得到includefile(mpif.h、mpif90.h、mpi.h)、编译指令(mpxlf、mpxlf90、mpcc)、MPIlibrary、和LoadLeveler指令(llsubmit、llq、llstatus、llcancel)。setlpath=(.~/usr/lpp/ppe.poe/include/usr/lpp/ppe.poe/lib)setlpath=($lpath/usr/lpp/ppe.poe/bin/home/loadl/bin)setpath=($path$lpath)加好上述路径之后,将.cshrc存档,再执行source.cshrc指令,即可进行并行程式的编译与执行。签退(logout)后再签到(login)之后就不必再执行source.cshrc指令。1.3.1IBM电脑系统的MPIFortran程式编译指令使用MPI的Fortran77并行程式,其编译器(compiler)一般叫做mpif77,但是在IBM电脑系统上却叫做mpxlf。mpxlf常用的编译选项如下:mpxlf-O3-qarch=auto-qstrict-ofile.xfile.f其中选项-O3 是作最高级的最佳化(level3Optimization),可使程式的 计算速度加快数倍-qarch=auto 是通知编译器该程式要在同型机器上执行-qstrict 是通知编译器不要改变计算的顺序-ofile.x 是指定执行档名为file.x,不指定时其内定(default)档名为a.out1.3.2IBM电脑系统的Jobcommandfile要在IBMSP2(ivy)上执行并行程式,使用者必须备妥LoadLeveler的jobcommandfile。例如,下面这个jobcommandfile叫做jobp4,它要在四个CPU上执行并行程式file.x。#!/bin/csh#@executable=/usr/bin/poe#@arguments=/your_working_directory/file.x–euilibus#@output=outp4#@error=outp4#@job_type=parallel#@class=medium#@min_processors=4#@max_processors=4#@requirements=(Adapter=="hps_user")#@wall_clock_limit=20#@queue其中executable =/usr/bin/poe是固定不变,poe是指ParallelOperatingEnvironmentarguments =执行档所在之全路径及档名output =标准输出档名(stdout)error =错误讯息(errormessage)输出档名class =SP2CPU的分组别,使用llclass指令可以看到分组别:short (CPU时间上限为12小时,共有10颗120MHzCPU)medium (CPU时间上限为24小时,共有64颗160MHzCPU)long (CPU时间上限为96小时,共有24颗120MHzCPU)min_processors=最少的CPU数目max_processors=最多的CPU数目requirements=(Adapter=="hps_user")是固定不变wall_clock_limit=该job最多需要的时间,单位为分钟queue是固定不变并行计算可以使用的CPU数目,shortclass最多4个CPU,mediumclass最多32个CPU,longclass最多8个CPU。由于MPI1.2版不具备取得CPU、控制CPU、和归还CPU的功能,所以min_processors和max_processors要填相同的数字。要在IBMSP2SMP(ivory)上执行并行程式,使用者必须备妥LoadLeveler的jobcommandfile。例如,下面这个jobcommandfile叫做jobp4,它要在四个CPU上执行并行程式file.x。#!/bin/csh#@network.mpi=css0,shared,us#@executable=/usr/bin/poe#@arguments=/your_working_directory/file.x–euilibus#@output=outp4#@error=outp4#@job_type=parallel#@class=medium#@tasks_per_node=4#@node=1#@queue由于IBMSP2SMP每个Node含有四棵375MHzCPU共用4GB或8GB的记忆体。class =SP2SMPCPU的分组别,使用llclass指令可以看到分组别:short (CPU时间上限为12小时,3个Node共有6颗CPU)medium (CPU时间上限为24小时,32个Node共有128颗CPU)bigmem (CPU时间上限为48小时,4个Node共有16颗CPU) 这个class一个Node备有8GB的共用记忆体 tasks_per_node=4 是说明一个Node选用四棵CPU node=1 是说明要用一个Node,一共四棵CPU并行计算可以使用的CPU数目mediumclass是8个Node一共32颗CPU。要在IBMp690上执行并行程式,使用者必须备妥LoadLeveler的jobcommandfile。例如,下面这个jobcommandfile叫做jobp8,它要在8个CPU上执行并行程式file.x。#!/bin/csh#@executable=/usr/bin/poe#@network.mpi=csss,shared,us#@arguments=/your-working-directory/file.x#@output=outp8#@error=outp8#@job_type=parallel#@class=8cpu#@tasks_per_node=8#@node=1#@queue由于IBMp690每个Node含有32棵1.3GHzCPU共用128GB的记忆体。class =p690CPU的分组别,使用llclass指令可以看到分组别:32cpu (CPU时间上限为36小时,2个Node共有64颗CPU)16cpu (CPU时间上限为72小时,1个Node共有32颗CPU)8cpu (CPU时间上限为72小时,6个Node共有188颗CPU)4cpu (CPU时间上限为96小时,6个Node共有188颗CPU) serial (CPU时间上限为168小时,1个Node共有32颗CPU) tasks_per_node=8 是说明一个Node选用8棵CPU node=1 是说明要用一个Node,一共8棵CPU1.3.3IBM电脑系统的并行程式的执行指令要在IBM电脑系统上执行并行程式,使用者在备妥LoadLeveler的jobcommandfile之后,就可以使用llsubmit指令将该jobcommandfile交给该系统排队等候执行。例如上一节的jobcommandfile例子jobp4即可用下述指令交付执行:llsubmitjobp4工作交付之后,该工作执行的情形可用llq指令查询。要缩小查询的范围可在llq指令之后加上grep指令叙明要查询的class或userid。例如上一个例子jobp4所选用的分组别为medium,就可用下述指令进行查询:llq|grepmedium llq显示之内容有下列事项:job_iduser_idsubmittedstatuspriorityclass runningon ivy1.1781.0u43ycc008/1311:24R50mediumivy39ivy1.1814.0u50pao008/1320:12R50short ivy35其中job_id 是LoadLeveler给交付的工作编定的工作代号user_id 是使用者的loginnamesubmitted 是交付工作的时刻,月/日时:分status 是工作执行的情形 R表Running I表Idle(=waitinginqueue) ST表Startexecution NQ表NotQueued,还在队伍之外Priority 是交付工作的优先次序,不用更动它Class 是CPU分组别Runningon 是执行交付工作的第一个CPU代号工作交付执行之后,如果要中止该工作的执行可用llcancel指令杀掉该工作。llcanceljob_id 此处的job_id就是使用llq指令所显示之使用者交付工作的工作代号。执行过llcancel指令之后,再使用llq指令就可以看出该工作已经消失不见了。1.4在PCCluster上如何使用MPI首先,使用MPICH的Cshell用户要在自己homedirectory的.cshrc档里加入下列路径,这样才能够抓得到includefile(mpif.h、mpi.h)、编译指令(mpif77、mpicc)、MPIlibrary、和DQS指令。不同的PCCluster这些存放的路径可能不同,要向该系统的管理人询问。其路径设定如下:setenvPGI/usr/local/pgisetpath=(.~/usr/local/pgi/linux86/bin$path)setpath=(/package/DQS_hpcserv2/bin$path)setpath=(/package/mpich_hpcserv2/bin$path)其中第一行是PGI公司(PortlandGroupInc.)软体存放的路径,第二行是PGI公司Fortran77编译器pgf77存放的路径,第三行是DQS批次工作排程软体存放的路径,第四行是MPICH编译系统存放的路径。没有购用PGI公司的软体时前面两行可以省略。1.4.1PCCluster上的MPIFortran程式编译指令MPICH的Fortran77并行程式编译器叫做mpif77,其底层是使用GNU的g77来编译,因此可以使用g77的调适选项。举例如下:mpif77-O3-ofile.xfile.f其中选项-O3 是选用g77最高层次的调适选项-ofile.x 是指定编译产生的执行档为file.x 没有指定时,内定的执行档为a.outfile.f 是Fortran77并行程式如果选用PGI公司的MPI并行程式编译器mpif77,其底层是使用该公司的pgf77来编译,因此可以使用pgf77及pgf90的调适选项。其makefile举例如下:OBJ=file.oEXE=file.xMPI=/home/package/mpich_PGILIB=$(MPI)/lib/LINUX/ch_p4LFLAG=-L$(LIB)-lfmpichMPIF77=$(MPI)/bin/mpif77OPT=-O2-I$(MPI)/include$(EXE):$(OBJ)$(MPIF77)$(LFLAG)-o$(EXE)$(OBJ)$(LIB).f.o:$(MPIF77)$(OPT)-c$<备妥makefile之后,只要下make指令就会开始程式的编译工作。1.4.2PCCluster上的Jobcommandfile如果该PCcluster是采用DQS排程软体来安排批次工作时,要在其上执行并行程式,使用者必须备妥DQS的jobcommandfile。例如,下面这个jobcommandfile叫做jobp4,它要在四个CPU上执行并行程式hubksp:#!/bin/csh#$-lqty.eq.4#$-NHUP4#$-Auser_id#$-cwd#$-jycat$HOSTS_FILE>MPI_HOSTmpirun-np4-machinefileMPI_HOSThubksp>&outp4其中#!/bin/csh 是说明这是个Cshellscript#$-lqty.eq.4 是向DQS要求四个CPU,qty是数量(quantity)#$-NHUP4 是说明这个工作的名字(Name)叫做HUP4#$-Auser_id是说明付费帐号(Account)就是使用者帐号#$-cwd 是说明要在现在这个路径(workingdirectory)上执行程式 内定的路径是homedirectory#$-jy 是说明错误讯息要输出到标准输出档$HOST_FILE 是DQS安排给这项工作的nodelist-np4hubksp 是告诉mpirun要在四个CPU上执行并行程式hubksp>&outp4 是要把标准输出档写入outp41.4.3PCCluster上的并行程式执行指令要在PCcluster上执行并行程式,使用者在备妥DQS的jobcommandfile之后,就可以使用qsub32指令将该jobcommandfile交给PCcluster排队等候执行。例如上一节的jobcommandfile例子jobp4即可用下述指令交付执行:qsub32jobp4工作交付之后,可以使用qstat32指令(不加参数)查询整个cluster交付工作执行的情形,使用qstat32-f指令查询整个cluster各个node的状况。上述指令qsub32jobp4之后使用qstat32指令显示的内容如下:c00tch00HUP4hpcs001620:1rRUNNING02/26/9910:51:23c00tch00HUP4hpcs002620:1rRUNNING02/26/9910:51:23c00tch00HUP4hpcs003620:1rRUNNING02/26/9910:51:23c00tch00HUP4hpcs004620:1rRUNNING02/26/9910:51:23PendingJobsc00tch00RAD5700:2QUEUED02/26/9919:24:32第一栏是user_id,第二栏是交付工作的名称,第三栏是CPU代号,第四栏是DQS替交付的工作编定的工作编号job_id(62),第五栏0:1的0是交付工作的优先序号,0:1的1是该用户交付的第一个工作,第六栏的r和第七栏的RUNNING表示该工作正在执行中,最后是该工作交付时的时刻,月/日/年时:分:秒。排队等待执行的工作则出现在PendingJobs之列,对应RUNNING的栏位则为QUEUED。工作交付执行之后,如果要中止该工作的执行可用qdel32指令杀掉该工作。Qdel32job_id此处的job_id就是使用qstat32指令所显示之第四栏。执行过qdel32指令之后,再使用qstat32指令就可以看出该工作已经消失不见了。第二章无边界资料交换的并行程式最简单的并行程式就是无边界资料交换的并行程式。本章将利用一个很简单的循序程式(sequentialprogram)使用MPI指令加以并行化,并比较其计算结果以资验证。2.1节介绍六个MPI基本指令MPI_INIT、MPI_FINALIZE、MPI_COMM_SIZE、MPI_COMM_RANK、MPI_SEND、MPI_RECV。2.2节介绍无边界资料交换的循序程式T2SEQ。2.3节说明使用这六个MPI基本指令并行化循序程式T2SEQ而成为并行程式T2CP。2.4节介绍另外四个常用的MPI指令MPI_SCATTER、MPI_GATHER、MPI_REDUCE、MPI_ALLREDUCE。2.5节是使用这些指令并行化循序程式T2SEQ而成为并行程式T2DCP。2.1MPI基本指令MPI的基本指令有下列六个,将于本节分段加以介绍。MPI_INIT,MPI_FINALIZE,MPI_COMM_SIZE,MPI_COMM_RANK,MPI_SEND,MPI_RECV2.1.1mpif.hincludefile使用MPI撰写Fortran并行程式时,必须在每一个程式(包括主程式和副程式)的宣告段落里加上INCLUDE'mpif.h'陈述(statement)。mpif.h档案里含有编译MPI并行程式所必须的MPI字汇与MPI常数(constant)。例如:PROGRAMDRIVERIMPLICITREAL*8...INCLUDE'mpif.h'...CALLCHEF(...)...STOPENDSUBROUTINECHEF(...)IMPLICITREAL*8...INCLUDE'mpif.h'......RETURNEND读者可以在MPI软体所在之路径里查看mpif.h的内容。不同厂商设定的MPI常数也许不尽相同,但是所使用的MPI字汇则是完全一致。2.1.2MPI_INIT,MPI_FINALIZE在叫用(CALL)其他MPI函数或副程式之前必须先叫用MPI_INIT副程式,来启动该程式在多个CPU上的并行计算工作。在程式结束(STOP)之前必须叫用MPI_FINALIZE副程式,以结束并行计算工作。所以MPI_INIT和MPI_FINALIZE在主程式里只要叫用一次就够了,例如:PROGRAMT2CPPARAMETER(..)INCLUDE'mpif.h'REAL*8...INTEGER...CALLMPI_INIT(IERR)...CALLMPI_FINALIZE(IERR)STOPEND所有MPI副程式引数(argument)的资料类别除了资料名称之外,其余的都是整数(integer),传回的引数IERR其值为零时是正常结束,否则就有错误发生。2.1.3MPI_COMM_SIZE,MPI_COMM_RANK通常在叫用过MPI_INIT之后,就必须叫用MPI_COMM_SIZE以得知参与并行计算的CPU个数(NPROC),及叫用MPI_COMM_RANK以得知我是第几个CPU(MYID),第几个CPU是从0开始起算。所以第一个CPU的MYID值为零,第二个CPU的MYID值为1,第三个CPU的MYID值为2,余类推。通常要在几个CPU上作并行计算是在下执行命令时决定的,而不是在程式里事先设定。当然,使用者也可以在程式里事先设定要在几个CPU上作并行计算,其意义只供程式人员做参考,实际上使用几个CPU作并行计算是根据jobcommandfile里min_processors和max_processors的设定值,或-np的设定值。MPI_COMM_SIZE和MPI_COMM_RANK的叫用格式如下:CALLMPI_COMM_SIZE(MPI_COMM_WORLD,NPROC,IERR)CALLMPI_COMM_RANK(MPI_COMM_WORLD,MYID,IERR)引数MPI_COMM_WORLD是MPI内定的(default)communicator,参与该程式并行计算的全部CPU都是属于同一个communicator。属于同一个communicator的各个CPU之间才可以传送资料。MPI1.2版不具备CPU的取得与控制功能,参与并行计算的CPU颗数从程式开始执行到程式结束都是固定不变的。因此,这两个MPI副程式在一个程式里只要叫用一次就可以了。例如:PROGRAMT2CPPARAMETER(..)INCLUDE'mpif.h'REAL*8...INTEGERNPROC,MYIDCALLMPI_INIT(IERR)CALLMPI_COMM_SIZE(MPI_COMM_WORLD,NPROC,IERR)CALLMPI_COMM_RANK(MPI_COMM_WORLD,MYID,IERR)...CALLMPI_FINALIZE(IERR)STOPEND2.1.4MPI_SEND,MPI_RECV参与并行计算的各个CPU之间的资料传送方式有两种,一种叫做'点对点通讯'(pointtopointcommunication),另外一种叫做'集体通讯'(collectivecommunication)。此处先介绍'点对点通讯'类的MPI_SEND和MPI_RECV,其他常用的'点对点通讯'及'集体通讯'指令容后再介绍。一个CPU与另外一个CPU之间的资料传送属于'点对点通讯',送出资料的CPU要叫用MPI_SEND来送资料,而收受资料的CPU要叫用MPI_RECV来收资料。一个MPI_SEND必须要有一个对应的MPI_RECV与之配合,才能完成一份资料的传送工作。MPI_SEND的叫用格式如下:CALLMPI_SEND(DATA,ICOUNT,DATA_TYPE,IDEST,ITAG,&MPI_COMM_WORLD,IERR)引数DATA 要送出去的资料起点,可以是纯量(scalar)或阵列(array)资料ICOUNT 要送出去的资料数量,当ICOUNT的值大于一时,DATA必须是阵列DATA_TYPE 是要送出去的资料类别,MPI内定的资料类别如表1.1IDEST 是收受资料的CPUidITAG 要送出去的资料标签MPIdatatypesFortrandatatypesMPI_CHARACTERCHARACTERMPI_LOGICALLOGICALMPI_INTEGERINTEGERMPI_REAL,MPI_REAL4REAL,REAL*4MPI_REAL8,MPI_DOUBLE_PRECISIONREAL*8,DOUBLEPRECISIONMPI_COMPLEX,MPI_COMPLEX8COMPLEX,COMPLEX*8MPI_COMPLEX16,MPI_DOUBLE_COMPLEXCOMPLEX*16 表1.1MPIdatatypesMPI_RECV的叫用格式如下:CALLMPI_RECV(DATA,ICOUNT,DATA_TYPE,ISRC,ITAG,&MPI_COMM_WORLD,ISTATUS,IERR)引数DATA 是要收受的资料起点ICOUNT 是要收受的资料数量DATA_TYPE 是要收受的资料类别ISRC 是送出资料的CPUidITAG 是要收受的资料标签ISTATUS 是执行MPI_RECV副程式之后的状况ISTATUS为一整数阵列,该阵列的长度为在mpif.h里已经设定的常数MPI_STATUS_SIZE,写法如下INTEGERISTATUS(MPI_STATUS_SIZE)一个CPU同时要收受多个CPU送来的资料时,若不依照特定的顺序,而是先到先收,则其指令为CALLMPI_RECV(BUFF,ICOUNT,DATA_TYPE,MPI_ANY_SOURCE,ITAG,MPI_COMM_WORLD,ISTATUS,IERR)若要判别送出该资料的CPUid时就要用到ISTATUS变数如下ISRC=ISTATUS(MPI_SOURCE)MPI在传送资料(MPI_SEND、MPI_RECV)时,是以下列四项构成其'信封'(envelope),用以识别一件讯息(message)。1.送出资料的CPUid2.收受资料的CPUid3.资料标签4.communicator所以一个CPU送给另外一个CPU多种资料时,不同的资料要用不同的资料标签,以资识别。2.2无边界资料交换的循序程式T2SEQT2SEQ是个无边界资料交换的循序程式,在testdatageneration段落里设定阵列B、C、D的值,然后把这些阵列写到磁档上。其目的是便利往后的范例程式可以读入同一组资料作并行计算,用来验证其计算的结果是否正确。这个程式的计算部份只有一个DOloop,而且该loop里只有两个计算陈述,其目的是方便往后说明如何将这一类DOloop并行化。实际的计算程式也许有数百个或数千个DOloop,但是其并行化的方法是一样的。PROGRAMT2SEQPARAMETER(NTOTAL=200)REAL*8A(NTOTAL),B(NTOTAL),C(NTOTAL),D(NTOTAL),SUMACCtestdatagenerationandwritetofile'input.dat'CDOI=1,NTOTALB(I)=3.D0/DFLOAT(I)+1.0C(I)=2.D0/DFLOAT(I)+1.0D(I)=1.D0/DFLOAT(I)+1.0ENDDOOPEN(7,FILE='input.dat',FORM='UNFORMATTED')WRITE(7)BWRITE(7)CWRITE(7)DCLOSE(7)CCread'input.dat',computeandwriteouttheresultCOPEN(7,FILE='input.dat',STATUS='OLD',FORM='UNFORMATTED')READ(7)BREAD(7)CREAD(7)DSUMA=0.0DOI=1,NTOTALA(I)=B(I)+C(I)*D(I)SUMA=SUMA+A(I)ENDDOWRITE(*,101)(A(I),I=1,NTOTAL,5)101FORMAT(10F8.3)WRITE(*,102)SUMA102FORMAT('SUMofarrayA=',E15.5)STOPEND循序程式T2SEQ的测试结果如下:10.0003.0562.5622.3832.2902.2342.1962.1682.1482.1312.1182.1082.0992.0912.0852.0792.0742.0702.0662.0632.0602.0572.0542.0522.0502.0482.0462.0442.0432.0412.0402.0392.0372.0362.0352.0342.0332.0322.0312.031SUMofarrayA=.43855E+032.3资料不切割的并行程式T2CP并行程式的切割(decomposition/partition)方式有两种。一种是计算切割而资料不切割,另外一种是计算和资料都切割。前一种切割方式不能够节省记忆体的使用量是其缺点,但是阵列的描述与循序版(sequentialversion)完全相同,程式容易阅读也容易维护是其优点。后一种切割方式能够节省记忆体的使用量是其最大优点,但是阵列的描述与循序版差异较大,程式的阅读与维护比较困难是其缺点。如何将循序程式T2SEQ并行化呢?这一节先介绍'计算切割而资料不切割'的方法,2.5节再介绍'计算及资料同时切割'的方法。假如T2SEQ程式要在四个CPU上并行计算而资料不切割时,就把一维阵列A、B、C、D均分为四段,各个CPU负责计算其中的一段,分工合作完成整个计算工作。此处是利用一个STARTEND副程式来计算各个CPU负责计算段落的起迄index。它是把第一段分给CPU0,第二段分给CPU1,第三段分给CPU2,余类推。如图2.1所示:computingpartitionwithoutdatapartitionistartiendntotal|||cpu0●●●●●●○○○○○○○○○○○○○○○○○○istartiendntotal|||cpu1○○○○○○●●●●●●○○○○○○○○○○○○istartiendntotal|||cpu2○○○○○○○○○○○○●●●●●●○○○○○○istartiend||cpu3○○○○○○○○○○○○○○○○○○●●●●●●●arrayelementinsideterritory○arrayelementoutsideterritory图2.1计算切割而资料不切割的示意图图2.1里符号●代表辖区内的阵列元素,符号○代表辖区外的阵列元素,各个CPU负责计算的范围是从该CPU的istart到iend。由于MPI1.2版不具备并行输出入(ParallelI/O)的功能,所以输入资料由CPU0(MYID值为零)读入后,利用一个DOloop分段传送(MPI_SEND)给其他三个CPU,而其他三个CPU(MYID值大于零)则接收由CPU0送来给该CPU的阵列片段。请留意,传送不同的阵列片段要使用不同的资料标签(ITAG),每一个MPI_SEND一定有一个对应的MPI_RECV。每一个CPU算完自己负责的段落后,把计算的结果(阵列A的一部份)传送给CPU0,CPU0利用一个DOloop把其他三个CPU送来的阵列片段逐一接收下来。然后由CPU0单独计算整个A阵列各个元素的和SUMA,再把A阵列和SUMA列印出来。PROGRAMT2CPCCcomputingpartitionwithoutdatapartitionCINCLUDE'mpif.h'PARAMETER(NTOTAL=200)REAL*8A(NTOTAL),B(NTOTAL),C(NTOTAL),D(NTOTAL),SUMAINTEGERNPROC,MYID,ISTATUS(MPI_STATUS_SIZE),ISTART,IEND,1COMM,GCOUNT(0:31),GSTART(0:31),GEND(0:31)CALLMPI_INIT(IERR)CALLMPI_COMM_SIZE(MPI_COMM_WORLD,NPROC,IERR)CALLMPI_COMM_RANK(MPI_COMM_WORLD,MYID,IERR)CALLSTARTEND(NPROC,1,NTOTAL,GSTART,GEND,GCOUNT)ISTART=GSTART(MYID)IEND=GEND(MYID)PRINT*,'NPROC,MYID,ISTART,IEND=',NPROC,MYID,ISTART,IENDCOMM=MPI_COMM_WORLDCCReadinputdataanddistributedatatoeachprocessorCIF(MYID.EQ.0)THENOPEN(7,FILE='input.dat',STATUS='OLD',FORM='UNFORMATTED')READ(7)BREAD(7)CREAD(7)DDOIDEST=1,NPROC-1ISTART1=GSTART(IDEST)KOUNT1=GCOUNT(IDEST)CALLMPI_SEND(B(ISTART1),KOUNT1,MPI_REAL8,IDEST,&10,COMM,IERR)CALLMPI_SEND(C(ISTART1),KOUNT1,MPI_REAL8,IDEST,&20,COMM,IERR)CALLMPI_SEND(D(ISTART1),KOUNT1,MPI_REAL8,IDEST,&30,COMM,IERR)ENDDOELSEKOUNT=GCOUNT(MYID)ISRC=0CALLMPI_RECV(B(ISTART),KOUNT,MPI_REAL8,ISRC,10,1COMM,ISTATUS,IERR)CALLMPI_RECV(C(ISTART),KOUNT,MPI_REAL8,ISRC,20,1COMM,ISTATUS,IERR)CALLMPI_RECV(D(ISTART),KOUNT,MPI_REAL8,ISRC,30,1COMM,ISTATUS,IERR)ENDIFCCCompute,collectcomputedresultandwriteouttheresultCCCCDOI=1,NTOTALDOI=ISTART,IENDA(I)=B(I)+C(I)*D(I)ENDDOITAG=110IF(MYID.NE.0)THENKOUNT=GCOUNT(MYID)IDEST=0CALLMPI_SEND(A(ISTART),KOUNT,MPI_REAL8,IDEST,ITAG,&COMM,IERR)ELSEDOISRC=1,NPROC-1ISTART1=GSTART(ISRC)KOUNT1=GCOUNT(ISRC)CALLMPI_RECV(A(ISTART1),KOUNT1,MPI_REAL8,ISRC,ITAG,&COMM,ISTATUS,IERR)ENDDOENDIFIF(MYID.EQ.0)THENWRITE(*,101)(A(I),I=1,NTOTAL,5)SUMA=0.0DOI=1,NTOTALSUMA=SUMA+A(I)ENDDOWRITE(*,102)SUMAENDIF101FORMAT(10F8.3)102FORMAT('SUMofarrayA=',E15.5)CALLMPI_FINALIZE(IERR)STOPENDSUBROUTINESTARTEND(NPROC,IS1,IS2,GSTART,GEND,GCOUNT)INTEGERID,NPROC,IS1,IS2,GSTART(0:31),GEND(0:31),GCOUNT(0:31)LENG=IS2-IS1+1IBLOCK=LENG/NPROCIR=LENG-IBLOCK*NPROCDOI=0,NPROC-1IF(I.LT.IR)THENGSTART(I)=IS1+I*(IBLOCK+1)GEND(I)=GSTART(I)+IBLOCKELSEGSTART(I)=IS1+I*IBLOCK+IRGEND(I)=GSTART(I)+IBLOCK-1ENDIFIF(LENG.LT.1)THENGSTART(I)=1GEND(I)=0ENDIFGCOUNT(I)=GEND(I)-GSTART(I)+1ENDDOEND资料不切割并行程式T2CP的测试结果如下:ATTENTION:0031-4084nodesallocatedbyLoadLeveler,continuing...NPROC,MYID,ISTART,IEND=42101150NPROC,MYID,ISTART,IEND=4151100NPROC,MYID,ISTART,IEND=43151200NPROC,MYID,ISTART,IEND=4015010.0003.0562.5622.3832.2902.2342.1962.1682.1482.1312.1182.1082.0992.0912.0852.0792.0742.0702.0662.0632.0602.0572.0542.0522.0502.0482.0462.0442.0432.0412.0402.0392.0372.0362.0352.0342.0332.0322.0312.031SUMofarrayA=.43855E+03这一种并行程式的写法叫做SPMD(SingleProgramMultipleData)程式。这个程式在多颗CPU上并行时,每一颗CPU都是执行这一个程式,有些地方是用rank(MYID)来判断要执行条件陈述(IFstatement)里的那一个区段,有些地方是用不同的index起迄位置来执行DOloop的某一段落。没有使用index或rank来区分执行的段落部份,则每一颗CPU都要执行。所以T2CP程式里,每一颗CPU都会执行该程式一开始的下列陈述:CALLMPI_INIT(IERR)CALLMPI_COMM_SIZE(MPI_COMM_WORLD,NPROC,IERR)CALLMPI_COMM_RANK(MPI_COMM_WORLD,MYID,IERR)CALLSTARTEND(NPROC,1,NTOTAL,GSTART,GEND,GCOUNT)ISTART=GSTART(MYID)IEND=GEND(MYID)PRINT*,'NPROC,MYID,ISTART,IEND=',NPROC,MYID,ISTART,IEND虽然执行的陈述完全一样,但是每一个CPU得到的MYID值却不一样,所得到的ISTART和IEND也就随之而异,从所列印出来的结果可以得到印证。这样一个SPMD并行程式每一个CPU都有工作做。CPU0会多做资料的读和写的工作。但是一般计算程式资料输出入所占的时间比例很小,所以各个CPU的负载相当均匀,也没有masterCPU和slaveCPU的区别。2.4MPI_SCATTER,MPI_GATHER,MPI_REDUCEMPI_SCATTER、MPI_GATHER、MPI_ALLGATHER、MPI_REDUCE、MPI_ALLREDUCE都是属于'集体通讯'类副程式。这一类的资料传输,凡是属于同一个communicator的每一个CPU都要参与运作。所以使用这一种指令时,每一个CPU都必须叫用同一个副程式。2.4.1MPI_SCATTER,MPI_GATHERMPI_SCATTER的叫用格式如下:IROOT=0CALLMPI_SCATTER(T,N,MPI_REAL8,B,N,MPI_REAL8,&IROOT,MPI_COMM_WORLD,IERR)MPI_SCATTER是IROOTCPU把一个阵列T等分为NPROC段,(NPROC=参与并行计算的CPU数量),每一段资料长度为N,依CPUid的顺序分送给每一个CPU(包括IROOTCPU在内)。它是把第一段分给CPU0,第二段分给CPU1,第三段分给CPU2,余类推。如图2.2所示:CPU0TT1│T2│T3│T4 CPU0BT1CPU1SCATTER CPU1BT2─────>CPU2 CPU2BT3CPU3 CPU3BT4 图2.2MPI_SCATTER示意图请注意每一段资料必须等长。其引数依序为T 是待送出阵列的起点N 是送给每一个CPU的资料数量MPI_REAL8 是待送出资料的类别B 是接收资料存放的起点,如果N值大于一时,B必须是个阵列N 是接收资料的数量MPI_REAL8 是接收资料的类别IROOT 是送出资料的CPUidMPI_GATHER的叫用格式如下:IDEST=0CALLMPI_GATHER(A,N,MPI_REAL8,T,N,MPI_REAL8,&IDEST,MPI_COMM_WORLD,IERR)MPI_GATHER与MPI_SCATTER的动作刚好相反,是IDESTCPU收集每一个CPU送给它的阵列A,依CPUid的顺序存入阵列T里头。也就是从CPU0收到的N个阵列元素存入T阵列的第一段,从CPU1收到的N个阵列元素存入T阵列的第二段,从CPU2收到的N个阵列元素存入T阵列的第三段,余类推。如图2.3所示:CPU0TT1│T2│T3│T4 CPU0AT1CPU1GATHER CPU1AT2<─────CPU2 CPU2AT3CPU3 CPU3AT4 图2.3MPI_GATHER示意图请注意每一段资料必须等长。MPI_GATHER的引数依序为A 是待送出的资料起点,如果N值大于一时,A必须是个阵列N 是待送出资料的数量MPI_REAL8 是待送出资料的类别T 是接收资料存放的阵列起点N 是接收来自各个CPU的资料数量MPI_REAL8 是接收资料的类别IDEST 是收集资料的CPUidMPI_ALLGATHER的叫用格式如下:CALLMPI_ALLGATHER(A,N,MPI_REAL8,T,N,MPI_REAL8,&MPI_COMM_WORLD,IERR)MPI_ALLGATHER与MPI_GATHER的运作功能相似,MPI_GATHER是把运作的结果存入指定的一个CPU,而MPI_ALLGATHER则是把运作的结果存入每一个CPU。CPU0TT1│T2│T3│T4 CPU0AT1CPU1TT1│T2│T3│T4ALLGATHER CPU1AT2CPU2TT1│T2│T3│T4 CPU2AT3CPU3TT1│T2│T3│T4 CPU3AT4图2.4MPI_ALLGATHER示意图2.4.2MPI_REDUCE,MPI_ALLREDUCE另外一种集体资料传输功能叫作'缩减运作'(reductionoperation),例如把各个CPU算出来的部份和(partialsum)加总,或找出各个CPU上某一个变数的最大值或最小值。MPI_REDUCE运作的结果只存放在指定的CPU(IROOT)里,MPI_ALLREDUCE则是把运作的结果存放在每一个CPU里。MPI_REDUCE和MPI_ALLREDUCE叫用格式如下:IROOT=0CALLMPI_REDUCE(SUMA,SUMALL,KOUNT,MPI_REAL8,MPI_SUM,IROOT,&MPI_COMM_WORLD,IERR)CALLMPI_ALLREDUCE(SUMA,SUMALL,KOUNT,MPI_REAL8,MPI_SUM,&MPI_COMM_WORLD,IERR)引数SUMA 是待运作(累加)的变数SUMALL 是存放运作(累加)后的结果(把各个CPU上的SUMA加总)KOUNT 是待运作(累加)的资料个数MPI_REAL8 是SUMA和SUMALL的资料类别MPI_SUM 是运作涵数,可以选用的涵数如表2.1IROOT 是存放运作结果的CPU_idMPI指令OperationDatatypeMPI_SUMMPI_PRODsum累加product乘积MPI_INTEGER,MPI_REAL,MPI_REAL8,MPI_COMPLEX,MPI_COMPLEX16MPI_MAXMPI_MINmaximum最大值minimum最小值MPI_INTEGER,MPI_REAL,MPI_REAL8,MPI_DOUBLE_PRECISIONMPI_MAXLOCMPI_MINLOCmaxvalueandlocationminvalueandlocationMPI_2INTEGER,MPI_2REAL,MPI_2DOUBLE_PRECISIONMPI_LANDMPI_LORMPI_LXORlogicalANDlogicalORlogicalexclusiveORMPI_LOGICALMPI_BANDMPI_BORMPI_BXORbinaryANDbinaryORbinaryexclusiveORMPI_INTEGER,MPI_BYTE表2.1MPIReductionFunctionMPI_REDUCE的运作方式如图2.5所示,MPI_ALLREDUCE的运作方式如图2.6所示。CPU0SUMA0.2│1.5CPU0SUMALL1.7│3.5CPU1SUMA
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 单证员的实习报告四篇
- xx市城市公共空间功能提升项目可行性研究报告
- 2024年药品销售人员合同3篇
- 2024年某网络科技公司服务器采购安装合同
- 2024年河道护坡项目承揽协议样本一
- 关于童年的秘密读书心得体会5篇
- 棚户区现状分析
- 2024年楼梯踏步施工协议
- 2024年汽车租赁公司挂靠车辆租赁合同及客户权益保障范本3篇
- 2024年度智能语音识别软件定制委托开发合同3篇
- 体育与健康课一年级(水平一)课时教案全册
- 配电房施工组织设计方案(土建部分)
- 回流焊曲线讲解
- 国家开放大学电大专科《英语教学法》2023-2024期末试题及答案(试卷代号:2145)
- 事业单位领导班子考核测评表
- 一些常见物质的安托因常数
- (整理)变形测量作业指导细则
- 布莱恩厨具公司的资本结构分析
- 高速公路服务区工作计划总结与工作思路
- 集团子公司资金计划管理制度
- 幼儿园中班个人保教工作总结
评论
0/150
提交评论