This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
ey klm^_glh\ ZkibjZglh\ b gZmqguo khljm^gbdh\ qvy ^_yl_evghklv k\yaZgZkiZjZee_evgufb\uqbke_gbyfb
M>D ;;D– 018.2*32.973
Fhkdh\kdbc]hkm^Zjkl\_gguc mgb\_jkbl_l
ISBN 5-211-04907-1
2
Kh^_j`Zgb_
Bg^_dkihnmgdpbyf03,....................................................................................... 4 Hkgh\gu_ihgylby................................................................................................... 5 H[sb_ijhp_^mju03,........................................................................................... 8 AZ^Zgby................................................................................................................ 11 I_j_^ZqZijb_fkhh[s_gbcf_`^mhl^_evgufbijhp_kkZfb ......................... 11 I_j_^ZqZijb_fkhh[s_gbck[ehdbjh\dhc ................................................... 12 I_j_^ZqZijb_fkhh[s_gbc[_a[ehdbjh\db.................................................. 21 Hleh`_ggu_aZijhkugZ\aZbfh^_ckl\b_ ....................................................... 30 Lmibdh\u_kblmZpbbdeadlock) ....................................................................... 32 AZ^Zgby................................................................................................................ 34 Dhee_dlb\gu_\aZbfh^_ckl\byijhp_kkh\ ......................................................... 36 AZ^Zgby................................................................................................................ 47 =jmiiubdhffmgbdZlhju .................................................................................... 48 Hi_jZpbbk]jmiiZfbijhp_kkh\...................................................................... 48 Hi_jZpbbkdhffmgbdZlhjZfb ......................................................................... 52 AZ^Zgby................................................................................................................ 55
3
Bg^_dkihnmgdpbyf03, MPI_ADDRESS ................ 66 MPI_ALLGATHER .............. 42 MPI_ALLGATHERV ............. 42 MPI_ALLREDUCE .............. 45 MPI_ALLTOALL ............... 42 MPI_ALLTOALLV .............. 43 MPI_BARRIER ................ 36 MPI_BCAST .................. 38 MPI_BSEND .................. 14 MPI_BSEND_INIT ............. 30 MPI_BUFFER_ATTACH .......... 15 MPI_BUFFER_DETACH .......... 15 MPI_CART_COORDS ............ 58 MPI_CART_CREATE ............ 56 MPI_CART_GET ............... 59 MPI_CART_RANK .............. 58 MPI_CART_SHIFT ............. 59 MPI_CART_SUB ............... 58 MPI_CARTDIM_GET ............ 58 MPI_COMM_CREATE ............ 53 MPI_COMM_DUP ............... 53 MPI_COMM_FREE .............. 54 MPI_COMM_GROUP ............. 49 MPI_COMM_RANK ............... 9 MPI_COMM_SIZE ............... 9 MPI_COMM_SPLIT ............. 54 MPI_DIMS_CREATE ............ 57 MPI_FINALIZE ................ 8 MPI_GATHER ................. 39 MPI_GATHERV ................ 40 MPI_GET_COUNT .............. 19 MPI_GET_PROCESSOR_NAME ..... 10 MPI_GRAPH_CREATE ........... 60 MPI_GRAPH_GET .............. 61 MPI_GRAPH_NEIGHBORS ........ 61 MPI_GRAPH_NEIGHBORS_COUNT .. 61 MPI_GRAPHDIMS_GET .......... 61 MPI_GROUP_COMPARE .......... 51 MPI_GROUP_DIFFERENCE ....... 50 MPI_GROUP_EXCL ............. 49 MPI_GROUP_FREE ............. 51 MPI_GROUP_INCL ............. 49 MPI_GROUP_INTERSECTION ..... 50 MPI_GROUP_RANK ............. 50 MPI_GROUP_SIZE ............. 50 MPI_GROUP_TRANSLATE_RANKS .. 51 MPI_GROUP_UNION ............ 50 MPI_IBSEND ................. 23 MPI_INIT .................... 8 MPI_INITIALIZED ............. 9 MPI_IPROBE ................. 23
MPI_IRECV .................. 23 MPI_IRSEND ................. 23 MPI_ISEND .................. 22 MPI_ISSEND ................. 23 MPI_OP_CREATE .............. 46 MPI_OP_FREE ................ 46 MPI_PACK ................... 69 MPI_PACK_SIZE .............. 69 MPI_PROBE .................. 19 MPI_RECV ................... 16 MPI_RECV_INIT .............. 30 MPI_REDUCE ................. 43 MPI_REDUCE_SCATTER ......... 45 MPI_REQUEST_FREE ........... 31 MPI_RSEND .................. 14 MPI_RSEND_INIT ............. 30 MPI_SCAN ................... 46 MPI_SCATTER ................ 40 MPI_SCATTERV ............... 41 MPI_SEND ................... 12 MPI_SEND_INIT .............. 30 MPI_SENDRECV ............... 33 MPI_SENDRECV_REPLACE ....... 34 MPI_SSEND .................. 14 MPI_SSEND_INIT ............. 30 MPI_START .................. 31 MPI_STARTALL ............... 31 MPI_TEST ................... 27 MPI_TESTALL ................ 27 MPI_TESTANY ................ 27 MPI_TESTSOME ............... 28 MPI_TOPO_TEST .............. 56 MPI_TYPE_COMMIT ............ 66 MPI_TYPE_CONTIGUOUS ........ 64 MPI_TYPE_EXTENT ............ 67 MPI_TYPE_FREE .............. 66 MPI_TYPE_HINDEXED .......... 65 MPI_TYPE_HVECTOR ........... 65 MPI_TYPE_INDEXED ........... 65 MPI_TYPE_LB ................ 67 MPI_TYPE_SIZE .............. 66 MPI_TYPE_STRUCT ............ 65 MPI_TYPE_UB ................ 67 MPI_TYPE_VECTOR ............ 64 MPI_UNPACK ................. 69 MPI_WAIT ................... 23 MPI_WAITALL ................ 24 MPI_WAITANY ................ 25 MPI_WAITSOME ............... 25 MPI_WTICK .................. 10 MPI_WTIME .................. 10 4
Hkgh\gu_ihgylby GZb[he__jZkijhkljZg_gghcl_ogheh]b_cijh]jZffbjh\Zgby^eyiZjZee_evguo dhfivxl_jh\ k jZkij_^_e_gghc iZfylvx \ gZklhys__ \j_fy y\ey_lky 03, Hkgh\guf kihkh[hf \aZbfh^_ckl\by iZjZee_evguo ijhp_kkh\ \ lZdbo kbkl_fZoy\ey_lkyi_j_^ZqZkhh[s_gbc^jm]^jm]mWlhbhljZ`_gh\gZa\Zgbb ^Zgghc l_ogheh]bb — 0HVVDJH 3DVVLQJ ,QWHUIDFH bgl_jn_ck i_j_^Zqb khh[s_gbc KlZg^Zjl MPI nbdkbjm_l bgl_jn_ck dhlhjuc ^he`_g kh[ex^Zlvky dZd kbkl_fhc ijh]jZffbjh\Zgby gZ dZ`^hc \uqbkebl_evghc ieZlnhjf_lZdbihevah\Zl_e_fijbkha^Zgbbk\hboijh]jZffKh\j_f_ggu_ j_ZebaZpbb qZs_ \k_]hkhhl\_lkl\mxlklZg^Zjlm03,\_jkbb <— ]h^Zo ihy\beky klZg^Zjl 03,- agZqbl_evgh jZkrbjb\rbc nmgdpbhgZevghklvij_^u^ms_c\_jkbbH^gZdh^hkboihjwlhl\ZjbZglMPI g_ihemqberbjhdh]hjZkijhkljZg_gbyb\iheghfh[t_f_g_j_Zebah\Zggb gZ h^ghc kbkl_f_ <_a^_ ^Ze__ _keb bgh]h g_ h]h\hj_gh fu [m^_f bf_lv ^_ehkhklZg^ZjlhfMPI-1.1. 03, ih^^_j`b\Z_l jZ[hlm k yaudZfb NhjljZg b Kb < ^Zgghf ihkh[bb ijbf_jubhibkZgby\k_oijhp_^mj[m^ml^Zgukbkihevah\Zgb_fyaudZNhjljZg H^gZdh wlh kh\_jr_ggh g_ y\ey_lky ijbgpbibZevguf ihkdhevdm hkgh\gu_ b^_b 03, b ijZ\beZ hnhjfe_gby hl^_evguo dhgkljmdpbc ^ey wlbo yaudh\\hfgh]hfkoh`bIhegZy\_jkbybgl_jn_ckZkh^_j`blhibkZgb_[he__ ijhp_^mj b nmgdpbcGZrZaZ^ZqZ — h[tykgblvb^_xl_ogheh]bbb ihfhqv hk\hblv g_h[oh^bfu_ gZ ijZdlbd_ dhfihg_glu >hihegbl_evgmx bgnhjfZpbx h[ bgl_jn_ck_ MPI fh`gh gZclb gZ l_fZlbq_kdhc kljZgbp_ BgnhjfZpbhggh-ZgZeblbq_kdh]h p_gljZ ih iZjZee_evguf \uqbke_gbyf \ k_lbBgl_jg_lhttp://parallel.ru/tech/tech_dev/mpi.html. Bgl_jn_ck MPI ih^^_j`b\Z_l kha^Zgb_ iZjZee_evguo ijh]jZff \ klbe_ MIMD (Multiple Instruction Multiple Data qlh ih^jZamf_\Z_l h[t_^bg_gb_ ijhp_kkh\kjZaebqgufbbkoh^gufbl_dklZfbH^gZdhibkZlvbhleZ`b\Zlv lZdb_ijh]jZffuhq_gvkeh`ghihwlhfmgZijZdlbd_ijh]jZffbklu]hjZa^h qZs_bkihevamxlSPMD-fh^_evSingle Program Multiple Data)iZjZee_evgh]h ijh]jZffbjh\Zgby \ jZfdZo dhlhjhc ^ey \k_o iZjZee_evguo ijhp_kkh\ bkihevam_lkyh^bgblhl`_dh^<gZklhys__\j_fy\k_[hevr_b[hevr_j_ZebaZpbcMPIih^^_j`b\ZxljZ[hlmkgblyfb IhkdhevdmMPIy\ey_lky[b[ebhl_dhclhijbdhfibeypbbijh]jZffug_h[oh^bfh ijbebgdh\Zlv khhl\_lkl\mxsb_ [b[ebhl_qgu_ fh^meb Wlh fh`gh k^_eZlv\dhfZg^ghckljhd_beb\hkihevah\Zlvkyij_^mkfhlj_ggufb\[hevrbgkl\_ kbkl_f dhfZg^Zfb beb kdjbilZfb mpicc ^ey ijh]jZff gZ yaud_ Kb mpiCC^eyijh]jZffgZyaud_Kb bmpif77/mpif90^eyijh]jZffgZ yaudZoNhjljZg HipbydhfibeylhjZ³-o name´iha\hey_laZ^Zlvbfy 5
name^eyihemqZ_fh]h\uihegbfh]hnZceZihmfheqZgbx\uihegbfucnZce gZau\Z_lkya.outgZijbf_j mpif77 -o program program.f
Ihke_ ihemq_gby \uihegbfh]h nZceZ g_h[oh^bfh aZimklblv _]h gZ lj_[m_fhfdhebq_kl\_ijhp_kkhjh\>eywlh]hh[uqghij_^hklZ\ey_lkydhfZg^ZaZimkdZMPI-ijbeh`_gbcmpirungZijbf_j mpirun -np Nijh]jZffZkZj]mf_glZfb!,
]^_ N - qbkeh ijhp_kkh\ dhlhjh_ ^he`gh [ulv g_ [he__ jZaj_r_ggh]h \ ^Zgghckbkl_f_qbkeZijhp_kkh\^eyh^ghcaZ^ZqbIhke_aZimkdZh^gZblZ `_ijh]jZffZ[m^_l\uihegylvky\k_fbaZims_ggufbijhp_kkZfbj_amevlZl \uiheg_gby \ aZ\bkbfhklb hl kbkl_fu [m^_l \u^Z\Zlvky gZ l_jfbgZe beb aZibku\Zlvky\nZcekij_^hij_^_e_ggufbf_g_f
IjbklZjl_ijh]jZffu\k_]^ZkqblZ_lkyqlh\k_ihjh`^_ggu_ijhp_kkujZ[hlZxl \ jZfdZo \k_h[t_fexs_]h dhffmgbdZlhjZ bf_xs_]h ij_^hij_^_e_ggh_bfyMPI_COMM_WORLDWlhldhffmgbdZlhjkms_kl\m_l\k_]^Zbkem`bl ^ey \aZbfh^_ckl\by \k_o aZims_gguo ijhp_kkh\ MPI-ijh]jZffu Djhf_ g_]h ijb klZjl_ ijh]jZffu bf__lky dhffmgbdZlhj MPI_COMM_SELF, kh^_j`Zsbc lhevdh h^bg l_dmsbc ijhp_kk Z lZd`_ dhffmgbdZlhj MPI_COMM_NULL g_ kh^_j`Zsbc gb h^gh]h ijhp_kkZ
7
H[sb_ijhp_^mju03, <^ZgghfjZa^_e_fuhklZgh\bfkygZh[sboijhp_^mjZoMPIg_k\yaZgguok i_j_kuedhc ^Zgguo ;hevrbgkl\h ijhp_^mj wlh]h jZa^_eZ g_h[oh^bfu ijZdlbq_kdb\dZ`^hckh^_j`Zl_evghciZjZee_evghcijh]jZff_ MPI_INIT(IERR) INTEGER IERR
BgbpbZebaZpbyiZjZee_evghcqZklbijh]jZffu
AZ\_jr_gb_iZjZee_evghcqZklbijbeh`_gby
< aZ\bkbfhklb hl j_ZebaZpbb MPI kljhqdb ‘Before MPI_INIT’ b ‘After MPI_FINALIZE’fh`_li_qZlZlveb[hh^bg\u^_e_ggucijhp_kkeb[h\k_aZims_ggu_ijhp_kkuijbeh`_gbyKljhqdm ‘Parallel section’^he`gugZi_qZlZlv \k_ ijhp_kku Ihjy^hd \u\h^Z kljhd k jZaguo ijhp_kkh\ fh`_l [ulvijhba\hevguf H[sZy ko_fZ 03,-ijh]jZffu gZ yaud_ Kb \u]ey^bl ijbf_jgh ke_^mxsbf h[jZahf
8
#include “mpi.h” main(int argc, char **argv) { … MPI_Init(&argc, &argv); … MPI_Finalize(); … }
>jm]b_iZjZee_evgu_ijh]jZffugZyaud_Kbkbkihevah\Zgb_fl_ogheh]bb MPI fh`gh gZclb gZijbf_j \
Ijhp_^mjZ \ha\jZsZ_l \ Zj]mf_gl_ FLAG agZq_gb_ .TRUE. _keb \ua\ZgZ ba iZjZee_evghcqZklbijbeh`_gbybagZq_gb_ .FALSE. -\ijhlb\ghfkemqZ_ Wlh _^bgkl\_ggZy ijhp_^mjZ 03, dhlhjmx fh`gh \ua\Zlv ^h \uah\Z MPI_INIT. MPI_COMM_SIZE(COMM, SIZE, IERR) INTEGER COMM, SIZE, IERR < Zj]mf_gl_ SIZE ijhp_^mjZ \ha\jZsZ_l qbkeh iZjZee_evguo ijhp_kkh\ \ dhffmgbdZlhj_COMM. MPI_COMM_RANK(COMM, RANK, IERR) INTEGER COMM, RANK, IERR < Zj]mf_gl_ RANK ijhp_^mjZ \ha\jZsZ_l ghf_j ijhp_kkZ \ dhffmgbdZlhj_ COMM ?keb ijhp_^mjZ MPI_COMM_SIZE ^ey lh]h `_ dhffmgbdZlhjZ COMM \_jgmeZ agZq_gb_ SIZE lh agZq_gb_ \ha\jZsZ_fh_ ijhp_^mjhc MPI_COMM_RANKq_j_ai_j_f_ggmxRANKe_`bl\^bZiZahg_hl0^hSIZE-1.
<ke_^mxs_fijbf_j_dZ`^ucaZims_ggucijhp_kki_qZlZ_lk\hcmgbdZevguc ghf_j \ dhffmgbdZlhj_ MPI_COMM_WORLD b qbkeh ijhp_kkh\ \ ^Zgghf dhffmgbdZlhj_ program example2 include ‘mpif.h’ integer ierr, size, rank call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) print *, ‘process ’, rank, ‘, size ’, size call MPI_FINALIZE(ierr) end
9
KljhdZ khhl\_lkl\mxsZy \uah\m ijhp_^mju print[m^_l\u\_^_gZklhevdh jZa kdhevdh ijhp_kkh\ [ueh ihjh`^_gh ijb aZimkd_ ijh]jZffu Ihjy^hd ihy\e_gbykljhdaZjZg__g_hij_^_e_gbfh`_l[ulv\hh[s_]h\hjyex[uf =ZjZglbjm_lkylhevdhlhqlhkh^_j`bfh_hl^_evguokljhdg_[m^_li_j_f_rZgh^jm]k^jm]hf DOUBLE PRECISION MPI_WTIME(IERR) INTEGER IERR
WlZ nmgdpby \ha\jZsZ_l gZ \ua\Z\r_f ijhp_kk_ Zkljhghfbq_kdh_ \j_fy \ k_dmg^Zo\_s_kl\_ggh_qbkeh^\hcghclhqghklb ijhr_^r__kg_dhlhjh]h fhf_glZ\ijhrehf?kebg_dhlhjucmqZklhdijh]jZffuhdjm`blv\uah\Zfb ^ZgghcnmgdpbblhjZaghklv\ha\jZsZ_fuoagZq_gbcihdZ`_l\j_fyjZ[hlu ^Zggh]h mqZkldZ =ZjZglbjm_lky qlh fhf_gl \j_f_gb bkihevam_fuc \ dZq_kl\_lhqdbhlkq_lZg_[m^_lbaf_g_gaZ\j_fykms_kl\h\Zgbyijhp_kkZ AZf_lbf qlh wlZ nmgdpby \ha\jZsZ_l j_amevlZl k\h_c jZ[hlu g_ q_j_a iZjZf_lju Z y\guf h[jZahf LZcf_ju jZaguo ijhp_kkhjh\ fh]ml [ulv g_ kbgojhgbabjh\Zgub\u^Z\ZlvjZaebqgu_agZq_gbywlhfh`ghhij_^_eblvih agZq_gbxiZjZf_ljZMPI_WTIME_IS_GLOBAL (1 –kbgojhgbabjh\Zgu0 -g_l DOUBLE PRECISION MPI_WTICK(IERR) INTEGER IERR
Nmgdpby\ha\jZsZ_ljZaj_r_gb_lZcf_jZgZ\ua\Z\r_fijhp_kk_\k_dmg^Zo WlZnmgdpbylZd`_\ha\jZsZ_lj_amevlZlk\h_cjZ[hlug_q_j_aiZjZf_ljuZ y\gufh[jZahf MPI_GET_PROCESSOR_NAME(NAME, LEN, IERR) CHARACTER*(*) NAME INTEGER LEN, IERR Ijhp_^mjZ\ha\jZsZ_l\kljhd_ NAMEbfymaeZgZdhlhjhfaZims_g\ua\Z\rbcijhp_kk<i_j_f_gghcLEN\ha\jZsZ_lkydhebq_kl\hkbf\heh\\bf_gb g_ ij_\urZxs__ agZq_gby dhgklZglu MPI_MAX_PROCESSOR_NAME K
ihfhsvx wlhc ijhp_^mju fh`gh hij_^_eblv gZ dZdb_ bf_ggh nbabq_kdb_ ijhp_kkhju[uebkieZgbjh\Zguijhp_kkuMPI-ijbeh`_gby
< ke_^mxs_c ijh]jZff_ gZ dZ`^hf ijhp_kk_ hij_^_eyxlky ^\_ oZjZdl_jbklbdbkbkl_fgh]hlZcf_jZ_]hjZaj_r_gb_b\j_fylj_[m_fh_gZaZf_j\j_f_gb ^ey mkj_^g_gby ihemqZ_fh]h agZq_gby \uihegy_lky NTIMES aZf_jh\ LZd`_ \ ^Zgghf ijbf_j_ ihdZaZgh bkihevah\Zgb_ ijhp_^mju MPI_GET_PROCESSOR_NAME.
10
program example3 include 'mpif.h' integer ierr, rank, len, i, NTIMES parameter (NTIMES = 100) character*(MPI_MAX_PROCESSOR_NAME) name double precision time_start, time_finish, tick call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_GET_PROCESSOR_NAME(name, len, ierr) tick = MPI_WTICK(ierr) time_start = MPI_WTIME(ierr) do i = 1, NTIMES time_finish = MPI_WTIME(ierr) end do call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) print *, 'processor ', name(1:len), & ', process ', rank, ': tick = ', tick, & ', time = ', (time_finish-time_start)/NTIMES call MPI_FINALIZE(ierr) end
AZ^Zgby • Hldhfibebjh\Zlvbijh\_jblvwnn_dlb\ghklv\uiheg_gbyijh]jZffu \uqbke_gby qbkeZ Ib gZ jZaebqghf qbke_ ijhp_kkhjh\ ijh]jZffZ h[uqgh\oh^bl\dZq_kl\_l_klh\h]hijbf_jZ\dhfie_dlihklZ\dbMPI b fh`_l gZoh^blvky gZijbf_j \ nZceZo /usr/local/examples/mpi/fpi.f beb cpi.c). • Fh`gh eb \ ijhp_kk_ jZ[hlu 03,-ijh]jZffu ihjh`^Zlv gh\u_ ijhp_kku_keb\dZdhc-lhfhf_glihy\bebkvk\h[h^gu_ijhp_kkhju" • Fh`_l eb 03,-ijh]jZffZ ijh^he`Zlv jZ[hlm ihke_ Z\Zjbcgh]h aZ\_jr_gbyh^gh]hbaijhp_kkh\" • Hij_^_eblvkdhevdhijhp_kkh\\uihegyxll_dklijh]jZffu^h\uah\Z ijhp_^mjuMPI_INITbihke_\uah\Zijhp_^mjuMPI_FINALIZE. • Hij_^_eblv kbgojhgbah\Zgu eb lZcf_ju jZaguo ijhp_kkh\ dhgdj_lghckbkl_fu
I_j_^ZqZijb_fkhh[s_gbcf_`^mhl^_evgufb ijhp_kkZfb IjZdlbq_kdb\k_ijh]jZffugZibkZggu_kbkihevah\Zgb_fdhffmgbdZpbhgghcl_ogheh]bbMPI^he`gukh^_j`Zlvkj_^kl\Zg_lhevdh^eyihjh`^_gby baZ\_jr_gbyiZjZee_evguoijhp_kkh\ghb^ey\aZbfh^_ckl\byaZims_gguo
11
ijhp_kkh\ f_`^m kh[hc LZdh_ \aZbfh^_ckl\b_ hkms_kl\ey_lky \ MPI ihkj_^kl\hfy\ghcihkuedbkhh[s_gbc
pbZebabjh\ZgZ khhl\_lkl\mxsZy ijhp_^mjZ ijb_fZ Ijb wlhf khh[s_gb_ fh`_l [ulv kdhibjh\Zgh dZd g_ihkj_^kl\_ggh \ [mn_j ijb_fZ lZd b ihf_s_gh\g_dhlhjuckbkl_fguc[mn_j_kebwlhij_^mkfhlj_gh\MPI AgZq_gb_ COUNT fh`_l[ulvgme_fIjhp_kkmjZaj_rZ_lkyi_j_^Z\Zlvkhh[s_gb_ 12
kZfhfmk_[_h^gZdhwlhg_[_ahiZkghbfh`_lijb\_klbd\hagbdgh\_gbxlmibdh\hckblmZpbbIZjZf_lj DATATYPEbf__l\yaud_NhjljZglbi INTEGER \yaud_Kb–ij_^hij_^_e_gguclbiMPI_Datatype Lbii_j_^Z\Z_fuowe_f_glh\ ^he`_g mdZau\Zlvky k ihfhsvx ij_^hij_^_e_gguo dhgklZgl lbiZ i_j_qbke_gguo^eyyaudZNhjljZg\ke_^mxs_clZ[ebp_ Lbi^Zgguo\MPI
Lbi^Zgguo\NhjljZg_
MPI_INTEGER MPI_REAL MPI_DOUBLE_PRECISION MPI_COMPLEX MPI_LOGICAL MPI_CHARACTER MPI_BYTE
INTEGER REAL DOUBLE PRECISION COMPLEX LOGICAL CHARACTER(1) [blbkihevam_lky^eyi_j_^Zqb g_lbibabjh\Zgguo^Zgguo lbi^eymiZdh\Zgguo^Zgguo
MPI_PACKED
?keb bkihevam_fuc k MPI [Zah\uc yaud bf__l ^hihegbl_evgu_ lbiu ^Zgguo lh khhl\_lkl\mxsb_ lbiu ^he`gu [ulv h[_ki_q_gu b \ MPI. Iheguc kibkhd ij_^hij_^_e_gguo bf_g lbih\ ^Zgguo i_j_qbke_g \ nZce_ mpif.h (mpi.h). Ijb i_j_kued_ khh[s_gbc fh`gh bkihevah\Zlv ki_pbZevgh_ agZq_gb_ MPI_PROC_NULL ^ey g_kms_kl\mxs_]h ijhp_kkZ Hi_jZpbb k lZdbf ijhp_kkhf aZ\_jrZxlky g_f_^e_ggh k dh^hf aZ\_jr_gby MPI_SUCCESS. GZijbf_j^eyi_j_kuedbkhh[s_gbyijhp_kkmkghf_jhfgZ_^bgbpm[hevr_ fh`gh\hkihevah\Zlvkyke_^mxsbfnjZ]f_glhf call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) next = rank+1 if(next .eq. size) next = MPI_PROC_NULL call MPI_SEND(buf, 1, MPI_REAL, next, & 5, MPI_COMM_WORLD, ierr)
<wlhfkemqZ_ijhp_kkkihke_^gbfghf_jhfg_hkms_kl\blgbdZdhcj_Zevghcihkuedb^ZgguoZkjZamihc^_l\uihegylvijh]jZffm^Zevr_ ;ehdbjh\dZ]ZjZglbjm_ldhjj_dlghklvih\lhjgh]hbkihevah\Zgby\k_oiZjZf_ljh\ ihke_ \ha\jZlZ ba ijhp_^mju Wlh hagZqZ_l qlh ihke_ \ha\jZlZ ba MPI_SEND fh`gh bkihevah\Zlv ex[u_ ijbkmlkl\mxsb_ \ \uah\_ ^Zgghc ijhp_^mju i_j_f_ggu_ [_a hiZk_gby bkihjlblv i_j_^Z\Z_fh_ khh[s_gb_
13
Ke_^m_lki_pbZevghhlf_lblvqlh\ha\jZlbaijhp_^mju MPI_SEND g_hagZqZ_lgblh]hqlhkhh[s_gb_ihemq_ghijhp_kkhf DESTgblh]hqlhkhh[s_gb_ihdbgmehijhp_kkhjgucwe_f_glgZdhlhjhf\uihegy_lkyijhp_kk\uihegb\rbc ^Zgguc \uah\ Ij_^hklZ\ey_lky lhevdh ]ZjZglby [_ahiZkgh]h baf_g_gby i_j_f_gguo bkihevah\Zgguo \ \uah\_ ^Zgghc ijhp_^mju Ih^h[gZy g_hij_^_e_gghklv ^Ze_dh g_ \k_]^Z mkljZb\Z_l ihevah\Zl_ey Qlh[u jZkrbjblv \hafh`ghklb i_j_^Zqb khh[s_gbc \ MPI \\_^_gu ^hihegbl_evgu_ ljb ijhp_^mju
14
Ihevah\Zl_ev^he`_ggZagZqblvgZihkueZxs_fijhp_kk_ki_pbZevgucfZkkb\dhlhjuc[m^_lbkihevah\Zlvky^ey[mn_jbaZpbbkhh[s_gbcijb\uah\_ ijhp_^mjuMPI_BSEND. MPI_BUFFER_ATTACH(BUF, SIZE, IERR)
s_gbc k [mn_jbaZpb_c < dZ`^hf ijhp_kk_ fh`_l [ulv lhevdh h^bg lZdhc [mn_j :kkhpbbjh\Zgguc k [mn_jhffZkkb\g_ke_^m_lbkihevah\Zlv\ijh]jZff_ ^ey ^jm]bo p_e_c JZaf_j fZkkb\Z \u^_ey_fh]h ^ey [mn_jbaZpbb ^he`_g ij_\hkoh^blv h[sbc jZaf_j khh[s_gby dZd fbgbfmf gZ \_ebqbgm hij_^_ey_fmxdhgklZglhcMPI_BSEND_OVERHEAD. MPI_BUFFER_DETACH(BUF, SIZE, IERR)
Hk\h[h`^_gb_\u^_e_ggh]h[mn_jgh]hfZkkb\Z^ey_]hbkihevah\Zgby\^jm]bop_eyoIjhp_^mjZ\ha\jZsZ_l\Zj]mf_glZoBUFbSIZEZ^j_kbjZaf_jhk\h[h`^Z_fh]h fZkkb\Z
15
program example4 include 'mpif.h' integer BUFSIZE parameter (BUFSIZE = 4 + MPI_BSEND_OVERHEAD) byte buf(BUFSIZE) integer rank, ierr, ibufsize, rbuf integer status(MPI_STATUS_SIZE) call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) if(rank .eq. 0) then call MPI_BUFFER_ATTACH(buf, BUFSIZE, ierr) call MPI_BSEND(rank, 1, MPI_INTEGER, 1, 5, & MPI_COMM_WORLD, ierr) call MPI_BUFFER_DETACH(buf, ibufsize, ierr) end if if(rank .eq. 1) then call MPI_RECV(rbuf, 1, MPI_INTEGER, 0, 5, & MPI_COMM_WORLD, status, ierr) print *, 'Process 1 received ', rbuf, ' from process ', & status(MPI_SOURCE) end if call MPI_FINALIZE(ierr) end MPI_RECV(BUF, COUNT, DATATYPE, SOURCE, MSGTAG, COMM, STATUS, IERR)
khhl\_lkl\mxsb_ we_f_glZf ijbgylh]h khh[s_gby ?keb dhebq_kl\h we_f_glh\\ijbgbfZ_fhfkhh[s_gbb[hevr_agZq_gby COUNTlh\hagbdZ_l hrb[dZ i_j_iheg_gby Qlh[u ba[_`Zlv wlh]h fh`gh kgZqZeZ hij_^_eblv kljmdlmjm ijboh^ys_]h khh[s_gby ijb ihfhsb ijhp_^mju MPI_PROBE (MPI_IPROBE ?keb gm`gh magZlv lhqgh_ qbkeh we_f_glh\ \ ijbgbfZ_fhf khh[s_gbb lh fh`gh \hkihevah\Zlvky ijhp_^mjhc MPI_GET_COUNT. ;ehdbjh\dZ ]ZjZglbjm_l qlh ihke_ \ha\jZlZ ba ijhp_^mju MPI_RECV \k_ we_f_glukhh[s_gbym`_[m^mlijbgylubjZkiheh`_gu\[mn_j_BUF. Gb`_ijb\_^_gijbf_jijh]jZffu\dhlhjhcgme_\hcijhp_kkihkueZ_lkhh[s_gb_ ijhp_kkm k ghf_jhf h^bg b `^_l hl g_]h hl\_lZ ?keb ijh]jZffZ [m^_l aZims_gZ k [hevrbf qbkehf ijhp_kkh\ lh j_Zevgh \uihegylv i_j_kuedb\k_jZ\ghklZgmllhevdhgme_\hcbi_j\ucijhp_kkuHklZevgu_ijhp_kkuihke_bobgbpbZebaZpbbijhp_^mjhc MPI_INITgZi_qZlZxlgZqZevgu_ 16
agZq_gby i_j_f_gguo a b b ihke_ q_]h aZ\_jrZlky \uihegb\ ijhp_^mjm MPI_FINALIZE. program example5 include 'mpif.h' integer ierr, size, rank real a, b integer status(MPI_STATUS_SIZE) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) a = 0.0 b = 0.0 if(rank .eq. 0) then b = 1.0 call MPI_SEND(b, 1, MPI_REAL, 1, 5, & MPI_COMM_WORLD, ierr); call MPI_RECV(a, 1, MPI_REAL, 1, 5, & MPI_COMM_WORLD, status, ierr); else if(rank .eq. 1) then a = 2.0 call MPI_RECV(b, 1, MPI_REAL, 0, 5, & MPI_COMM_WORLD, status, ierr); call MPI_SEND(a, 1, MPI_REAL, 0, 5, & MPI_COMM_WORLD, ierr); end if end if print *, 'process ', rank,' a = ', a, ', b = ', b call MPI_FINALIZE(ierr) end
<ke_^mxs_fijbf_j_dZ`^ucijhp_kkkq_lgufghf_jhfihkueZ_lkhh[s_gb_ k\h_fm khk_^m k ghf_jhf gZ _^bgbpm [hevrbf >hihegbl_evgh ihklZ\e_gZ ijh\_jdZ ^ey ijhp_kkZ k fZdkbfZevguf ghf_jhf qlh[u hg g_ ihkeZe khh[s_gb_ g_kms_kl\mxs_fm ijhp_kkm AgZq_gby i_j_f_gghc b baf_gylky lhevdhgZijhp_kkZokg_q_lgufbghf_jZfb program example6 include 'mpif.h' integer ierr, size, rank, a, b integer status(MPI_STATUS_SIZE) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) a = rank b = -1 if(mod(rank, 2) .eq. 0) then if(rank+1 .lt. size) then &ihkueZxl\k_ijhp_kkudjhf_ihke_^g_]h call MPI_Send(a, 1, MPI_INTEGER, rank+1, 5, 17
&
MPI_COMM_WORLD, ierr);
end if else call MPI_Recv(b, 1, MPI_INTEGER, rank-1, 5, & MPI_COMM_WORLD, status, ierr); end if print *, 'process ', rank,' a = ', a, ', b = ', b call MPI_FINALIZE(ierr) end
Ijbijb_f_khh[s_gby\f_klhZj]mf_glh\ SOURCEb MSGTAGfh`ghbkihevah\Zlvke_^mxsb_ij_^hij_^_e_ggu_dhgklZglu • MPI_ANY_SOURCE — ijbagZd lh]h qlh ih^oh^bl khh[s_gb_ hl ex[h]h ijhp_kkZ • MPI_ANY_TAG — ijbagZd lh]h qlh ih^oh^bl khh[s_gb_ k ex[uf b^_glbnbdZlhjhf Ijbh^gh\j_f_gghfbkihevah\Zgbbwlbo^\modhgklZgl[m^_lijbgylhkhh[s_gb_kex[ufb^_glbnbdZlhjhfhlex[h]hijhp_kkZ J_Zevgu_ Zljb[mlu ijbgylh]h khh[s_gby \k_]^Z fh`gh hij_^_eblv ih khhl\_lkl\mxsbf we_f_glZf fZkkb\Z status < NhjljZg_ iZjZf_lj status y\ey_lky p_ehqbke_gguf fZkkb\hf jZaf_jZ MPI_STATUS_SIZE. DhgklZglu MPI_SOURCE, MPI_TAGbMPI_ERRORy\eyxlkybg^_dkZfbih^ZgghfmfZkkb\m ^ey^hklmiZdagZq_gbyfkhhl\_lkl\mxsboihe_c • status(MPI_SOURCE) — ghf_jijhp_kkZ-hlijZ\bl_eykhh[s_gby • status(MPI_TAG) — b^_glbnbdZlhjkhh[s_gby • status(MPI_ERROR) — dh^ hrb[db. < yaud_ Kb iZjZf_lj status y\ey_lky kljmdlmjhc ij_^hij_^_e_ggh]h lbiZ MPI_StatuskiheyfbMPI_SOURCE, MPI_TAGbMPI_ERROR. H[jZlbf \gbfZgb_ gZ g_dhlhjmx g_kbff_ljbqghklv hi_jZpbc ihkuedb b ijb_fZ khh[s_gbc K ihfhsvx dhgklZglu MPI_ANY_SOURCE fh`gh ijbgylv khh[s_gb_hlex[h]hijhp_kkZH^gZdh\kemqZ_ihkuedb^Zgguolj_[m_lky y\ghmdZaZlvghf_jijbgbfZxs_]hijhp_kkZ <klZg^Zjl_h]h\hj_ghqlh_kebh^bgijhp_kkihke_^h\Zl_evghihkueZ_l^\Z khh[s_gby khhl\_lkl\mxsb_ h^ghfm b lhfm `_ \uah\m MPI_RECV ^jm]hfm ijhp_kkm lh i_j\uf [m^_l ijbgylh khh[s_gb_ dhlhjh_ [ueh hlijZ\e_gh jZgvr_
MPI_GET_COUNT(STATUS, DATATYPE, COUNT, IERR) INTEGER COUNT, DATATYPE, IERR, STATUS(MPI_STATUS_SIZE) IhagZq_gbxiZjZf_ljZ STATUSijhp_^mjZhij_^_ey_lqbkeh COUNTm`_ijbgyluoihke_h[jZs_gbyd MPI_RECV bebijbgbfZ_fuoihke_h[jZs_gbyd MPI_PROBE beb MPI_IPROBE we_f_glh\ khh[s_gby lbiZ DATATYPE >ZggZy
ijhp_^mjZ \ qZklghklb g_h[oh^bfZ ^ey hij_^_e_gby jZaf_jZ h[eZklb iZfylb\u^_ey_fhc^eyojZg_gbyijbgbfZ_fh]hkhh[s_gby
MPI_PROBE(SOURCE, MSGTAG, COMM, STATUS, IERR) INTEGER SOURCE, MSGTAG, COMM, IERR, STATUS(MPI_STATUS_SIZE) Ihemq_gb_ \ fZkkb\_ STATUS bgnhjfZpbb h kljmdlmj_ h`b^Z_fh]h khh[s_gby k b^_glbnbdZlhjhf MSGTAG hl ijhp_kkZ k ghf_jhf SOURCE \ dhffmgbdZlhj_ COMM k [ehdbjh\dhc
^h l_o ihj ihdZ khh[s_gb_ k ih^oh^ysbf b^_glbnbdZlhjhf b ghf_jhf ijhp_kkZ-hlijZ\bl_ey g_ [m^_l ^hklmigh ^ey ihemq_gby Ke_^m_l hkh[h h[jZlblv \gbfZgb_ gZ lh qlh ijhp_^mjZ hij_^_ey_l lhevdh nZdl ijboh^Z khh[s_gby gh j_Zevgh _]h g_ ijbgbfZ_l ?keb ihke_ \uah\Z MPI_PROBE \uau\Z_lky MPI_RECV k lZdbfb `_ iZjZf_ljZfb lh [m^_l ijbgylh lh `_ kZfh_khh[s_gb_bgnhjfZpbyhdhlhjhf[ueZihemq_gZkihfhsvx\uah\Z ijhp_^mjuMPI_PROBE. Ke_^mxsbc ijbf_j ^_fhgkljbjm_l ijbf_g_gb_ ijhp_^mju MPI_PROBE ^ey hij_^_e_gbykljmdlmjuijboh^ys_]hkhh[s_gbyIjhp_kk0`^_lkhh[s_gby hlex[h]hbaijhp_kkh\ 1b 2kh^gbfbl_f`_l_]hfH^gZdhihkueZ_fu_ wlbfbijhp_kkZfb^Zggu_bf_xljZaguclbi>eylh]hqlh[uhij_^_eblv\ dZdmx i_j_f_ggmx ihf_sZlv ijboh^ys__ khh[s_gb_ ijhp_kk kgZqZeZ ijb ihfhsb\uah\Z MPI_PROBEhij_^_ey_lhldh]h`_bf_gghihklmibehwlhkhh[s_gb_Ke_^mxsbcg_ihkj_^kl\_gghihke_ MPI_PROBE\uah\ MPI_RECV]ZjZglbjh\Zgghijbf_lgm`gh_khh[s_gb_ihke_q_]hijbgbfZ_lkykhh[s_gb_ hl^jm]h]hijhp_kkZ program example7 include 'mpif.h' integer rank, ierr, ibuf, status(MPI_STATUS_SIZE) real rbuf call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) ibuf = rank rbuf = 1.0 * rank if(rank .eq. 1) call MPI_SEND(ibuf, 1, MPI_INTEGER, 0, 5, & MPI_COMM_WORLD, ierr) if(rank .eq. 2) call MPI_SEND(rbuf, 1, MPI_REAL, 0, 5, & MPI_COMM_WORLD, ierr) if(rank .eq. 0) then call MPI_PROBE(MPI_ANY_SOURCE, 5, MPI_COMM_WORLD, & status, ierr) 19
if(status(MPI_SOURCE) .EQ. 1) then call MPI_RECV(ibuf, 1, MPI_INTEGER, 1, 5, & MPI_COMM_WORLD, status, ierr) call MPI_RECV(rbuf, 1, MPI_REAL, 2, 5, & MPI_COMM_WORLD, status, ierr) else if(status(MPI_SOURCE) .EQ. 2) then call MPI_RECV(rbuf, 1, MPI_REAL, 2, 5, & MPI_COMM_WORLD, status, ierr) call MPI_RECV(ibuf, 1, MPI_INTEGER, 1, 5, & MPI_COMM_WORLD, status, ierr) end if end if print *, 'Process 0 recv ', ibuf, ' from process 1, ', & rbuf, ' from process 2' end if call MPI_FINALIZE(ierr) end
<ke_^mxs_fijbf_j_fh^_ebjm_lkyihke_^h\Zl_evguch[f_gkhh[s_gbyfb f_`^m^\mfyijhp_kkZfbaZf_jy_lky\j_fygZh^gmbl_jZpbxh[f_gZhij_^_ey_lkyaZ\bkbfhklv\j_f_gbh[f_gZhl^ebgukhh[s_gbyLZdbfh[jZahf hij_^_eyxlky [Zah\u_ oZjZdl_jbklbdb dhffmgbdZpbhgghc k_lb iZjZee_evgh]h dhfivxl_jZ eZl_glghklv \j_fy gZ i_j_^Zqm khh[s_gby gme_\hc ^ebgu bfZdkbfZevgh^hklb`bfZyijhimkdgZykihkh[ghklvdhebq_kl\hf_]Z[Zcl\k_dmg^m dhffmgbdZpbhgghck_lbZlZd`_^ebgZkhh[s_gbcgZdhlhjhchgZ^hklb]Z_lkyDhgklZglZNMAXaZ^Z_lh]jZgbq_gb_gZfZdkbfZevgmx ^ebgm ihkueZ_fh]h khh[s_gby Z dhgklZglZ NTIMES hij_^_ey_l dhebq_kl\h ih\lhj_gbc ^ey mkj_^g_gby j_amevlZlZ KgZqZeZ ihkueZ_lky khh[s_gb_ gme_\hc ^ebgu ^ey hij_^_e_gby eZl_glghklb aZl_f ^ebgZ khh[s_gbc m^\Zb\Z_lkygZqbgZykihkuedbh^gh]hwe_f_glZlbiZreal*8. program example8 include 'mpif.h' integer ierr, rank, size, i, n, lmax, NMAX, NTIMES parameter (NMAX = 1 000 000, NTIMES = 10) double precision time_start, time, bandwidth, max real*8 a(NMAX) integer status(MPI_STATUS_SIZE) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) time_start = MPI_WTIME(ierr) n = 0 max = 0.0 lmax = 0 do while(n .le. NMAX) time_start = MPI_WTIME(ierr) 20
do i = 1, NTIMES if(rank .eq. 0) then call MPI_SEND(a, n, MPI_DOUBLE_PRECISION, 1, 1, & MPI_COMM_WORLD, ierr) call MPI_RECV(a, n, MPI_DOUBLE_PRECISION, 1, 1, & MPI_COMM_WORLD, status, ierr) end if if(rank .eq. 1) then call MPI_RECV(a, n, MPI_DOUBLE_PRECISION, 0, 1, & MPI_COMM_WORLD, status, ierr) call MPI_SEND(a, n, MPI_DOUBLE_PRECISION, 0, 1, & MPI_COMM_WORLD, ierr) end if enddo time = (MPI_WTIME(ierr)-time_start)/2/NTIMES bandwidth = (8*n*1.d0/(2**20))/time if(max .lt. bandwidth) then max = bandwidth lmax = 8*n end if if(rank .eq. 0) then if(n .eq. 0) then print *, 'latency = ', time, ' seconds' else print *, 8*n, ' bytes, bandwidth =', bandwidth, & ' Mb/s' end if end if if(n .eq. 0) then n = 1 else n = 2*n end if end do if(rank .eq. 0) then print *, 'max bandwidth =', max, ' Mb/s , length =', & lmax, ' bytes' end if call MPI_FINALIZE(ierr) end
I_j_^ZqZijb_fkhh[s_gbc[_a[ehdbjh\db < MPI ij_^mkfhlj_g gZ[hj ijhp_^mj ^ey hkms_kl\e_gby Zkbgojhgghc i_j_^Zqb^Zgguo<hlebqb_hl[ehdbjmxsboijhp_^mj\ha\jZlbaijhp_^mj ^Zgghc]jmiiuijhbkoh^blkjZamihke_\uah\Z[_adZdhc-eb[hhklZgh\dbjZ[hlu ijhp_kkh\ GZ nhg_ ^Zevg_cr_]h \uiheg_gby ijh]jZffu h^gh\j_f_gghijhbkoh^blbh[jZ[hldZZkbgojhgghaZims_gghchi_jZpbb
21
< ijbgpbi_ ^ZggZy \hafh`ghklv bkdexqbl_evgh ihe_agZ ^ey kha^Zgby wnn_dlb\guo ijh]jZff < kZfhf ^_e_ ijh]jZffbkl agZ_l qlh \ g_dhlhjuc fhf_gl_fmihlj_[m_lkyfZkkb\dhlhjuc\uqbkey_l^jm]hcijhp_kkHgaZjZg__ \uklZ\ey_l \ ijh]jZff_ Zkbgojhgguc aZijhk gZ ihemq_gb_ ^Zggh]h fZkkb\ZZ^hlh]hfhf_glZdh]^ZfZkkb\j_Zevghihlj_[m_lkyhgfh`_l\uihegylv ex[mx ^jm]mx ihe_agmx jZ[hlm Hiylv `_ \h fgh]bo kemqZyo kh\_jr_gghg_h[yaZl_evgh^h`b^ZlvkyhdhgqZgbyihkuedbkhh[s_gby^ey\uiheg_gby ihke_^mxsbo \uqbke_gbc >ey aZ\_jr_gby Zkbgojhggh]h h[f_gZ lj_[m_lky \uah\ ^hihegbl_evghc ijhp_^mju dhlhjZy ijh\_jy_l aZ\_jrbeZkvebhi_jZpbybeb^h`b^Z_lky__aZ\_jr_gbyLhevdhihke_wlh]hfh`gh bkihevah\Zlv [mn_j ihkuedb ^ey ^jm]bo p_e_c [_a hiZk_gby aZihjlblv hlijZ\ey_fh_khh[s_gb_ ?keb _klv \hafh`ghklv hi_jZpbb ijb_fZi_j_^Zqb khh[s_gbc kdjulv gZ nhg_\uqbke_gbclhwlbf\jh^_[ugZ^h[_ah]h\hjhqghihevah\ZlvkyH^gZdh gZ ijZdlbd_ g_ \k_ \k_]^Z kh]eZkm_lky k l_hjb_c Fgh]h_ aZ\bkbl hl dhgdj_lghcj_ZebaZpbbDkh`Ze_gbx^Ze_dhg_\k_]^ZZkbgojhggu_hi_jZpbb wnn_dlb\gh ih^^_j`b\Zxlky ZiiZjZlmjhc b kbkl_fguf hdjm`_gb_f Ihwlhfm g_ klhbl m^b\eylvky _keb wnn_dl hl \uiheg_gby \uqbke_gbc gZ nhg_ i_j_kuehd hdZ`_lky gme_\uf beb kh\k_f g_[hevrbf K^_eZggu_ aZf_qZgby dZkZxlky lhevdh \hijhkh\ wnn_dlb\ghklb < hlghr_gbb ij_^hklZ\ey_fhc nmgdpbhgZevghklb Zkbgojhggu_ hi_jZpbb bkdexqbl_evgh ihe_agu ihwlhfm hgb ijbkmlkl\mxl ijZdlbq_kdb \ dZ`^hc j_Zevghc ijh]jZff_ MPI_ISEND(BUF, COUNT, DATATYPE, DEST, MSGTAG, COMM, REQUEST, IERR)
• MPI_IBSEND — g_[ehdbjmxsZyi_j_^ZqZkhh[s_gbyk[mn_jbaZpb_c • MPI_ISSEND — g_[ehdbjmxsZyi_j_^ZqZkhh[s_gbykkbgojhgbaZpb_c • MPI_IRSEND — g_[ehdbjmxsZyi_j_^ZqZkhh[s_gbyih]hlh\ghklb Dbaeh`_gghc\ur_k_fZglbd_jZ[hluwlboijhp_^mj^h[Z\ey_lkyhlkmlkl\b_ [ehdbjh\db MPI_IRECV(BUF, COUNT, DATATYPE, SOURCE, MSGTAG, COMM, REQUEST, IERR)
jmxs_]hijb_fZ\ha\jZlbaijhp_^mjuijhbkoh^blkjZamihke_bgbpbZebaZpbbijhp_kkZijb_fZ[_ah`b^Zgbyihemq_gby\k_]hkhh[s_gbyb_]haZibkb \[mn_j_BUFHdhgqZgb_ijhp_kkZijb_fZfh`ghhij_^_eblvkihfhsvxiZjZf_ljZREQUESTbijhp_^mjk_f_ckl\MPI_WAIT bMPI_TEST.
Khh[s_gb_hlijZ\e_ggh_ex[hcbaijhp_^mjMPI_SEND, MPI_ISENDbex[hc balj_obofh^bnbdZpbcfh`_l[ulvijbgylhex[hcbaijhp_^mj MPI_RECV bMPI_IRECV. H[jZlbf hkh[h_ \gbfZgb_ gZ lh qlh ^h aZ\_jr_gby g_[ehdbjmxs_c hi_jZpbbg_ke_^m_laZibku\Zlv\bkihevam_fucfZkkb\^Zgguo MPI_IPROBE(SOURCE, MSGTAG, COMM, FLAG, STATUS, IERR) LOGICAL FLAG INTEGER SOURCE, MSGTAG, COMM, IERR, STATUS(MPI_STATUS_SIZE) Ihemq_gb_ \ fZkkb\_ STATUS bgnhjfZpbb h kljmdlmj_ h`b^Z_fh]h khh[s_gby k b^_glbnbdZlhjhf MSGTAG hl ijhp_kkZ k ghf_jhf SOURCE \ dhffmgbdZlhj_ COMM [_a [ehdbjh\db < iZjZf_lj_ FLAG \ha\jZsZ_lky agZq_gb_ .TRUE. _keb khh[s_gb_ k ih^oh^ysbfb Zljb[mlZfb m`_ fh`_l
[ulv ijbgylh \ wlhf kemqZ_ ^_ckl\b_ ijhp_^mju iheghklvx ZgZeh]bqgh MPI_PROBE bagZq_gb_ .FALSE._kebkhh[s_gbykmdZaZggufbZljb[mlZfb _s_g_l MPI_WAIT(REQUEST, STATUS, IERR) INTEGER REQUEST, IERR, STATUS(MPI_STATUS_SIZE)
H`b^Zgb_aZ\_jr_gbyZkbgojhgghchi_jZpbbZkkhpbbjh\Zgghckb^_glbnbdZlhjhf REQUEST b aZims_gghc \uah\hf ijhp_^mju MPI_ISEND beb MPI_IRECVIhdZZkbgojhggZyhi_jZpbyg_[m^_laZ\_jr_gZijhp_kk\uihegb\rbc ijhp_^mjm MPI_WAIT [m^_l aZ[ehdbjh\Zg >ey hi_jZpbb g_[ehdbjmxs_]hijb_fZhij_^_ey_lkyiZjZf_lj STATUSIhke_\uiheg_gby 23
ijhp_^mju b^_glbnbdZlhj g_[ehdbjmxs_c mklZgZ\eb\Z_lky\agZq_gb_MPI_REQUEST_NULL.
hi_jZpbb
REQUEST
MPI_WAITALL(COUNT, REQUESTS, STATUSES, IERR) INTEGER COUNT, REQUESTS(*), STATUSES(MPI_STATUS_SIZE,*), IERR H`b^Zgb_ aZ\_jr_gby COUNT Zkbgojhgguo hi_jZpbc Zkkhpbbjh\Zgguo k b^_glbnbdZlhjZfb fZkkb\Z REQUESTS >ey hi_jZpbc g_[ehdbjmxsbo ijb_fh\ hij_^_eyxlky khhl\_lkl\mxsb_ iZjZf_lju \ fZkkb\_ STATUSES.
?keb\h\j_fyh^ghcbebg_kdhevdbohi_jZpbch[f_gZ\hagbdebhrb[dblh ihe_ hrb[db \ we_f_glZo fZkkb\Z STATUSES [m^_l mklZgh\e_gh \ khhl\_lkl\mxs__agZq_gb_Ihke_\uiheg_gbyijhp_^mjukhhl\_lkl\mxsb_ REQUESTS we_f_glu iZjZf_ljZ mklZgZ\eb\Zxlky \ agZq_gb_ MPI_REQUEST_NULL. Gb`_ihdZaZgijbf_jnjZ]f_glZijh]jZffu\dhlhjhc\k_ijhp_kkuh[f_gb\Zxlky khh[s_gbyfb k [eb`Zcrbfb khk_^yfb \ khhl\_lkl\bb k lhiheh]b_cdhevpZijbihfhsbg_[ehdbjmxsbohi_jZpbcAZf_lbfqlhbkihevah\Zgb_^eywlbop_e_c[ehdbjmxsbohi_jZpbcfh]ehijb\_klbd\hagbdgh\_gbxlmibdh\hckblmZpbb program example9 include 'mpif.h' integer ierr, rank, size, prev, next, reqs(4), buf(2) integer stats(MPI_STATUS_SIZE, 4) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) prev = rank - 1 next = rank + 1 if (rank .eq. 0) prev = size - 1 if (rank .eq. size - 1) next = 0 call MPI_IRECV(buf(1), 1, MPI_INTEGER, prev, 5, & MPI_COMM_WORLD, reqs(1), ierr) call MPI_IRECV(buf(2), 1, MPI_INTEGER, next, 6, & MPI_COMM_WORLD, reqs(2), ierr) call MPI_ISEND(rank, 1, MPI_INTEGER, prev, 6, & MPI_COMM_WORLD, reqs(3), ierr) call MPI_ISEND(rank, 1, MPI_INTEGER, next, 5, & MPI_COMM_WORLD, reqs(4), ierr) call MPI_WAITALL(4, reqs, stats, ierr); print *, ‘process ’, rank, & ‘ prev=’, buf(1), ‘ next=’, buf(2) call MPI_FINALIZE(ierr) end MPI_WAITANY(COUNT, REQUESTS, INDEX, STATUS, IERR) INTEGER COUNT, REQUESTS(*), INDEX, STATUS(MPI_STATUS_SIZE), IERR H`b^Zgb_ aZ\_jr_gby h^ghc ba COUNT Zkbgojhgguo hi_jZpbc Zkkhpbbjh\Zgguokb^_glbnbdZlhjZfb REQUESTS?kebdfhf_glm\uah\ZaZ\_jrbebkv 24
g_kdhevdh ba h`b^Z_fuo hi_jZpbc lh kemqZcguf h[jZahf [m^_l \u[jZgZ h^gZbagboIZjZf_lj INDEX kh^_j`blghf_jwe_f_glZ\fZkkb\_ REQUESTS, kh^_j`Zs_]h b^_glbnbdZlhj aZ\_jr_gghc hi_jZpbb >ey g_[ehdbjmxs_]h ijb_fZ hij_^_ey_lky iZjZf_lj STATUS Ihke_ \uiheg_gby ijhp_^mju khhl\_lkl\mxsbc we_f_gl iZjZf_ljZ REQUESTS mklZgZ\eb\Z_lky \ agZq_gb_ MPI_REQUEST_NULL. MPI_WAITSOME(INCOUNT, REQUESTS, OUTCOUNT, INDEXES, STATUSES, IERR) INTEGER INCOUNT, REQUESTS(*), OUTCOUNT, INDEXES(*), IERR, STATUSES(MPI_STATUS_SIZE,*) H`b^Zgb_aZ\_jr_gbyohly[uh^ghcbaINCOUNTZkbgojhgguohi_jZpbcZkkhpbbjh\Zgguo k b^_glbnbdZlhjZfb REQUESTS IZjZf_lj OUTCOUNT kh^_j`bl qbkeh aZ\_jr_gguo hi_jZpbc Z i_j\u_ OUTCOUNT we_f_glh\ fZkkb\Z INDEXES kh^_j`Zl ghf_jZ we_f_glh\ fZkkb\Z REQUESTS k bo b^_glbnbdZlhjZfb I_j\u_ OUTCOUNT we_f_glh\ fZkkb\Z STATUSES kh^_j`Zl iZjZf_lju
aZ\_jr_gguo hi_jZpbc ^ey g_[ehdbjmxsbo ijb_fh\ Ihke_ \uiheg_gby ijhp_^mju khhl\_lkl\mxsb_ we_f_glu iZjZf_ljZ REQUESTS mklZgZ\eb\Zxlky\agZq_gb_MPI_REQUEST_NULL.
< ke_^mxs_f ijbf_j_ ^_fhgkljbjm_lky ko_fZ bkihevah\Zgby ijhp_^mju MPI_WAITSOME^eyhj]ZgbaZpbbdhffmgbdZpbhgghcko_fu³master-slave´\k_ ijhp_kku h[sZxlky k h^gbf \u^_e_gguf ijhp_kkhf
25
program example10 include 'mpif.h' integer rank, size, ierr, N, MAXPROC parameter(N = 1000, MAXPROC = 128) integer req(MAXPROC), num, indexes(MAXPROC) integer statuses(MPI_STATUS_SIZE, MAXPROC) double precision a(N, MAXPROC) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) if(rank .ne. 0) then do while(.TRUE.) call slave(a, N) call MPI_SEND(a, N, MPI_DOUBLE_PRECISION, 0, 5, & MPI_COMM_WORLD, ierr) end do else do i = 1, size-1 call MPI_IRECV(a(1, i), N, MPI_DOUBLE_PRECISION, i, & 5, MPI_COMM_WORLD, req(i), ierr) end do do while(.TRUE.) call MPI_WAITSOME(size-1, req, num, indexes, & statuses, ierr) do i = 1, num call master(a(1, indexes(i)), N) call MPI_IRECV(a(1, indexes(i)), N, & MPI_DOUBLE_PRECISION, & indexes(i), 5, MPI_COMM_WORLD, & req(indexes(i)), ierr) end do end do end if call MPI_FINALIZE(ierr) end subroutine slave(a, n) double precision a integer n &h[jZ[hldZehdZevghcqZklbfZkkb\ZD end subroutine master(a, n) double precision a integer n &h[jZ[hldZfZkkb\ZD End
26
MPI_TEST(REQUEST, FLAG, STATUS, IERR) LOGICAL FLAG INTEGER REQUEST, IERR, STATUS(MPI_STATUS_SIZE) Ijh\_jdZ aZ\_jr_gghklb Zkbgojhgghchi_jZpbb MPI_ISENDbeb MPI_IRECV, Zkkhpbbjh\Zgghckb^_glbnbdZlhjhf REQUEST<iZjZf_lj_ FLAG\ha\jZsZ_lkyagZq_gb_ .TRUE._kebhi_jZpbyaZ\_jr_gZbagZq_gb_ .FALSE. -\ijhlb\ghf kemqZ_\ yaud_ Kb – 1 beb 0 khhl\_lkl\_ggh ?kebaZ\_jr_gZijh-
p_^mjZ ijb_fZ lh Zljb[mlu b ^ebgm ihemq_ggh]h khh[s_gby fh`gh hij_^_eblv h[uqguf h[jZahf k ihfhsvx iZjZf_ljZ STATUS Ihke_ \uiheg_gby ijhp_^mju khhl\_lkl\mxsbc we_f_gl iZjZf_ljZ REQUEST mklZgZ\eb\Z_lky\agZq_gb_MPI_REQUEST_NULL. MPI_TESTALL(COUNT, REQUESTS, FLAG, STATUSES, IERR) LOGICAL FLAG INTEGER COUNT, REQUESTS(*), STATUSES(MPI_STATUS_SIZE,*), IERR Ijh\_jdZ aZ\_jr_gghklb COUNT Zkbgojhgguo hi_jZpbc Zkkhpbbjh\Zgguok b^_glbnbdZlhjZfb REQUESTS < iZjZf_lj_ FLAG ijhp_^mjZ \ha\jZsZ_l agZq_gb_ .TRUE. \ yaud_ Kb – 1 _keb \k_ hi_jZpbb Zkkhpbbjh\Zggu_ k mdZ-
aZggufb b^_glbnbdZlhjZfb aZ\_jr_gu < wlhf kemqZ_ iZjZf_lju khh[s_gbc[m^mlmdZaZgu\fZkkb\_ STATUSES?kebdZdZy-eb[hbahi_jZpbc g_aZ\_jrbeZkvlh\ha\jZsZ_lky.FALSE.\yaud_Kb– 0 bhij_^_e_gghklv we_f_glh\ fZkkb\Z STATUSES g_ ]ZjZglbjm_lky Ihke_ \uiheg_gby REQUESTS ijhp_^mju khhl\_lkl\mxsb_ we_f_glu iZjZf_ljZ mklZgZ\eb\Zxlky\agZq_gb_MPI_REQUEST_NULL. MPI_TESTANY(COUNT, REQUESTS, INDEX, FLAG, STATUS, IERR) LOGICAL FLAG INTEGER COUNT, REQUESTS(*), INDEX, STATUS(MPI_STATUS_SIZE), IERR
Ijh\_jdZaZ\_jr_gghklbohly[uh^ghcZkbgojhgghchi_jZpbbZkkhpbbjh\Zgghckb^_glbnbdZlhjhfbafZkkb\ZREQUESTS<iZjZf_lj_FLAG\ha\jZsZ_lky agZq_gb_ .TRUE. \ yaud_ Kb – 1 _keb ohly [u h^gZ ba hi_jZpbc Zkbgojhggh]hh[f_gZaZ\_jr_gZijbwlhf INDEXkh^_j`blghf_jkhhl\_lkl\mxs_]hwe_f_glZ\fZkkb\_REQUESTSZSTATUS — iZjZf_ljukhh[s_gby< ijhlb\ghf kemqZ_ \ iZjZf_lj_ FLAG [m^_l \ha\jZs_gh agZq_gb_ .FALSE. \ yaud_Kb– 0 ?kebdfhf_glm\uah\ZaZ\_jrbebkvg_kdhevdhbah`b^Z_fuo hi_jZpbc lh kemqZcguf h[jZahf [m^_l \u[jZgZ h^gZ ba gbo Ihke_ \uiheg_gby ijhp_^mju khhl\_lkl\mxsbc we_f_gl iZjZf_ljZ REQUESTS mklZgZ\eb\Z_lky\agZq_gb_MPI_REQUEST_NULL.
27
MPI_TESTSOME(INCOUNT, REQUESTS, OUTCOUNT, INDEXES, STATUSES, IERR) INTEGER INCOUNT, REQUESTS(*), OUTCOUNT, INDEXES(*), IERR, STATUSES(MPI_STATUS_SIZE,*) :gZeh]ijhp_^mju MPI_WAITSOMEgh\ha\jZlijhbkoh^blg_f_^e_ggh?keb
gbh^gZbal_klbjm_fuohi_jZpbcdfhf_glm\uah\Zg_aZ\_jrbeZkvlhagZq_gb_OUTCOUNT[m^_ljZ\ghgmex
Ke_^mxsbc ijbf_j ^_fhgkljbjm_l ijbf_g_gb_ g_[ehdbjmxsbo hi_jZpbc ^eyj_ZebaZpbbljZgkihgbjh\Zgbyd\Z^jZlghcfZljbpujZkij_^_e_gghcf_`^m ijhp_kkZfb ih kljhdZf KgZqZeZ dZ`^uc ijhp_kk ehdZevgh hij_^_ey_l nlkljhdfZkkb\ZaAZl_fijbihfhsbg_[ehdbjmxsbohi_jZpbcMPI_ISEND b MPI_IRECVbgbpbZebabjmxlky\k_g_h[oh^bfu_^eyljZgkihgbjh\Zgbyh[f_gu ^Zggufb GZ nhg_ gZqbgZxsboky h[f_gh\ dZ`^uc ijhp_kk ljZgkihgbjm_l k\hx ehdZevgmx qZklv fZkkb\Z a Ihke_ wlh]h ijhp_kk ijb ihfhsb \uah\Z ijhp_^mju MPI_WAITANY ^h`b^Z_lky ijboh^Z khh[s_gby hl ex[h]h ^jm]h]h ijhp_kkZ b ljZgkihgbjm_l ihemq_ggmx hl ^Zggh]h ijhp_kkZ qZklv fZkkb\Z a H[jZ[hldZ ijh^he`Z_lky ^h l_o ihj ihdZ g_ [m^ml ihemq_gu khh[s_gby hl \k_o ijhp_kkh\ < dhgp_ bkoh^guc fZkkb\ a b ljZgkihgbjh\ZggucfZkkb\bjZki_qZlu\Zxlky program example11 include 'mpif.h' integer ierr, rank, size, N, nl, i, j parameter (N = 9) double precision a(N, N), b(N, N) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) nl = (N-1)/size+1 call work(a, b, N, nl, size, rank) call MPI_FINALIZE(ierr) end subroutine work(a, b, n, nl, size, rank) include 'mpif.h' integer ierr, rank, size, n, MAXPROC, nl, i, j, ii, jj, ir parameter (MAXPROC = 64) double precision a(nl, n), b(nl, n), c integer irr, status(MPI_STATUS_SIZE), req(MAXPROC*2) do i = 1, nl do j = 1, n ii = i+rank*nl if(ii .le. n) a(i, j) = 100*ii+j end do end do do ir = 0, size-1 if(ir .ne. rank) & call MPI_IRECV(b(1, ir*nl+1), nl*nl, 28
& & &
MPI_DOUBLE_PRECISION, ir, MPI_ANY_TAG, MPI_COMM_WORLD, req(ir+1), ierr) end do req(rank+1) = MPI_REQUEST_NULL
do ir = 0, size-1 if(ir .ne. rank) & call MPI_ISEND(a(1, ir*nl+1), nl*nl, & MPI_DOUBLE_PRECISION, ir, & 1, MPI_COMM_WORLD, & req(ir+1+size), ierr) end do ir = rank do i = 1, nl ii = i+ir*nl do j = i+1, nl jj = j+ir*nl b(i, jj) = a(j, ii) b(j, ii) = a(i, jj) end do b(i, ii) = a(i, ii) end do do irr = 1, size-1 call MPI_WAITANY(size, req, ir, status, ierr) ir = ir-1 do i = 1, nl ii = i+ir*nl do j = i+1, nl jj = j+ir*nl c = b(i, jj) b(i, jj) = b(j, ii) b(j, ii) = c end do end do end do do i = 1, nl do j = 1, N ii = i+rank*nl if(ii .le. n) print *, 'process ', rank, & ': a(', ii, ', ', j, ') =', a(i,j), & ', b(', ii, ', ', j, ') =', b(i,j) end do end do end
29
Hleh`_ggu_aZijhkugZ\aZbfh^_ckl\b_ Ijhp_^mju ^Zgghc ]jmiiu iha\heyxl kgbablv gZdeZ^gu_ jZkoh^u \hagbdZxsb_\jZfdZoh^gh]hijhp_kkhjZijbh[jZ[hld_ijb_fZi_j_^Zqbbi_j_f_s_gbbg_h[oh^bfhcbgnhjfZpbbf_`^mijhp_kkhfbk_l_\ufdhgljhee_jhf QZklh \ ijh]jZff_ ijboh^blky fgh]hdjZlgh \uihegylv h[f_gu k h^bgZdh\ufbiZjZf_ljZfbgZijbf_j\pbde_ <wlhfkemqZ_fh`ghh^bgjZa bgbpbZebabjh\Zlv hi_jZpbx h[f_gZ b ihlhf fgh]hdjZlgh __ aZimkdZlv g_ ljZly gZ dZ`^hc bl_jZpbb ^hihegbl_evgh]h \j_f_gb gZ bgbpbZebaZpbx b aZ\_^_gb_khhl\_lkl\mxsbo\gmlj_ggbokljmdlmj^ZgguoDjhf_lh]hlZdbf h[jZahf g_kdhevdh aZijhkh\ gZ ijb_f bbeb i_j_^Zqm fh]ml h[t_^bgylvky \f_kl_^eylh]hqlh[u^Ze__bofh`gh[ueh[uaZimklblvh^ghcdhfZg^hc \ijhq_f wlh kh\k_f g_h[yaZl_evgh ohjhrh ihkdhevdm fh`_l ijb\_klb d i_j_]jmad_dhffmgbdZpbhgghck_lb Kihkh[ ijb_fZ khh[s_gby gbdZd g_ aZ\bkbl hl kihkh[Z _]h ihkuedb khh[s_gb_ hlijZ\e_ggh_ k ihfhsvx hleh`_gguo aZijhkh\ eb[h h[uqguf kihkh[hffh`_l[ulvijbgylhdZdh[uqgufkihkh[hflZdbkihfhsvxhleh`_gguoaZijhkh\ MPI_SEND_INIT(BUF, COUNT, DATATYPE, DEST, MSGTAG, COMM, REQUEST, IERR)
Nhjfbjh\Zgb_hleh`_ggh]haZijhkZgZihkuedmkhh[s_gbyKZfZhi_jZpby i_j_kuedbijbwlhfg_gZqbgZ_lky :gZeh]bqgh lj_f fh^bnbdZpbyf ijhp_^mj MPI_SEND b MPI_ISEND ij_^mkfhlj_guljb^hihegbl_evguo\ZjbZglZijhp_^mjuMPI_SEND_INIT: • MPI_BSEND_INIT — nhjfbjh\Zgb_ hleh`_ggh]h aZijhkZ gZ i_j_^Zqm khh[s_gbyk[mn_jbaZpb_c • MPI_SSEND_INIT — nhjfbjh\Zgb_ hleh`_ggh]h aZijhkZ gZ i_j_^Zqm khh[s_gbykkbgojhgbaZpb_c • MPI_RSEND_INIT — nhjfbjh\Zgb_ hleh`_ggh]h aZijhkZ gZ i_j_^Zqm khh[s_gbyih]hlh\ghklb MPI_RECV_INIT(BUF, COUNT, DATATYPE, SOURCE, MSGTAG, COMM, REQUEST, IERR)
Nhjfbjh\Zgb_ hleh`_ggh]h aZijhkZ gZ ijb_f khh[s_gby KZfZ hi_jZpby ijb_fZijbwlhfg_gZqbgZ_lky
30
MPI_START(REQUEST, IERR) INTEGER REQUEST, IERR
BgbpbZebaZpbyhleh`_ggh]haZijhkZgZ\uiheg_gb_hi_jZpbbh[f_gZkhhl\_lkl\mxs_c agZq_gbx iZjZf_ljZ REQUEST Hi_jZpby aZimkdZ_lky dZd g_[ehdbjmxsZy MPI_STARTALL(COUNT, REQUESTS, IERR) INTEGER COUNT, REQUESTS, IERR BgbpbZebaZpby COUNT hleh`_gguo aZijhkh\ gZ \uiheg_gb_ hi_jZpbc h[f_gZ khhl\_lkl\mxsbo agZq_gbyf i_j\uo COUNT we_f_glh\ fZkkb\Z REQUESTSHi_jZpbbaZimkdZxlkydZdg_[ehdbjmxsb_
< hlebqb_ hl g_[ehdbjmxsbo hi_jZpbc ih aZ\_jr_gbb \uiheg_gby hi_jZpbbaZims_gghcijbihfhsbhleh`_ggh]haZijhkZgZ\aZbfh^_ckl\b_ agZq_gb_iZjZf_ljZREQUEST (REQUESTS khojZgy_lkybfh`_lbkihevah\Zlvky \^Zevg_cr_f MPI_REQUEST_FREE(REQUEST, IERR) INTEGER REQUEST, IERR
>ZggZy ijhp_^mjZ m^Zey_l kljmdlmju ^Zgguo k\yaZggu_ k iZjZf_ljhf REQUESTIhke___\uiheg_gbyiZjZf_ljREQUESTmklZgZ\eb\Z_lky\agZq_gb_ MPI_REQUEST_NULL ?keb hi_jZpby k\yaZggZy k wlbf aZijhkhf m`_ \uihegy_lkylhhgZ[m^_laZ\_jr_gZ <ke_^mxs_fijbf_j_bgbpbZebabjmxlkyhleh`_ggu_aZijhkugZhi_jZpbb ^\mgZijZ\e_ggh]h h[f_gZ k khk_^gbfb ijhp_kkZfb \ dhevp_\hc lhiheh]bb KZfb hi_jZpbb aZimkdZxlky gZ dZ`^hc bl_jZpbb ihke_^mxs_]h pbdeZ Ih aZ\_jr_gbbpbdeZhleh`_ggu_aZijhkum^Zeyxlky prev = rank - 1 next = rank + 1 if(rank .eq. 0) prev = size - 1 if(rank .eq. size - 1) next = 0 call MPI_RECV_INIT(rbuf(1), 1, MPI_REAL, prev, 5, & MPI_COMM_WORLD, reqs(1), ierr) call MPI_RECV_INIT(rbuf(2), 1, MPI_REAL, next, 6, & MPI_COMM_WORLD, reqs(2), ierr) call MPI_SEND_INIT(sbuf(1), 1, MPI_REAL, prev, 6, & MPI_COMM_WORLD, reqs(3), ierr) call MPI_SEND_INIT(sbuf(2), 1, MPI_REAL, next, 5, & MPI_COMM_WORLD, reqs(4), ierr) do i=... sbuf(1)=... sbuf(2)=... call MPI_STARTALL(4, reqs, ierr) ... call MPI_WAITALL(4, reqs, stats, ierr); ... end do 31
call call call call
MPI_REQUEST_FREE(reqs(1), MPI_REQUEST_FREE(reqs(2), MPI_REQUEST_FREE(reqs(3), MPI_REQUEST_FREE(reqs(4),
ierr) ierr) ierr) ierr)
Lmibdh\u_kblmZpbbGHDGORFN Bkihevah\Zgb_[ehdbjmxsboijhp_^mjijb_fZbihkuedbk\yaZghk\hafh`guf\hagbdgh\_gb_flmibdh\hckblmZpbbIj_^iheh`bfqlhjZ[hlZxl^\Z iZjZee_evguoijhp_kkZbhgb^he`guh[f_gylvky^Zggufb;ueh[u\iheg_ _kl_kl\_ggh \ dZ`^hf ijhp_kk_ kgZqZeZ \hkihevah\Zlvky ijhp_^mjhc MPI_SENDZaZl_fijhp_^mjhcMPI_RECV.Ghbf_gghwlh]hbg_klhbl^_eZlv >_eh \ lhfqlhfuaZjZg__g_agZ_fdZdj_Zebah\ZgZijhp_^mjZ MPI_SEND. ?keb jZajZ[hlqbdb ^ey ]ZjZglbb dhjj_dlgh]h ih\lhjgh]h bkihevah\Zgby [mn_jZ ihkuedb aZeh`beb ko_fm ijb dhlhjhc ihkueZxsbc ijhp_kk `^_l gZqZeZijb_fZlh\hagbdg_ldeZkkbq_kdbclmibdI_j\ucijhp_kkg_fh`_l \_jgmlvky ba ijhp_^mju ihkuedb ihkdhevdm \lhjhc g_ gZqbgZ_l ijb_f khh[s_gby:\lhjhcijhp_kkg_fh`_lgZqZlvijb_fkhh[s_gbyihkdhevdm kZfihihoh`_cijbqbg_aZkljyegZihkued_ ?s_om`_kblmZpbydh]^Zh[Zijhp_kkZkgZqZeZihiZ^ZxlgZ[ehdbjmxsmx ijhp_^mjm ijb_fZ MPI_RECV Z ebrv aZl_f gZ ihkuedm ^Zgguo < lZdhf kemqZ_lmibd\hagbdg_lg_aZ\bkbfhhlkihkh[Zj_ZebaZpbbijhp_^mjijb_fZ bihkuedb^Zgguo ijhp_kk0:
ijhp_kk1:
MPI_RECVhlijhp_kkZ MPI_SENDijhp_kkm
MPI_RECVhlijhp_kkZ MPI_SENDijhp_kkm
ijhp_kk0:
ijhp_kk1:
MPI_SENDijhp_kkm MPI_RECVhlijhp_kkZ
MPI_SENDijhp_kkm MPI_RECVhlijhp_kkZ
Fh`_l \hagbdgmlv lmibd
JZkkfhljbfjZaebqgu_kihkh[ujZaj_r_gbylmibdh\uokblmZpbc 1. Ijhkl_crbf\ZjbZglhfjZaj_r_gbylmibdh\hckblmZpbb[m^_lbaf_g_gb_ ihjy^dZ ke_^h\Zgby ijhp_^mj ihkuedb b ijb_fZ khh[s_gby gZ hghf ba ijhp_kkh\dZdihdZaZghgb`_ ijhp_kk0:
ijhp_kk1:
MPI_SENDijhp_kkm MPI_RECVhlijhp_kkZ
MPI_RECVhlijhp_kkZ MPI_SENDijhp_kkm
32
Lmibd g_\hagbdZ_l
2. >jm]bf \ZjbZglhf jZaj_r_gby lmibdh\hc kblmZpbb fh`_l [ulv bkihevah\Zgb_ g_[ehdbjmxsbo hi_jZpbc AZf_gbf \uah\ ijhp_^mju ijb_fZkhh[s_gbyk[ehdbjh\dhcgZ\uah\ijhp_^mju MPI_IRECVJZkiheh`bf _]h i_j_^ \uah\hf ijhp_^mju MPI_SEND l_ ij_h[jZam_f njZ]f_glke_^mxsbfh[jZahf Ijhp_kk0:
ijhp_kk1:
MPI_SENDijhp_kkm MPI_RECVhlijhp_kkZ
MPI_IRECVhlijhp_kkZ MPI_SENDijhp_kkm MPI_WAIT
Lmibd g_\hagbdZ_l
< lZdhc kblmZpbb lmibd ]ZjZglbjh\Zggh g_ \hagbdg_l ihkdhevdm d fhf_glm\uah\Zijhp_^mjuMPI_SEND aZijhkgZijb_fkhh[s_gbym`_[m^_l \uklZ\e_g Z agZqbl i_j_^ZqZ ^Zgguo fh`_l gZqZlvky Ijb wlhf j_dhf_g^m_lky\uklZ\eylvijhp_^mjm MPI_IRECV\ijh]jZff_dZdfh`gh jZgvr_ qlh[u jZgvr_ ij_^hklZ\blv \hafh`ghklv gZqZeZ i_j_kuedb b fZdkbfZevghbkihevah\Zlvij_bfms_kl\ZZkbgojhgghklb 3. Lj_lvbf \ZjbZglhf jZaj_r_gby lmibdh\hc kblmZpbb fh`_l [ulv bkihevah\Zgb_ijhp_^mjuMPI_SENDRECV. MPI_SENDRECV(SBUF, SCOUNT, STYPE, DEST, STAG, RBUF, RCOUNT, RTYPE, SOURCE, RTAG, COMM, STATUS, IERR)
Ijhp_^mjZ \uihegy_l kh\f_s_ggu_ ijb_f b i_j_^Zqm khh[s_gbc k [ehdbjh\dhc Ih \uah\m ^Zgghc ijhp_^mju hkms_kl\ey_lky ihkuedZ SCOUNT we_f_glh\ lbiZ STYPE ba fZkkb\Z SBUF k l_]hf STAG ijhp_kkm k ghf_jhf DEST \ dhffmgbdZlhj_ COMM b ijb_f \ fZkkb\ RBUF g_ [he__ RCOUNTwe_f_glh\lbiZRTYPE kl_]hfRTAGhlijhp_kkZkghf_jhfSOURCE \ dhffmgbdZlhj_ COMM >ey ijbgbfZ_fh]h khh[s_gby aZihegy_lky iZjZf_lj STATUS IjbgbfZxsbc b hlijZ\eyxsbc ijhp_kku fh]ml y\eylvky h^gbf b l_f `_ ijhp_kkhf ;mn_ju i_j_^Zqb b ijb_fZ ^Zgguo g_ ^he`gu i_j_k_dZlvky =ZjZglbjm_lky qlh ijb wlhf lmibdh\hc kblmZpbb g_ \hagbdZ_l Khh[s_gb_ hlijZ\e_ggh_ hi_jZpb_c MPI_SENDRECV fh`_l [ulv ijbgylh h[uqguf h[jZahf b hi_jZpby MPI_SENDRECV fh`_l ijbgylv khh[s_gb_ hlijZ\e_ggh_ h[uqghc hi_jZpb_c
33
MPI_SENDRECV_REPLACE(BUF, COUNT, DATATYPE, DEST, STAG, SOURCE, RTAG, COMM, STATUS, IERR)
Kh\f_s_ggu_ ijb_f b i_j_^ZqZ khh[s_gbc k [ehdbjh\dhc q_j_a h[sbc [mn_jBUFIjbgbfZ_fh_khh[s_gb_g_^he`ghij_\urZlvihjZaf_jmhlijZ\ey_fh_ khh[s_gb_ Z i_j_^Z\Z_fu_ b ijbgbfZ_fu_ ^Zggu_ ^he`gu [ulvh^gh]hlbiZ <ke_^mxs_fijbf_j_hi_jZpbb^\mgZijZ\e_ggh]hh[f_gZkkhk_^gbfbijhp_kkZfb\dhevp_\hclhiheh]bbijhba\h^ylkyijbihfhsb^\mo\uah\h\ijhp_^mjuMPI_SENDRECVIjbwlhf]ZjZglbjh\Zgghg_\hagbdZ_llmibdh\hckblmZpbb program example12 include 'mpif.h' integer ierr, rank, size, prev, next, buf(2) integer status1(MPI_STATUS_SIZE), status2(MPI_STATUS_SIZE) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) prev = rank - 1 next = rank + 1 if(rank .eq. 0) prev = size - 1 if(rank .eq. size - 1) next = 0 call MPI_SENDRECV(rank, 1, MPI_INTEGER, prev, 6, & buf(2), 1, MPI_INTEGER, next, 6, & MPI_COMM_WORLD, status2, ierr) call MPI_SENDRECV(rank, 1, MPI_INTEGER, next, 5, & buf(1), 1, MPI_INTEGER, prev, 5, & MPI_COMM_WORLD, status1, ierr) print *, ‘process ’, rank, & ‘ prev=’, buf(1), ‘ next=’, buf(2) call MPI_FINALIZE(ierr) end
AZ^Zgby • DZdbfbZljb[mlZfbh[eZ^Z_l\MPIdZ`^h_ihkueZ_fh_khh[s_gb_" • Fh`ghebkhh[s_gb_hlijZ\e_ggh_kihfhsvx[ehdbjmxs_chi_jZpbbihkuedbijbgylvg_[ehdbjmxs_chi_jZpb_cijb_fZ" • Qlh]ZjZglbjm_l[ehdbjh\dZijbhlijZ\d_ijb_f_khh[s_gbc" • Fh`gh eb \ dZq_kl\_ l_]h\ ijb ihkued_ jZaebqguo khh[s_gbc \ ijh]jZff_\k_]^Zbkihevah\Zlvh^ghblh`_qbkeh" • DZdijbgylvex[h_khh[s_gb_hlex[h]hijhp_kkZ"
34
• DZd ijbgbfZxsbc ijhp_kk fh`_l hij_^_eblv ^ebgm ihemq_ggh]h khh[s_gby" • Fh`gh eb ijb ihkued_ khh[s_gby bkihevah\Zlv dhgklZglu MPI_ANY_SOURCEbMPI_ANY_TAG? • Fh`ghebg_ijbgbfZykhh[s_gbyhij_^_eblv_]hZljb[mlu" • ;m^_lebdhjj_dlgZijh]jZffZ\dhlhjhcihkueZxsbcijhp_kkmdZau\Z_l \ dZq_kl\_ ^ebgu [mn_jZ qbkeh 10 Z ijbgbfZxsbc ijhp_kk qbkeh 20" ?keb ^Z lh kdhevdh we_f_glh\ fZkkb\Z [m^_l j_Zevgh i_j_keZghf_`^mijhp_kkZfb" • KjZ\gblvwnn_dlb\ghklvj_ZebaZpbbjZaebqguo\b^h\i_j_kuehd^Zgguok[ehdbjh\dhcMPI_SEND, MPI_BSEND, MPI_SSEND, MPI_RSEND f_`^m^\mfy\u^_e_ggufbijhp_kkhjZfb • Qlh hagZqZ_l aZ\_jr_gb_ hi_jZpbb ^ey jZaebqguo \b^h\ i_j_kuedb ^Zgguok[ehdbjh\dhc" • Hij_^_eblv fZdkbfZevgh ^himklbfmx ^ebgm ihkueZ_fh]h khh[s_gby \^Zgghcj_ZebaZpbbMPI. • J_Zebah\ZlvkdZeyjgh_ijhba\_^_gb_jZkij_^_e_gguof_`^mijhp_kkhjZfb\_dlhjh\ • KjZ\gblv wnn_dlb\ghklv j_ZebaZpbb i_j_kuehd ^Zgguo f_`^m ^\mfy \u^_e_ggufbijhp_kkhjZfbk[ehdbjh\dhcb[_a[ehdbjh\db • Hij_^_eblv \hafh`gh eb \ ^Zgghc j_ZebaZpbb MPI kh\f_s_gb_ Zkbgojhgguo i_j_kuehd ^Zgguo b \uiheg_gby Zjbnf_lbq_kdbo hi_jZpbc • DZd k ihfhsvx ijhp_^mju MPI_TEST kfh^_ebjh\Zlv nmgdpbhgZevghklvijhp_^mjuMPI_WAIT? • < q_f khklhyl jZaebqby \ bkihevah\Zgbb ijhp_^mj MPI_WAITALL, MPI_WAITANY b MPI_WAITSOME" DZd kfh^_ebjh\Zlv bo nmgdpbhgZevghklvijbihfhsbijhp_^mjuMPI_WAIT? • Qlh ijhbahc^_l ijb hkms_kl\e_gbb h[f_gZ ^Zggufb k ijhp_kkhf MPI_PROC_NULL? • J_Zebah\Zlv ijb ihfhsb ihkuedb khh[s_gbc lbiZ lhqdZ-lhqdZ ke_^mxsb_ko_fudhffmgbdZpbbijhp_kkh\ o i_j_^ZqZ^Zgguoihdhevpm^\Z\ZjbZglZwklZn_lgZyiZehqdZ hq_j_^ghc ijhp_kk ^h`b^Z_lky khh[s_gby hl ij_^u^ms_]h b ihlhfihkueZ_lke_^mxs_fm bk^\b]h^gh\j_f_ggu_ihkuedZ bijb_fkhh[s_gbc o master-VODYH \k_ ijhp_kku h[sZxlky k h^gbf \u^_e_gguf ijhp_kkhf o i_j_kuedZ^ZgguohldZ`^h]hijhp_kkZdZ`^hfm • Bkke_^h\Zlvwnn_dlb\ghklvdhffmgbdZpbhgguoko_fbaij_^u^ms_]h aZ^Zgby \ aZ\bkbfhklb hl qbkeZ bkihevah\Zgguo ijhp_kkh\ b h[t_fZ i_j_kueZ_fuo^Zgguobamqblv\hafh`ghklbhilbfbaZpbb
35
• Hij_^_eblv\ub]jurdhlhjucfh`ghihemqblvijbbkihevah\Zgbbhleh`_gguoaZijhkh\gZ\aZbfh^_ckl\b_ • KjZ\gblv wnn_dlb\ghklv j_ZebaZpbb nmgdpbb MPI_SENDRECV k fh^_ebjh\Zgb_f lhc `_ nmgdpbhgZevghklb ijb ihfhsb g_[ehdbjmxsbohi_jZpbc
Dhee_dlb\gu_\aZbfh^_ckl\byijhp_kkh\ < hi_jZpbyo dhee_dlb\gh]h \aZbfh^_ckl\by ijhp_kkh\ mqZkl\mxl \k_ ijhp_kku dhffmgbdZlhjZ Khhl\_lkl\mxsZy ijhp_^mjZ ^he`gZ [ulv \ua\ZgZ dZ`^uf ijhp_kkhf [ulv fh`_l kh k\hbf gZ[hjhf iZjZf_ljh\
Ijhp_^mjZ bkihevam_lky ^ey [Zjv_jghc kbgojhgbaZpbb ijhp_kkh\ JZ[hlZ ijhp_kkh\ [ehdbjm_lky ^h l_o ihj ihdZ \k_ hklZ\rb_ky ijhp_kku dhffmgbdZlhjZ COMM g_ \uihegyl wlm ijhp_^mjm Lhevdh ihke_ lh]h dZd ihke_^gbc ijhp_kk dhffmgbdZlhjZ \uihegbl ^Zggmx ijhp_^mjm \k_ ijhp_kku [m^ml jZa[ehdbjh\Zgu b ijh^he`Zl \uiheg_gb_ ^Zevr_ >ZggZy ijhp_^mjZ y\ey_lky dhee_dlb\ghc
MPI_BARRIER ohly j_Zevgh bkiheg_ggu_ \uah\u jZaebqgufb ijhp_kkZfb
dhffmgbdZlhjZfh]ml[ulvjZkiheh`_gu\jZaguof_klZoijh]jZffu
< ke_^mxs_f ijbf_j_ nmgdpbhgZevghklv ijhp_^mju MPI_BARRIER fh^_ebjm_lky ijb ihfhsb hleh`_gguo aZijhkh\ gZ \aZbfh^_ckl\b_ >ey mkj_^g_gby j_amevlZlh\ ijhba\h^blky NTIMES hi_jZpbc h[f_gZ \ jZfdZo dZ`^hcbagbo\k_ijhp_kku^he`guihkeZlvkhh[s_gb_ijhp_kkmkghf_jhf 0 ihke_ q_]h ihemqblv hl g_]h hl\_lguc kb]gZe hagZqZxsbc qlh \k_ ijhp_kku ^hreb ^h wlhc lhqdb \ ijh]jZff_ Bkihevah\Zgb_ hleh`_gguo aZijhkh\ iha\hey_l bgbpbZebabjh\Zlv ihkuedm ^Zgguo lhevdh h^bg jZa Z aZl_f bkihevah\Zlv gZ dZ`^hc bl_jZpbb pbdeZ >Ze__ \j_fy gZ fh^_ebjh\Zgb_ kjZ\gb\Z_lky kh \j_f_g_f gZ kbgojhgbaZpbx ijb ihfhsb kZfhcklZg^Zjlghcijhp_^mjuMPI_BARRIER. program example13 include 'mpif.h' integer ierr, rank, size, MAXPROC, NTIMES, i, it parameter (MAXPROC = 128, NTIMES = 10000) integer ibuf(MAXPROC) double precision time_start, time_finish integer req(2*MAXPROC), statuses(MPI_STATUS_SIZE, MAXPROC) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) if(rank .eq. 0) then do i = 1, size-1 call MPI_RECV_INIT(ibuf(i), 0, MPI_INTEGER, i, 5, & MPI_COMM_WORLD, req(i), ierr) call MPI_SEND_INIT(rank, 0, MPI_INTEGER, i, 6, & MPI_COMM_WORLD, req(size+i), & ierr) end do time_start = MPI_WTIME(ierr) do it = 1, NTIMES call MPI_STARTALL(size-1, req, ierr) call MPI_WAITALL(size-1, req, statuses, ierr) call MPI_STARTALL(size-1, req(size+1), ierr) call MPI_WAITALL(size-1, req(size+1), statuses, & ierr) end do else call MPI_RECV_INIT(ibuf(1), 0, MPI_INTEGER, 0, 6, & MPI_COMM_WORLD, req(1), ierr) call MPI_SEND_INIT(rank, 0, MPI_INTEGER, 0, 5, & MPI_COMM_WORLD, req(2), ierr) time_start = MPI_WTIME(ierr) do it = 1, NTIMES call MPI_START(req(2), ierr) call MPI_WAIT(req(2), statuses, ierr) call MPI_START(req(1), ierr) 37
call MPI_WAIT(req(1), statuses, ierr) end do end if time_finish = MPI_WTIME(ierr)-time_start print *, 'rank = ', rank, ' all time = ', & (time_finish)/NTIMES time_start = MPI_WTIME(ierr) do it = 1, NTIMES call MPI_BARRIER(MPI_COMM_WORLD,ierr) enddo time_finish = MPI_WTIME(ierr)-time_start print *, 'rank = ', rank, ' barrier time = ', & (time_finish)/NTIMES call MPI_FINALIZE(ierr) end MPI_BCAST(BUF, COUNT, DATATYPE, ROOT, COMM, IERR)
^he`gu[ulvh^bgZdh\ufbm\k_oijhp_kkh\
Ke_^mxsZy ko_fZ beexkljbjm_l ^_ckl\b_ ijhp_^mju MPI_BCAST A^_kv lZd`_ dZd b \ ^Zevg_crbo ko_fZo ih \_jlbdZeb bah[jZ`Zxlky jZagu_ ijhp_kkumqZkl\mxsb_\dhee_dlb\ghchi_jZpbbZih]hjbahglZeb–jZkiheh`_ggu_gZgbo[ehdb^Zgguo
GZijbf_j^eylh]hqlh[ui_j_keZlvhlijhp_kkZ 2\k_fhklZevgufijhp_kkZfijbeh`_gbyfZkkb\ bufba 100p_ehqbke_gguowe_f_glh\gm`ghqlh[u \h\k_oijhp_kkZo\klj_lbekyke_^mxsbc\uah\ 38
call MPI_BCAST(buf, 100, MPI_INTEGER, & 2, MPI_COMM_WORLD, ierr) MPI_GATHER(SBUF, SCOUNT, STYPE, RBUF, RCOUNT, RTYPE, ROOT, COMM, IERR)
\hajZklZgbyghf_jh\ijhp_kkh\
GZijhp_kk_ ROOTkms_kl\_ggufby\eyxlkyagZq_gby\k_oiZjZf_ljh\ZgZ hklZevguo ijhp_kkZo — lhevdh agZq_gby iZjZf_ljh\ SBUF, SCOUNT, STYPE, ROOTb COMMAgZq_gbyiZjZf_ljh\ ROOTbCOMM^he`gu[ulvh^bgZdh\ufbm \k_oijhp_kkh\IZjZf_lj RCOUNTmijhp_kkZ ROOTh[hagZqZ_lqbkehwe_f_glh\ lbiZ RTYPE ijbgbfZ_fuo g_ hl \k_o ijhp_kkh\ \ kmff_ Z hl dZ`^h]h ijhp_kkZ Ke_^mxsZyko_fZbeexkljbjm_l^_ckl\b_ijhp_^mjuMPI_GATHER.
GZijbf_j^eylh]hqlh[uijhp_kk2kh[jZe\fZkkb\rbufih10p_ehqbke_gguowe_f_glh\fZkkb\h\bufkh\k_oijhp_kkh\ijbeh`_gbygm`ghqlh[u\h \k_oijhp_kkZo\klj_lbekyke_^mxsbc\uah\ call MPI_GATHER(buf, 10, MPI_INTEGER, rbuf, 10, MPI_INTEGER, 2, MPI_COMM_WORLD, ierr)
& &
MPI_GATHERV(SBUF, SCOUNT, STYPE, RBUF, RCOUNTS, DISPLS, RTYPE, ROOT, COMM, IERR)
INTEGER SCOUNT, STYPE, RCOUNTS(*), DISPLS(*), RTYPE, ROOT, COMM, IERR K[hjdZjZaebqgh]hdhebq_kl\Z^ZgguobafZkkb\h\ SBUFIhjy^hdjZkiheh`_gby^Zgguo\j_amevlbjmxs_f[mn_j_RBUFaZ^Z_lfZkkb\DISPLS. RCOUNTS –p_ehqbke_ggucfZkkb\kh^_j`Zsbcdhebq_kl\hwe_f_glh\i_j_-
^Z\Z_fuohldZ`^h]hijhp_kkZbg^_dkjZ\_gjZg]mihkueZxs_]hijhp_kkZ jZaf_jfZkkb\ZjZ\_gqbkemijhp_kkh\\dhffmgbdZlhj_COMM).
DISPLS – p_ehqbke_gguc fZkkb\ kh^_j`Zsbc kf_s_gby hlghkbl_evgh gZqZeZ fZkkb\Z RBUF bg^_dk jZ\_g jZg]m ihkueZxs_]h ijhp_kkZ jZaf_j fZkkb\ZjZ\_gqbkemijhp_kkh\\dhffmgbdZlhj_COMM).
>Zggu_ihkeZggu_ijhp_kkhf J-1jZaf_sZxlky\ J-hf[ehd_[mn_jZ RBUF gZijhp_kk_ROOTdhlhjucgZqbgZ_lkykhkf_s_gb_f\DISPLS(J)we_f_glh\ lbiZRTYPEkgZqZeZ[mn_jZ MPI_SCATTER(SBUF, SCOUNT, STYPE, RBUF, RCOUNT, RTYPE, ROOT, COMM, IERR)
^_eblkygZjZ\gu_qZklbihqbkemijhp_kkh\dZ`^Zybadhlhjuokhklhblba SCOUNT we_f_glh\ lbiZ STYPE ihke_ q_]h I-y qZklv ihkueZ_lky I-1)-fm ijhp_kkm GZijhp_kk_ ROOTkms_kl\_ggufby\eyxlkyagZq_gby\k_oiZjZf_ljh\ZgZ \k_o hklZevguo ijhp_kkZo — lhevdh agZq_gby iZjZf_ljh\ RBUF, RCOUNT, RTYPE, SOURCE b COMM AgZq_gby iZjZf_ljh\ SOURCE b COMM ^he`gu [ulv h^bgZdh\ufbm\k_oijhp_kkh\ Ke_^mxsZyko_fZbeexkljbjm_l^_ckl\b_ijhp_^mjuMPI_SCATTER.
40
<ke_^mxs_fijbf_j_ijhp_kk 0hij_^_ey_lfZkkb\ sbufihke_q_]hjZkkueZ_l _]h ih h^ghfm klhe[pm \k_f aZims_gguf ijhp_kkZf ijbeh`_gby J_amevlZlgZdZ`^hfijhp_kk_jZkiheZ]Z_lky\fZkkb\_rbuf.
1
real sbuf(size, size), rbuf(size) if(rank .eq. 0) then do 1 i = 1, size do 1 j = 1, size sbuf(i, j)=... end if if (numtasks .eq. size) then call MPI_SCATTER(sbuf, size, MPI_REAL, & rbuf, size, MPI_REAL, & 0, MPI_COMM_WORLD, ierr) end if
MPI_SCATTERV(SBUF, SCOUNTS, DISPLS, STYPE, RBUF, RCOUNT, RTYPE, ROOT, COMM, IERR)
^Z\Z_fuo dZ`^hfm ijhp_kkm bg^_dk jZ\_g jZg]m Z^j_kZlZ ^ebgZ jZ\gZ qbkemijhp_kkh\\dhffmgbdZlhj_COMM).
DISPLS – p_ehqbke_gguc fZkkb\ kh^_j`Zsbc kf_s_gby hlghkbl_evgh gZqZeZfZkkb\Z SBUFbg^_dkjZ\_gjZg]mZ^j_kZlZ^ebgZjZ\gZqbkemijhp_kkh\\dhffmgbdZlhj_COMM).
>Zggu_ihkueZ_fu_ijhp_kkhfROOTijhp_kkmJ-1jZaf_s_gu\J-hf[ehd_ [mn_jZSBUFdhlhjucgZqbgZ_lkykhkf_s_gb_f\DISPLS(J)we_f_glh\lbiZ STYPEkgZqZeZ[mn_jZSBUF. 41
MPI_ALLGATHER(SBUF, SCOUNT, STYPE, RBUF, RCOUNT, RTYPE, COMM, IERR)
Ke_^mxsZyko_fZbeexkljbjm_l^_ckl\b_ijhp_^mjuMPI_ALLGATHER.
MPI_ALLGATHERV(SBUF, SCOUNT, STYPE, RBUF, RCOUNTS, DISPLS, RTYPE, COMM, IERR)
Ke_^mxsZyko_fZbeexkljbjm_l^_ckl\b_ijhp_^mjuMPI_ALLTOALL.
42
MPI_ALLTOALLV(SBUF, SCOUNTS, SDISPLS, STYPE, RBUF, RCOUNTS, RDISPLS, RTYPE, COMM, IERR)
^Zgguo \k_f ijhp_kkZf ^Zggh]h dhffmgbdZlhjZ JZaf_s_gb_ ^Zgguo \ [mn_j_ SBUFhlkueZxs_]hijhp_kkZhij_^_ey_lkyfZkkb\hf SDISPLSZjZaf_s_gb_ ^Zgguo \ [mn_j_ RBUF ijbgbfZxs_]h ijhp_kkZ hij_^_ey_lky fZkkb\hfRDISPLS.
MPI_REDUCE(SBUF, RBUF, COUNT, DATATYPE, OP, ROOT, COMM, IERR)
<MPIij_^mkfhlj_gjy^ij_^hij_^_e_gguo]eh[Zevguohi_jZpbchgbaZ^Zxlkyke_^mxsbfbdhgklZglZfb • MPI_MAX, MPI_MIN – hij_^_e_gb_ fZdkbfZevgh]h b fbgbfZevgh]h agZq_gby • MPI_MINLOC, MPI_MAXLOC– hij_^_e_gb_ fZdkbfZevgh]h b fbgbfZevgh]hagZq_gbybbof_klhiheh`_gby • MPI_SUM, MPI_PROD – \uqbke_gb_ ]eh[Zevghc kmffu b ]eh[Zevgh]h ijhba\_^_gby • MPI_LAND, MPI_LOR, MPI_LXOR –eh]bq_kdb_³B´³BEB´bkdexqZxs__ ³BEB´ • MPI_BAND, MPI_BOR, MPI_BXOR –ih[blh\u_³B´³BEB´bkdexqZxs__ ³BEB´ 43
Djhf_lh]hijh]jZffbklfh`_laZ^Zlvk\hxnmgdpbx^ey\uiheg_gby]eh[Zevghchi_jZpbbijbihfhsbijhp_^mjuMPI_OP_CREATE. < ke_^mxs_f ijbf_j_ hi_jZpby ]eh[Zevgh]h kmffbjh\Zgby fh^_ebjm_lky ijb ihfhsb ko_fu k^\Zb\Zgby k bkihevah\Zgb_f i_j_kuehd ^Zgguo lbiZ lhqdZ-lhqdZWnn_dlb\ghklvlZdh]hfh^_ebjh\ZgbykjZ\gb\Z_lkykbkihevah\Zgb_fdhee_dlb\ghchi_jZpbbMPI_REDUCE. program example14 include 'mpif.h' integer ierr, rank, i, size, n, nproc parameter (n = 1 000 000) double precision time_start, time_finish double precision a(n), b(n), c(n) integer status(MPI_STATUS_SIZE) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) nproc = size do i = 1, n a(i) = 1.d0/size end do call MPI_BARRIER(MPI_COMM_WORLD, ierr) time_start = MPI_WTIME(ierr) do i = 1, n c(i) = a(i) end do do while (nproc .gt. 1) if(rank .lt. nproc/2) then call MPI_RECV(b, n, MPI_DOUBLE_PRECISION, & nproc-rank-1, 1, MPI_COMM_WORLD, & status, ierr) do i = 1, n c(i) = c(i) + b(i) end do else if(rank .lt. nproc) then call MPI_SEND(c, n, MPI_DOUBLE_PRECISION, & nproc-rank-1, 1, MPI_COMM_WORLD, ierr) end if nproc = nproc/2 end do do i = 1, n b(i) = c(i) end do time_finish = MPI_WTIME(ierr)-time_start if(rank .eq. 0) print *, 'model b(1)=', b(1) print *, 'rank=', rank, ' model time =', time_finish do i = 1, n a(i) = 1.d0/size end do call MPI_BARRIER(MPI_COMM_WORLD, ierr) 44
time_start = MPI_WTIME(ierr) call MPI_REDUCE(a, b, n, MPI_DOUBLE_PRECISION, MPI_SUM, 0, & MPI_COMM_WORLD, ierr) time_finish = MPI_WTIME(ierr)-time_start if(rank .eq. 0) print *, 'reduce b(1)=', b(1) print *, 'rank=', rank, ' reduce time =', time_finish call MPI_FINALIZE(ierr) end MPI_ALLREDUCE(SBUF, RBUF, COUNT, DATATYPE, OP, COMM, IERR)
< ke_^mxs_f ijbf_j_ dZ`^uc ijhp_kk \uqbkey_l ihkljhqgu_ kmffu we_f_glh\ehdZevgh]hfZkkb\Z aihke_q_]hihemq_ggu_kmffukh\k_oijhp_kkh\kdeZ^u\Zxlkyijbihfhsbijhp_^mjuMPI_ALLREDUCEbj_amevlZlihemqZ_lky\fZkkb\_rgZ\k_oijhp_kkZoijbeh`_gby do i = 1, n s(i) = 0.0 end do do i = 1, n do j = 1, m s(i) = s(i)+a(i, j) end do end do call MPI_ALLREDUCE(s, r, n, MPI_REAL, MPI_SUM, & MPI_COMM_WORLD, IERR) MPI_REDUCE_SCATTER(SBUF, RBUF, RCOUNTS, DATATYPE, OP, COMM, IERR)
lhfm qlh kgZqZeZ \uihegyxlky ]eh[Zevgu_ hi_jZpbb aZl_f j_amevlZl jZkkueZ_lky ih ijhp_kkZf I-uc ijhp_kk ihemqZ_l (I+1)-mx ihjpbx j_amevlZlh\ba RCOUNTS(I+1)we_f_glh\bihf_sZ_l\fZkkb\ RBUFFZkkb\ RCOUNTS ^he`_g[ulvh^bgZdh\ufgZ\k_oijhp_kkZodhffmgbdZlhjZCOMM.
45
MPI_SCAN(SBUF, RBUF, COUNT, DATATYPE, OP, COMM, IERR)
Kha^Zgb_ ihevah\Zl_evkdhc ]eh[Zevghc hi_jZpbb OP dhlhjZy [m^_l \uqbkeylvkynmgdpb_c FUNCKha^Z\Z_fZyhi_jZpby^he`gZ[ulvZkkhpbZlb\ghcZ _kebiZjZf_lj COMMUTEjZ\_g .TRUE.lhhgZ^he`gZ[ulvlZd`_bdhffmlZlb\ghc ?keb iZjZf_lj COMMUTE jZ\_g .FALSE. lh ihjy^hd \uiheg_gby ]eh[Zevghc hi_jZpbb kljh]h nbdkbjm_lky kh]eZkgh m\_ebq_gbx ghf_jh\ ijhp_kkh\gZqbgZykijhp_kkZkghf_jhf0. FUNCTION FUNC(INVEC(*), INOUTVEC(*), LEN, TYPE)
LZdbfh[jZahfaZ^Z_lkybgl_jn_ckihevah\Zl_evkdhcnmgdpbb^eykha^Zgby ]eh[Zevghc hi_jZpbb I_j\uc Zj]mf_gl hi_jZpbb [_j_lky ba iZjZf_ljZ INVEC\lhjhcZj]mf_gl–baiZjZf_ljZINOUTVECZj_amevlZl\ha\jZsZ_lky\ iZjZf_lj_ INOUTVECIZjZf_lj LENaZ^Z_ldhebq_kl\hwe_f_glh\\oh^gh]hb \uoh^gh]hfZkkb\h\ZiZjZf_lj TYPE –lbi\oh^guob\uoh^guo^Zgguo< ihevah\Zl_evkdhc nmgdpbb g_ ^he`gu ijhba\h^blvky gbdZdb_ h[f_gu ^Zggufbkbkihevah\Zgb_f\uah\h\ijhp_^mjMPI. MPI_OP_FREE(OP, IERR) INTEGER OP, IERR
Mgbqlh`_gb_ ihevah\Zl_evkdhc ]eh[Zevghc hi_jZpbb Ih \uiheg_gbb ijhp_^mjui_j_f_gghcOPijbk\Zb\Z_lkyagZq_gb_MPI_OP_NULL. Ke_^mxsbc ijbf_j ^_fhgkljbjm_l aZ^Zgb_ ihevah\Zl_evkdhc nmgdpbb ^ey bkihevah\Zgby \ dZq_kl\_ ]eh[Zevghc hi_jZpbb AZ^Z_lky nmgdpby smod5, \uqbkeyxsZy ihwe_f_glgmx kmffm ih fh^mex 5 \_dlhjh\ p_ehqbke_gguo Zj]mf_glh\>ZggZynmgdpbyh[ty\ey_lky\dZq_kl\_]eh[Zevghchi_jZpbbop \ \uah\_ ijhp_^mju MPI_OP_CREATE aZl_f bkihevam_lky \ ijhp_^mj_ MPI_REDUCE ihke_ q_]h m^Zey_lky k ihfhsvx \uah\Z ijhp_^mju MPI_OP_FREE. program example15 46
include 'mpif.h' integer ierr, rank, i, n parameter (n = 1 000) integer a(n), b(n) integer op external smod5 call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) do i = 1, n a(i) = i + rank end do print *, 'process ', rank, ' a(1) =', a(1) call MPI_OP_CREATE(smod5, .TRUE., op, ierr) call MPI_REDUCE(a, b, n, MPI_INTEGER, op, 0, & MPI_COMM_WORLD, ierr) call MPI_OP_FREE(op, ierr) if(rank .eq. 0) print *, ' b(1) =', b(1) call MPI_FINALIZE(ierr) end integer function smod5(in, inout, l, type) integer l, type integer in(l), inout(l), i do i = 1, l inout(i) = mod(in(i)+inout(i), 5) end do return end
AZ^Zgby • Q_f dhee_dlb\gu_ hi_jZpbb hlebqZxlky hl \aZbfh^_ckl\bc lbiZ lhqdZ-lhqdZ" • <_jgh eb qlh \ dhee_dlb\guo \aZbfh^_ckl\byo mqZkl\mxl \k_ ijhp_kkuijbeh`_gby? • Fh]mleb\hagbdZlvdhgnebdluf_`^mh[uqgufbkhh[s_gbyfbihkueZ_fufbijhp_kkZfb^jm]^jm]mbkhh[s_gbyfbdhee_dlb\guohi_jZpbc"?keb^ZdZdhgbjZaj_rZxlky" • Fh`gh eb ijb ihfhsb ijhp_^mju MPI_RECV ijbgylv khh[s_gb_ ihkeZggh_ijhp_^mjhcMPI_BCAST? • Kfh^_ebjh\Zlv [Zjv_jgmx kbgojhgbaZpbx ijb ihfhsb i_j_kuehd lhqdZ-lhqdZbkjZ\gblvwnn_dlb\ghklvlZdhcj_ZebaZpbbbklZg^Zjlghc ijhp_^mjuMPI_BARRIER. • < q_f jZaebqb_ \ nmgdpbhgZevghklb ijhp_^mj MPI_BCAST b MPI_SCATTER? • Kfh^_ebjh\Zlv]eh[Zevgh_kmffbjh\Zgb_f_lh^hfk^\Zb\ZgbybkjZ\gblv wnn_dlb\ghklv lZdhc j_ZebaZpbb k bkihevah\Zgb_f klZg^Zjlghc ijhp_^mjuMPI_REDUCE. 47
• Kfh^_ebjh\Zlv ijhp_^mjm MPI_ALLREDUCE ijb ihfhsb ijhp_^mj MPI_REDUCEbMPI_BCAST. • GZibrbl_k\hc\ZjbZglijhp_^mjuMPI_GATHERbkihevamynmgdpbbihkuedbkhh[s_gbclbiZlhqdZ-lhqdZ • Ih^mfZcl_ dZd hj]Zgbah\Zlv dhee_dlb\guc Zkbgojhgguc h[f_g ^ZggufbZgZeh]bqgucnmgdpbbZ MPI_REDUCE[ MPI_ALLTOALL. • Bkke_^h\Zlv fZkrlZ[bjm_fhklv aZ\bkbfhklv \j_f_gb \uiheg_gby hl qbkeZ ijhp_kkh\ jZaebqguo dhee_dlb\guo hi_jZpbc gZ dhgdj_lghc kbkl_f_
=jmiiubdhffmgbdZlhju < MPI kms_kl\mxl rbjhdb_ \hafh`ghklb ^ey hi_jZpbc gZ^ ]jmiiZfb ijhp_kkh\bdhffmgbdZlhjZfbWlh[u\Z_lg_h[oh^bfh\h-i_j\uoqlh[u^Zlv \hafh`ghklv g_dhlhjhc ]jmii_ ijhp_kkh\ jZ[hlZlv gZ^ k\h_c g_aZ\bkbfhc ih^aZ^Zq_c
48
MPI_COMM_GROUP(COMM, GROUP, IERR) INTEGER COMM, GROUP, IERR Ihemq_gb_ ]jmiiu GROUP khhl\_lkl\mxs_c dhffmgbdZlhjm COMM < yaud_ KbiZjZf_lj GROUPbf__lij_^hij_^_e_gguclbi MPI_GroupIhkdhevdmba-
gZqZevgh
kms_kl\m_l _^bgkl\_gguc g_ljb\bZevguc dhffmgbdZlhj MPI_COMM_WORLD kgZqZeZ gm`gh ihemqblv khhl\_lkl\mxsmx _fm ]jmiim ijhp_kkh\Wlhfh`ghk^_eZlvijbihfhsbke_^mxs_]h\uah\Z call MPI_COMM_GROUP(MPI_COMM_WORLD, group, ierr) MPI_GROUP_INCL(GROUP, N, RANKS, NEWGROUP, IERR) INTEGER GROUP, N, RANKS(*), NEWGROUP, IERR Kha^Zgb_]jmiiu NEWGROUPba Nijhp_kkh\ij_`g_c]jmiiu GROUPkjZg]Zfb RANKS(1),…,RANKS(N) ijbq_f jZg]m RANKS(I) \ klZjhc ]jmii_ khhl\_lkl\m_l jZg] I-1 \ gh\hc ]jmii_ Ijb N=0 kha^Z_lky imklZy ]jmiiZ MPI_GROUP_EMPTY
\h]hihjy^dZijhp_kkh\\]jmii_
MPI_GROUP_EXCL(GROUP, N, RANKS, NEWGROUP, IERR) INTEGER GROUP, N, RANKS(*), NEWGROUP, IERR Kha^Zgb_]jmiiu NEWGROUPbaijhp_kkh\]jmiiu GROUPbkdexqZyijhp_kku k jZg]Zfb RANKS(1),…,RANKS(N) ijbq_f ihjy^hd hklZ\rboky ijhp_kkh\ \ gh\hc ]jmii_ khhl\_lkl\m_l ihjy^dm ijhp_kkh\ \ klZjhc ]jmii_ Ijb N=0
kha^Z_lky]jmiiZb^_glbqgZyklZjhc]jmii_
< ke_^mxs_f ijbf_j_ kha^Z_lky ^\_ g_i_j_k_dZxsboky ]jmiiu ijhp_kkh\ group1b group2gZhkgh\_ijhp_kkh\]jmiiu group<dZ`^mxbakha^Z\Z_fuo ]jmii \hc^_l ijbf_jgh iheh\bgZ ijhp_kkh\ ij_`g_c ]jmiiu ijb g_q_lghf qbke_ ijhp_kkh\ \ ]jmiim group2 \hc^_l gZ h^bg ijhp_kk [hevr_ Ihjy^hdgmf_jZpbbijhp_kkh\\h\gh\vkha^Z\Z_fuo]jmiiZokhojZgblky size1 = size/2 do i = 1, size1 ranks(i) = i-1 enddo call MPI_GROUP_INCL(group, size1, ranks, group1, ierr) call MPI_GROUP_EXCL(group, size1, ranks, group2, ierr)
Ke_^mxsb_ ljb ijhp_^mju hij_^_eyxl hi_jZpbb gZ^ ]jmiiZfb ijhp_kkh\ dZd gZ^fgh`_kl\ZfbBa-aZhkh[_gghkl_cgmf_jZpbbijhp_kkh\gbh[t_^bg_gb_gbi_j_k_q_gb_]jmiig_dhffmlZlb\gughZkkhpbZlb\gu MPI_GROUP_INTERSECTION(GROUP1, GROUP2, NEWGROUP, IERR) INTEGER GROUP1, GROUP2, NEWGROUP, IERR Kha^Zgb_ ]jmiiu NEWGROUP ba i_j_k_q_gby ]jmii GROUP1 b GROUP2 Ihemq_ggZy ]jmiiZ kh^_j`bl \k_ ijhp_kku ]jmiiu GROUP1 \oh^ysb_ lZd`_ \ ]jmiimGROUP2bmihjy^hq_ggu_dZd\i_j\hc]jmii_ 49
MPI_GROUP_UNION(GROUP1, GROUP2, NEWGROUP, IERR) INTEGER GROUP1, GROUP2, NEWGROUP, IERR Kha^Zgb_ ]jmiiu NEWGROUP ba h[t_^bg_gby ]jmii GROUP1 b GROUP2 Ihemq_ggZy]jmiiZkh^_j`bl\k_ijhp_kku]jmiiu GROUP1\ij_`g_fihjy^d_aZ dhlhjufbke_^mxlijhp_kku]jmiiu GROUP2g_\hr_^rb_\]jmiim GROUP1,
lZd`_\ij_`g_fihjy^d_
MPI_GROUP_DIFFERENCE(GROUP1, GROUP2, NEWGROUP, IERR) INTEGER GROUP1, GROUP2, NEWGROUP, IERR Kha^Zgb_]jmiiu NEWGROUPbajZaghklb]jmii GROUP1b GROUP2Ihemq_ggZy ]jmiiZkh^_j`bl\k_we_f_glu]jmiiuGROUP1g_\oh^ysb_\]jmiimGROUP2
bmihjy^hq_ggu_dZd\i_j\hc]jmii_
GZijbf_jimklv\]jmiim gr1\oh^ylijhp_kku 0, 1, 2, 4, 5Z\]jmiim gr2 ijhp_kku 0, 2, 3 gmf_jZpby ijhp_kkh\ aZ^ZgZ \ ]jmii_ khhl\_lkl\mxs_c dhffmgbdZlhjmMPI_COMM_WORLD Lh]^Zihke_\uah\h\ call MPI_GROUP_INTERSECTION(gr1, gr2, newgr1, ierr) call MPI_GROUP_UNION(gr1, gr2, newgr2, ierr) call MPI_GROUP_DIFFERENCE(gr1, gr2, newgr3, ierr)
\]jmiimnewgr1\oh^ylijhp_kku0, 2; \]jmiimnewgr2\oh^ylijhp_kku0, 1, 2, 4, 5, 3; \]jmiimnewgr3\oh^ylijhp_kku1, 4, 5. Ihjy^hdgmf_jZpbbijhp_kkh\\ihemq_gguo]jmiiZokhhl\_lkl\m_lihjy^dm boi_j_qbke_gby MPI_GROUP_SIZE(GROUP, SIZE, IERR) INTEGER GROUP, SIZE, IERR Hij_^_e_gb_dhebq_kl\ZSIZEijhp_kkh\\]jmii_GROUP. MPI_GROUP_RANK(GROUP, RANK, IERR) INTEGER GROUP, RANK, IERR Hij_^_e_gb_ghf_jZijhp_kkZRANK\]jmii_GROUP?keb\ua\Z\rbcijhp_kk g_\oh^bl\]jmiimGROUPlh\ha\jZsZ_lkyagZq_gb_MPI_UNDEFINED. MPI_GROUP_TRANSLATE_RANKS(GROUP1, N, RANKS1, GROUP2, RANKS2, IERR) INTEGER GROUP1, N, RANKS1(*), GROUP2, RANKS2(*), IERR <fZkkb\_ RANKS2\ha\jZsZxlkyjZg]b\]jmii_ GROUP2ijhp_kkh\kjZg]Zfb RANKS1 \ ]jmii_ GROUP1 IZjZf_lj N aZ^Z_l qbkeh ijhp_kkh\ ^ey dhlhjuo
gm`ghhij_^_eblvjZg]b
MPI_GROUP_COMPARE(GROUP1, GROUP2, RESULT, IERR) INTEGER GROUP1, GROUP2, RESULT, IERR 50
KjZ\g_gb_]jmiiGROUP1bGROUP2?keb]jmiiuGROUP1bGROUP2iheghklvx kh\iZ^Zxl lh \ iZjZf_lj_ RESULT \ha\jZsZ_lky agZq_gb_ MPI_IDENT ?keb ]jmiiu hlebqZxlky lhevdh jZg]Zfb ijhp_kkh\ lh \ha\jZsZ_lky agZq_gb_ MPI_SIMILARBgZq_\ha\jZsZ_lkyagZq_gb_MPI_UNEQUAL. MPI_GROUP_FREE(GROUP, IERR) INTEGER GROUP, IERR Mgbqlh`_gb_ ]jmiiu GROUP. Ihke_ \uiheg_gby ijhp_^mju i_j_f_ggZy GROUPijbgbfZ_lagZq_gb_ MPI_GROUP_NULL?kebkwlhc]jmiihcdfhf_glm
\uah\Z ijhp_^mju m`_ \uihegy_lky dZdZy-lh hi_jZpby lh hgZ [m^_l aZ\_jr_gZ
<ke_^mxs_fijbf_j_\k_ijhp_kkuijbeh`_gbyjZa[b\ZxlkygZ^\_g_i_j_k_dZxsb_kyijbf_jghjZ\gu_]jmiiugroup1bgroup2Ijbg_q_lghfqbke_ ijhp_kkh\ \ ]jmii_ group2fh`_lhdZaZlvkygZh^bgijhp_kk[hevr_lh]^Z ihke_^gbcijhp_kkba^Zgghc]jmiiug_^he`_gh[f_gb\Zlvky^Zggufbgbk h^gbf ijhp_kkhf ba ]jmiiu group1 K ihfhsvx \uah\h\ ijhp_^mju MPI_GROUP_TRANSLATE_RANKSdZ`^ucijhp_kkgZoh^blijhp_kkkl_f`_ghf_jhf\^jm]hc]jmii_bh[f_gb\Z_lkykgbfkhh[s_gb_fq_j_adhffmgbdZlhj MPI_COMM_WORLDijbihfhsb\uah\Zijhp_^mju MPI_SENDRECV<dhgp_ ijh]jZffu g_ gm`gu_ ^Ze__ ]jmiiu mgbqlh`Zxlky k ihfhsvx \uah\h\ ijhp_^mjMPI_GROUP_FREE. program example16 include 'mpif.h' integer ierr, rank, i, size, size1 integer a(4), b(4) integer status(MPI_STATUS_SIZE) integer group, group1, group2 integer ranks(128), rank1, rank2, rank3 call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_COMM_GROUP(MPI_COMM_WORLD, group, ierr) size1 = size/2 do i = 1, size1 ranks(i) = i-1 enddo call MPI_GROUP_INCL(group, size1, ranks, group1, ierr) call MPI_GROUP_EXCL(group, size1, ranks, group2, ierr) call MPI_GROUP_RANK(group1, rank1, ierr) call MPI_GROUP_RANK(group2, rank2, ierr) if (rank1 .eq. MPI_UNDEFINED) then if(rank2 .lt. size1) then call MPI_GROUP_TRANSLATE_RANKS(group1, 1, rank2, & group, rank3, ierr) else rank3 = MPI_UNDEFINED end if 51
else call MPI_GROUP_TRANSLATE_RANKS(group2, 1, rank1, & group, rank3, ierr) end if a(1) = rank a(2) = rank1 a(3) = rank2 a(4) = rank3 if (rank3 .ne. MPI_UNDEFINED) then call MPI_SENDRECV(a, 4, MPI_INTEGER, rank3, 1, & b, 4, MPI_INTEGER, rank3, 1, & MPI_COMM_WORLD, status, ierr) end if call MPI_GROUP_FREE(group, ierr) call MPI_GROUP_FREE(group1, ierr) call MPI_GROUP_FREE(group2, ierr) print *, 'process ', rank, ' a=', a, ' b=', b call MPI_FINALIZE(ierr) end
Hi_jZpbbkdhffmgbdZlhjZfb DhffmgbdZlhjij_^hklZ\ey_lhl^_evgucdhgl_dklh[f_gZijhp_kkh\g_dhlhjhc]jmiiuDhgl_dklh[_ki_qb\Z_l\hafh`ghklvg_aZ\bkbfuoh[f_gh\^ZggufbDZ`^hc]jmii_ijhp_kkh\fh`_lkhhl\_lkl\h\Zlvg_kdhevdhdhffmgbdZlhjh\ghdZ`^ucdhffmgbdZlhj\ex[hcfhf_gl\j_f_gbh^ghagZqghkhhl\_lkl\m_llhevdhh^ghc]jmii_ Ke_^mxsb_ dhffmgbdZlhju kha^Zxlky kjZam ihke_ \uah\Z ijhp_^mju MPI_INIT: • MPI_COMM_WORLD –dhffmgbdZlhjh[t_^bgyxsbc\k_ijhp_kkuijbeh`_gby • MPI_COMM_NULL –agZq_gb_bkihevam_fh_^eyhrb[hqgh]hdhffmgbdZlhjZ • MPI_COMM_SELF –dhffmgbdZlhj\dexqZxsbclhevdh\ua\Z\rbcijhp_kk Kha^Zgb_ dhffmgbdZlhjZ y\ey_lky dhee_dlb\ghc hi_jZpb_c b lj_[m_l hi_jZpbb f_`ijhp_kkgh]h h[f_gZ ihwlhfm lZdb_ ijhp_^mju ^he`gu \uau\Zlvky\k_fbijhp_kkZfbg_dhlhjh]hkms_kl\mxs_]hdhffmgbdZlhjZ MPI_COMM_DUP(COMM, NEWCOMM, IERR) INTEGER COMM, NEWCOMM, IERR Kha^Zgb_gh\h]hdhffmgbdZlhjZ NEWCOMMklhc`_]jmiihcijhp_kkh\bZljb[mlZfbqlhbmdhffmgbdZlhjZCOMM. 52
MPI_COMM_CREATE(COMM, GROUP, NEWCOMM, IERR) INTEGER COMM, GROUP, NEWCOMM, IERR Kha^Zgb_ gh\h]h dhffmgbdZlhjZ NEWCOMM ba dhffmgbdZlhjZ COMM ^ey ]jmiiu ijhp_kkh\ GROUP dhlhjZy ^he`gZ y\eylvky ih^fgh`_kl\hf ]jmiiu k\yaZgghc k dhffmgbdZlhjhf COMM
<ke_^mxs_fijbf_j_kha^Z_lky^\_gh\uo]jmiiuh^gZbadhlhjuokh^_j`bli_j\mxiheh\bgmijhp_kkh\Z\lhjZy–\lhjmxiheh\bgmIjbg_q_lghf qbke_ijhp_kkh\\h\lhjmx]jmiim\hc^_lgZh^bgijhp_kk[hevr_DZ`^Zy ]jmiiZkha^Z_lkylhevdhgZl_oijhp_kkZodhlhju_\g__\oh^yl>eydZ`^hc gh\hc ]jmiiu kha^Z_lky khhl\_lkl\mxsbc _c dhffmgbdZlhj new_comm b hi_jZpby MPI_ALLREDUCE \uihegy_lky ih hl^_evghklb ^ey ijhp_kkh\ \oh^ysbo\jZagu_]jmiiu call MPI_COMM_GROUP(MPI_COMM_WORLD, group, ierr) do i = 1, size/2 ranks(i) = i-1 end do if (rank .lt. size/2) then call MPI_GROUP_INCL(group, size/2, ranks, & new_group, ierr) else call MPI_GROUP_EXCL(group, size/2, ranks, & new_group, ierr) end if call MPI_COMM_CREATE(MPI_COMM_WORLD, new_group, & new_comm, ierr) call MPI_ALLREDUCE(sbuf, rbuf, 1, MPI_INTEGER, & MPI_SUM, new_comm, ierr) call MPI_GROUP_RANK(new_group, new_rank, ierr) print *, 'rank= ', rank, ' newrank= ', & new_rank, ' rbuf= ', rbuf
53
MPI_COMM_SPLIT(COMM, COLOR, KEY, NEWCOMM, IERR) INTEGER COMM, COLOR, KEY, NEWCOMM, IERR JZa[b_gb_ dhffmgbdZlhjZ COMM gZ g_kdhevdh gh\uo dhffmgbdZlhjh\ ih qbkemagZq_gbciZjZf_ljZ COLOR<h^bgdhffmgbdZlhjihiZ^Zxlijhp_kku kh^gbfagZq_gb_fCOLORIjhp_kkuk[hevrbfagZq_gb_fiZjZf_ljZKEYihemqZl[hevrbcjZg]\gh\hc]jmii_ijbh^bgZdh\hfagZq_gbbiZjZf_ljZKEY
ihjy^hdgmf_jZpbbijhp_kkh\\u[bjZ_lkykbkl_fhc
Ijhp_kkudhlhju_g_^he`gu\hclb\gh\u_dhffmgbdZlhjumdZau\Zxl\ dZq_kl\_ iZjZf_ljZ COLOR dhgklZglm MPI_UNDEFINED Bf \ iZjZf_lj_ NEWCOMM\_jg_lkyagZq_gb_MPI_COMM_NULL. < ke_^mxs_f ijbf_j_ dhffmgbdZlhj MPI_COMM_WORLD jZa[b\Z_lky gZ ljb qZklb<i_j\mx\hc^mlijhp_kkukghf_jZfb0, 3, 6bl^\h\lhjmx– 1, 4, 7 bl^Z\lj_lvx– 2, 5, 8bl^AZ^Zgb_\dZq_kl\_iZjZf_ljZKEYi_j_f_gghc rank]ZjZglbjm_lqlhihjy^hdgmf_jZpbbijhp_kkh\\kha^Z\Z_fuo]jmiiZo khhl\_lkl\m_l ihjy^dm gmf_jZpbb \ bkoh^ghc ]jmii_ lh _klv ihjy^dm i_j_qbke_gby\ur_ call MPI_COMM_SPLIT(MPI_COMM_WORLD, mod(rank, 3), rank, new_comm, ierr)
&
MPI_COMM_FREE(COMM, IERR) INTEGER COMM, IERR M^Ze_gb_ dhffmgbdZlhjZ COMM Ihke_ \uiheg_gby ijhp_^mju i_j_f_gghc COMMijbk\Zb\Z_lkyagZq_gb_MPI_COMM_NULL?kebkwlbfdhffmgbdZlhjhfd
fhf_glm\uah\Zijhp_^mjum`_\uihegy_lkydZdZy-lhhi_jZpbylhhgZ[m^_l aZ\_jr_gZ <ke_^mxs_fijbf_j_kha^Z_lkyh^bggh\ucdhffmgbdZlhjcomm_revs\dhlhjuc \oh^yl \k_ ijhp_kku ijbeh`_gby ijhgmf_jh\Zggu_ \ h[jZlghf ihjy^d_Dh]^ZdhffmgbdZlhjklZgh\blkyg_gm`gufhgm^Zey_lkyijbihfhsb \uah\Z ijhp_^mju MPI_COMM_FREE LZd fh`gh bkihevah\Zlv ijhp_^mjm MPI_COMM_SPLIT^eyi_j_gmf_jZpbbijhp_kkh\ program example17 include 'mpif.h' integer ierr, rank, size integer comm_revs, rank1 call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_COMM_SPLIT(MPI_COMM_WORLD, 1, size-rank, & comm_revs, ierr) call MPI_COMM_RANK(comm_revs, rank1, ierr) print *, 'rank = ', rank,' rank1 = ', rank1 call MPI_COMM_FREE(comm_revs, ierr) 54
call MPI_FINALIZE(ierr) end
AZ^Zgby • DZdb_]jmiiuijhp_kkh\kms_kl\mxlijbaZimkd_ijbeh`_gby" • Fh]mleb]jmiiuijhp_kkh\bf_lvg_imklh_i_j_k_q_gb_g_kh\iZ^Zxs__gbkh^ghcbagboiheghklvx" • <q_fhlebqb_f_`^m]jmiihcijhp_kkh\bdhffmgbdZlhjhf" • Fh]ml eb h[f_gb\Zlvky ^Zggufb ijhp_kku ijbgZ^e_`Zsb_ jZaguf dhffmgbdZlhjZf" • Fh`_leb\dZdhc-lh]jmii_g_[ulvijhp_kkZkghf_jhf0? • Fh`_l eb \ dZdmx-eb[h ]jmiim g_ \hclb ijhp_kk k ghf_jhf 0 \ dhffmgbdZlhj_MPI_COMM_WORLD? • Fh`_leblhevdhh^bgijhp_kk\g_dhlhjhc]jmii_\ua\Zlvijhp_^mjm MPI_GROUP_INCL? • DZd kha^Zlv gh\mx ]jmiim ba ijhp_kkh\ 3, 4 b 7 dhffmgbdZlhjZ MPI_COMM_WORLD? • JZa[blv \k_ ijhp_kku ijbeh`_gby gZ ljb ijhba\hevguo ]jmiiu b gZi_qZlZlv jZg]b \ MPI_COMM_WORLD l_o ijhp_kkh\ qlh ihiZeb \ i_j\u_^\_]jmiiughg_ihiZeb\lj_lvx • DZdb_dhffmgbdZlhjukms_kl\mxlijbaZimkd_ijbeh`_gby" • Fh`gh eb \ ijhp_kk_ \uiheg_gby ijh]jZffu baf_gblv qbkeh ijhp_kkh\\dhffmgbdZlhj_MPI_COMM_WORLD? • Fh`_l eb lhevdh h^bg ijhp_kk \ g_dhlhjhf dhffmgbdZlhj_ \ua\Zlv ijhp_^mjmMPI_COMM_CREATE? • Fh`gh eb ijb ihfhsb ijhp_^mju MPI_COMM_SPLIT kha^Zlv jh\gh h^bggh\ucdhffmgbdZlhj" • Fh`gh eb ijb ihfhsb ijhp_^mju MPI_COMM_SPLIT kha^Zlv klhevdh gh\uo dhffmgbdZlhjh\ kdhevdh ijhp_kkh\ \oh^bl \ [Zah\uc dhffmgbdZlhj" • J_Zebah\Zlv jZa[b_gb_ ijhp_kkh\ gZ ^\_ ]jmiiu \ h^ghc ba dhlhjuo hkms_kl\ey_lkyh[f_g^ZggufbihdhevpmZ\^jm]hc–dhffmgbdZpbb ihko_f_PDVWHU-slave.
b lZdbf h[jZahf ijb[eb`_gby iZjZee_evghc ijh]jZffu d kljmdlmj_ fZl_fZlbq_kdh]h Ze]hjblfZ Djhf_ lh]h lhiheh]by fh`_l bkihevah\Zlvky kbkl_fhc ^ey hilbfbaZpbb jZkij_^_e_gby ijhp_kkh\ ih nbabq_kdbf ijhp_kkhjZf bkihevam_fh]h iZjZee_evgh]h dhfivxl_jZ ijb ihfhsb baf_g_gbyihjy^dZgmf_jZpbbijhp_kkh\\gmljbdhffmgbdZlhjZ <MPIij_^mkfhlj_gu^\ZlbiZlhiheh]bc • ^_dZjlh\Z lhiheh]by jZaf_jghklb • lhiheh]by]jZnZ.
ijyfhm]hevgZy
j_r_ldZ
ijhba\hevghc
MPI_TOPO_TEST(COMM, TYPE, IERR) INTEGER COMM, TYPE, IERR
Ijhp_^mjZhij_^_e_gbylbiZlhiheh]bbk\yaZgghckdhffmgbdZlhjhf COMM.
^ey hilbfbaZpbb jZkij_^_e_gby ijhp_kkh\ ih nbabq_kdbf ijhp_kkhjZf bkihevam_fh]hiZjZee_evgh]hdhfivxl_jZ
Ijhp_^mjZ y\ey_lky dhee_dlb\ghc Z agZqbl ^he`gZ [ulv \ua\ZgZ \k_fb ijhp_kkZfb dhffmgbdZlhjZ COMM ?keb dhebq_kl\h ijhp_kkh\ \ aZ^Z\Z_fhc lhiheh]bb COMM_CART f_gvr_ qbkeZ ijhp_kkh\ \ bkoh^ghf dhffmgbdZlhj_ KHFFlhg_dhlhjufijhp_kkZffh`_l\_jgmlvkyagZq_gb_ MPI_COMM_NULLZ agZqblhgbg_[m^mlijbgbfZlvmqZklby\kha^Z\Z_fhclhiheh]bb?kebdh56
ebq_kl\h ijhp_kkh\ \ aZ^Z\Z_fhc lhiheh]bb [hevr_ qbkeZ ijhp_kkh\ \ bkoh^ghfdhffmgbdZlhj_lh\uah\[m^_lhrb[hqguf <ke_^mxs_fijbf_j_kha^Z_lkylj_of_jgZylhiheh]by 4×3×2dZ`^h_baf_j_gb_dhlhjhcy\ey_lkyi_jbh^bq_kdbfdjhf_lh]hjZaj_rZ_lkyi_j_mihjy^hq_gb_ijhp_kkh\>ZggucnjZ]f_gl^he`_g\uihegylvkyg_f_g__q_fgZ 24ijhp_kkZo dims(1) = 4 dims(2) = 3 dims(3) = 2 periods(1) = .TRUE. periods(2) = .TRUE. periods(3) = .TRUE. call MPI_CART_CREATE(MPI_COMM_WORLD, 3, dims, periods, & .TRUE., comm_cart, ierr) MPI_DIMS_CREATE(NNODES, NDIMS, DIMS, IERR) INTEGER NNODES, NDIMS, DIMS(*), IERR Ijhp_^mjZihfh]Z_lhij_^_eblvjZaf_ju DIMS(I)^eydZ`^hcba NDIMSjZaf_jghkl_cijbkha^Zgbb^_dZjlh\hclhiheh]bb^ey NNODESijhp_kkh\Ij_^-
ihqlbl_evgufkqblZ_lkykha^Zgb_lhiheh]bb\dhlhjhcqbkehijhp_kkh\ih jZagufjZaf_jghklyfijbf_jghh^ghblh`_Ihevah\Zl_evfh`_lmijZ\eylv qbkehfijhp_kkh\\g_dhlhjuojZaf_jghklyoke_^mxsbfh[jZahfAgZq_gb_ DIMS(I)jZkkqblu\Z_lky^Zgghcijhp_^mjhc_kebi_j_^\uah\hfhghjZ\gh 0 bgZq_ hklZ\ey_lky [_a baf_g_gbc HljbpZl_evgu_ agZq_gby we_f_glh\ fZkkb\Z DIMS y\eyxlky hrb[hqgufb I_j_^ \uah\hf ijhp_^mju agZq_gb_ NNODES ^he`gh [ulv djZlgh ijhba\_^_gbx g_gme_\uo agZq_gbc fZkkb\Z DIMS
57
dimsi_j_^
\uah\hf
(0, (0, (0, (0,
0, 0, 3, 3,
0) 0) 0) 0)
\uah\ijhp_^mju MPI_DIMS_CREATE(6, MPI_DIMS_CREATE(7, MPI_DIMS_CREATE(6, MPI_DIMS_CREATE(7,
3, 3, 3, 3,
dims, dims, dims, dims,
dimsihke_
\uah\Z
ierr) ierr) ierr) ierr)
(3, 2, 1) (7, 1, 1) (2, 3, 1) hrb[dZ
MPI_CART_COORDS(COMM, RANK, MAXDIMS, COORDS, IERR) INTEGER COMM, RANK, MAXDIMS, COORDS(*), IERR
Hij_^_e_gb_^_dZjlh\uodhhj^bgZlijhp_kkZih_]hjZg]m RANK\dhffmgbdZlhj_ COMMDhhj^bgZlu\ha\jZsZxlky\fZkkb\_ COORDSkqbkehfwe_f_glh\MAXDIMSHlkq_ldhhj^bgZlihdZ`^hfmbaf_j_gbxgZqbgZ_lkykgmey MPI_CART_RANK(COMM, COORDS, RANK, IERR) INTEGER COMM, COORDS(*), RANK, IERR Hij_^_e_gb_jZg]Z RANKijhp_kkZ\dhffmgbdZlhj_ COMMih_]h^_dZjlh\uf dhhj^bgZlZf COORDS>eyi_jbh^bq_kdboj_r_lhddhhj^bgZlu\g_^himklb-
fuo bgl_j\Zeh\ i_j_kqblu\Zxlky ^ey g_i_jbh^bq_kdbo j_r_lhd hgb y\eyxlkyhrb[hqgufb
MPI_CART_SUB(COMM, DIMS, NEWCOMM, IERR) INTEGER COMM, NEWCOMM, IERR LOGICAL DIMS(*) JZks_ie_gb_ dhffmgbdZlhjZ COMM k dhlhjuf k\yaZgZ ^_dZjlh\Z lhiheh]by ijb ihfhsb ijhp_^mju MPI_CART_CREATE gZih^]jmiiukhhl\_lkl\mxsb_ ^_dZjlh\uf ih^j_r_ldZf f_gvr_c jZaf_jghklb I–uc we_f_gl eh]bq_kdh]h fZkkb\Z DIMS mklZgZ\eb\Z_lky jZ\guf agZq_gbx .TRUE. _keb I–h_
baf_j_gb_ ^he`gh hklZlvky \ nhjfbjm_fhc ih^j_r_ld_ k\yaZgghc k dhffmgbdZlhjhfNEWCOMM.
LOGICAL PERIODS(*)
Ihemq_gb_ bgnhjfZpbb h ^_dZjlh\hc lhiheh]bb dhffmgbdZlhjZ COMM b dhhj^bgZlZo\g_c\ua\Z\r_]hijhp_kkZ MAXDIMSaZ^Z_ljZaf_jghklv^_dZjlh\hc lhiheh]bb < iZjZf_lj_ DIMS \ha\jZsZ_lky dhebq_kl\h ijhp_kkh\ ^ey dZ`^h]hbaf_j_gby\iZjZf_lj_PERIODS –i_jbh^bqghklvihdZ`^hfmbaf_j_gbx\iZjZf_lj_COORDS –dhhj^bgZlu\ua\Z\r_]hijhp_kkZ\^_dZjlh\hc lhiheh]bb MPI_CART_SHIFT(COMM, DIRECTION, DISP, SOURCE, DEST, IERR) INTEGER COMM, DIRECTION, DISP, SOURCE, DEST, IERR Ihemq_gb_ghf_jh\ihkueZxs_]hSOURCE bijbgbfZxs_]hDEST ijhp_kkh\\^_dZjlh\hclhiheh]bbdhffmgbdZlhjZ COMM^eyhkms_kl\e_gbyk^\b]Z \^hevbaf_j_gbyDIRECTIONgZ\_ebqbgmDISP.
>eyi_jbh^bq_kdbobaf_j_gbchkms_kl\ey_lkypbdebq_kdbck^\b]^eyg_i_jbh^bq_kdbo – ebg_cguc k^\b] < kemqZ_ ebg_cgh]h k^\b]Z gZ g_dhlhjuo ijhp_kkZo \ dZq_kl\_ ghf_jh\ ihkueZxs_]h beb ijbgbfZxs_]h ijhp_kkh\ fh`_l [ulv ihemq_gh agZq_gb_ MPI_PROC_NULL hagZqZxs__ \uoh^ aZ ]jZgbpu ^bZiZahgZ < kemqZ_ pbdebq_kdh]h k^\b]Z ihke_^gbc ijhp_kk ih ^Zgghfm baf_j_gbx hkms_kl\ey_l h[f_gu k gme_\uf ijhp_kkhf >ey nf_jghc^_dZjlh\hcj_r_ldbagZq_gb_ DIRECTION^he`gh[ulv\ij_^_eZohl 0^hn-1. AgZq_gby SOURCEb DESTfh`ghbkihevah\ZlvgZijbf_j^eyh[f_gZkihfhsvxijhp_^mjuMPI_SENDRECV. < ke_^mxs_f ijbf_j_ kha^Z_lky ^\mf_jgZy ^_dZjlh\Z j_r_ldZ i_jbh^bq_kdZyihh[hbfbaf_j_gbyfhij_^_eyxlkydhhj^bgZluijhp_kkZ\^Zgghcj_r_ld_ Ihlhf ijb ihfhsb ijhp_^mju MPI_CART_SHIFT \uqbkeyxlky dhhj^bgZluijhp_kkh\kdhlhjufbgm`ghkh\_jrblvh[f_g^Zggufb^eyhkms_kl\e_gbypbdebq_kdh]hk^\b]ZkrZ]hf2ihbaf_j_gbx1<dhgp_njZ]f_glZ ihemq_ggu_agZq_gbyghf_jh\ijhp_kkh\bkihevamxlky^eyh[f_gZ^Zggufb ijbihfhsbijhp_^mjuMPI_SENDRECV_REPLACE. periods(1) = .TRUE. periods(2) = .TRUE. call MPI_CART_CREATE(MPI_COMM_WORLD, 2, dims, & periods, .TRUE., comm, ierr) call MPI_COMM_RANK(comm, rank, ierr) call MPI_CART_COORDS(comm, rank, 2, coords, ierr) shift = 2 dest = 1 call MPI_CART_SHIFT(comm, 0, shift, source, dest, ierr) call MPI_SENDRECV_REPLACE(a, 1, MPI_REAL, dest, 0, & source, 0, comm, status, ierr)
59
Lhiheh]by]jZnZ MPI_GRAPH_CREATE(COMM, NNODES, INDEX, EDGES, REORDER, COMM_GRAPH, IERR) INTEGER COMM, NNODES, INDEX(*), EDGES(*), COMM_GRAPH, IERR LOGICAL REORDER Kha^Zgb_gZhkgh\_dhffmgbdZlhjZ COMMgh\h]hdhffmgbdZlhjZ COMM_GRAPH klhiheh]b_c]jZnZIZjZf_lj NNODESaZ^Z_lqbkeh\_jrbg]jZnZ INDEX(I) kh^_j`bl kmffZjgh_ dhebq_kl\h khk_^_c ^ey i_j\uo I \_jrbg FZkkb\ EDGES kh^_j`bl mihjy^hq_gguc kibkhd ghf_jh\ ijhp_kkh\-khk_^_c \k_o \_jrbgIZjZf_lj REORDERijbagZq_gbb .TRUE.hagZqZ_lqlhkbkl_f_jZa-
j_r_ghf_gylvihjy^hdgmf_jZpbbijhp_kkh\
Ijhp_^mjZ y\ey_lky dhee_dlb\ghc Z agZqbl ^he`gZ [ulv \ua\ZgZ \k_fb ijhp_kkZfbbkoh^gh]hdhffmgbdZlhjZ?kebNNODESf_gvr_qbkeZijhp_kkh\ dhffmgbdZlhjZ COMM lh g_dhlhjuf ijhp_kkZf \_jg_lky agZq_gb_ MPI_COMM_NULL Z agZqbl hgb g_ [m^ml ijbgbfZlv mqZklby \ kha^Z\Z_fhc lhiheh]bb ?keb NNODES [hevr_ qbkeZ ijhp_kkh\ dhffmgbdZlhjZ COMM lh \uah\ijhp_^mjuy\ey_lkyhrb[hqguf <ke_^mxs_clZ[ebqd_ijb\_^_gijbf_jhibkZgby]jZnZq_j_aaZ^Zgb_\k_o khk_^_cdZ`^hc\_jrbgu Ijhp_kk
Khk_^b
0 1 2 3
1, 3 0 3 0, 2
>eyhibkZgbylZdh]h]jZnZgm`ghaZihegblvke_^mxsb_kljmdlmju^Zgguo INDEX=2, 3, 4, 6 EDGES=1, 3, 0, 3, 0, 2
Ihke_ wlh]h fh`gh kha^Zlv lhiheh]bx ]jZnZ gZijbf_j k ihfhsvx ke_^mxs_]h \uah\Z \uah\ [m^_l dhjj_dlguf ijb \uiheg_gbb gZ g_ f_g__ q_fgZ4ijhp_kkZo call MPI_GRAPH_CREATE(MPI_COMM_WORLD, 4, INDEX, EDGES, .TRUE., comm_graph, ierr)
&
60
MPI_GRAPH_NEIGHBORS_COUNT(COMM, RANK, NNEIGHBORS, IERR) INTEGER COMM, RANK, NNEIGHBORS, IERR Hij_^_e_gb_ dhebq_kl\Z NNEIGHBORS g_ihkj_^kl\_gguo khk_^_c ijhp_kkZ k jZg]hfRANK\]jZnh\hclhiheh]bbk\yaZgghckdhffmgbdZlhjhfCOMM. MPI_GRAPH_NEIGHBORS(COMM, RANK, MAX, NEIGHBORS, IERR) INTEGER COMM, RANK, MAX, NEIGHBORS(*), IERR
Hij_^_e_gb_ jZg]h\ g_ihkj_^kl\_gguo khk_^_c ijhp_kkZ k jZg]hf RANK \ ]jZnh\hclhiheh]bbk\yaZgghckdhffmgbdZlhjhf COMMJZg]bkhk_^_c\ha\jZsZxlky \ fZkkb\_ NEIGHBORS, MAX aZ^Z_l h]jZgbq_gb_gZdhebq_kl\hkhk_^_c fh`_l [ulv ihemq_gh gZijbf_j \uah\hf ijhp_^mju MPI_GRAPH_NEIGHBORS_COUNT). MPI_GRAPHDIMS_GET(COMM, NNODES, NEDGES, IERR) INTEGER COMM, NNODES, NEDGES, IERR Hij_^_e_gb_ qbkeZ \_jrbg NNODES b qbkeZ j_[_j NEDGES]jZnh\hclhiheh]bbk\yaZgghckdhffmgbdZlhjhfCOMM. MPI_GRAPH_GET(COMM, MAXINDEX, MAXEDGES, INDEX, EDGES, IERR) INTEGER COMM, MAXINDEX, MAXEDGES, INDEX(*), EDGES(*), IERR
Hij_^_e_gb_ bgnhjfZpbb h lhiheh]bb ]jZnZ k\yaZgghc k dhffmgbdZlhjhf COMM<fZkkb\Zo INDEXbEDGES\ha\jZsZ_lkyhibkZgb_]jZnh\hclhiheh]bb \lhf\b^_dZdhgZaZ^Z_lkyijbkha^Zgbblhiheh]bbkihfhsvxijhp_^mju MPI_GRAPH_CREATEIZjZf_lju MAXINDEXbMAXEDGESaZ^Zxlh]jZgbq_gbygZ jZaf_jukhhl\_lkl\mxsbofZkkb\h\fh]ml[ulvihemq_gugZijbf_j\uah\hfijhp_^mjuMPI_GRAPHDIMS_GET). <ke_^mxs_fijbf_j_kha^Z_lky]jZnh\Zylhiheh]by comm_graph^eyh[s_gby ijhp_kkh\ ih dhffmgbdZpbhgghc ko_f_ PDVWHU-VODYH
61
program example18 include 'mpif.h' integer ierr, rank, rank1, i, size, MAXPROC, MAXEDGES parameter (MAXPROC = 128, MAXEDGES = 512) integer a, b integer status(MPI_STATUS_SIZE) integer comm_graph, index(MAXPROC), edges(MAXEDGES) integer num, neighbors(MAXPROC) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) do i = 1, size index(i) = size+i-2 end do do i = 1, size-1 edges(i) = i edges(size+i-1) = 0 end do call MPI_GRAPH_CREATE(MPI_COMM_WORLD, size, index, edges, & .TRUE., comm_graph, ierr) call MPI_GRAPH_NEIGHBORS_COUNT(comm_graph, rank, num, & ierr) call MPI_GRAPH_NEIGHBORS(comm_graph, rank, num, neighbors, & ierr) do i = 1, num call MPI_SENDRECV(rank, 1, MPI_INTEGER, neighbors(i), & 1, rank1, 1, MPI_INTEGER, & neighbors(i), 1, comm_graph, & status, ierr) print *, 'procecc ', rank, ' communicate with process', & rank1 end do call MPI_FINALIZE(ierr) end
AZ^Zgby • H[yaZgZ eb \bjlmZevgZy lhiheh]by ih\lhjylv nbabq_kdmx lhiheh]bx p_e_\h]hdhfivxl_jZ" • Ex[hcebdhffmgbdZlhjfh`_lh[eZ^Zlv\bjlmZevghclhiheh]b_c" • Fh`_l eb ijhp_kk \oh^blv h^gh\j_f_ggh \ ^_dZjlh\m lhiheh]bx b \ lhiheh]bx]jZnZ" • Fh`gh eb \ua\Zlv ijhp_^mjm MPI_CART_CREATE lhevdh gZ iheh\bg_ ijhp_kkh\dhffmgbdZlhjZ" • G_h[oh^bfhebbkihevah\Zlvijhp_^mjmMPI_DIMS_CREATEi_j_^\uah\hfijhp_^mjuMPI_CART_CREATE? • Fh`ghebbkihevah\Zlvdhhj^bgZluijhp_kkZ\^_dZjlh\hclhiheh]bb \ijhp_^mjZoh[f_gZ^Zggufb" 62
• DZdb_ • • •
•
i_j_kuedb ^Zgguo hkms_kl\eyxlky ijhp_^mjhc MPI_CART_SHIFT? DZd hij_^_eblv k dZdbfb ijhp_kkZfb \ lhiheh]bb ]jZnZ k\yaZg ^Zggucijhp_kk" DZdkha^Zlvlhiheh]bx]jZnZ\dhlhjhcdZ`^ucijhp_kkk\yaZgkdZ`^uf" J_Zebah\Zlv jZa[b_gb_ ijhp_kkh\ gZ ^\_ ]jmiiu \ h^ghc ba dhlhjuo hkms_kl\ey_lkyh[f_gihdhevpmijbihfhsbk^\b]Z\h^ghf_jghc^_dZjlh\hclhiheh]bbZ\^jm]hc–dhffmgbdZpbbihko_f_PDVWHU-slave, j_Zebah\Zgghcijbihfhsblhiheh]bb]jZnZ Bkihevah\Zlv^\mf_jgmx^_dZjlh\mlhiheh]bxijhp_kkh\ijbj_ZebaZpbbiZjZee_evghcijh]jZffui_j_fgh`_gbyfZljbp
I_j_kuedZjZaghlbiguo^Zgguo Ih^ khh[s_gb_f \ MPI ihgbfZ_lky fZkkb\ h^ghlbiguo ^Zgguo jZkiheh`_gguo\ihke_^h\Zl_evguoyq_cdZoiZfylbQZklh\ijh]jZffZolj_[mxlky i_j_kuedb[he__keh`guoh[t_dlh\^ZgguokhklhysbobajZaghlbiguowe_f_glh\ beb jZkiheh`_gguo g_ \ ihke_^h\Zl_evguo yq_cdZo iZfylb < wlhf kemqZ_fh`gheb[hihkueZlv^Zggu_g_[hevrbfbihjpbyfbjZkiheh`_gguo ih^jy^we_f_glh\h^gh]hlbiZeb[hbkihevah\Zlvdhibjh\Zgb_^Zgguoi_j_^ hlkuedhc\g_dhlhjucijhf_`mlhqguc[mn_jH[Z\ZjbZglZy\eyxlky^hklZlhqgh g_m^h[gufb b lj_[mxl ^hihegbl_evguo aZljZl dZd \j_f_gb lZd b hi_jZlb\ghciZfylb >eyi_j_kuedbjZaghlbiguo^Zgguo\MPIij_^mkfhlj_gu^\Zki_pbZevguo kihkh[Z • Ijhba\h^gu_lbiu^Zgguo; • MiZdh\dZ^Zgguo. Ijhba\h^gu_lbiu^Zgguo Ijhba\h^gu_lbiu^Zgguokha^Zxlky\h\j_fy\uiheg_gbyijh]jZffukihfhsvxijhp_^mj-dhgkljmdlhjh\gZhkgh\_kms_kl\mxsbodfhf_glm\uah\Z dhgkljmdlhjZlbih\^Zgguo Kha^Zgb_lbiZ^Zgguokhklhblba^\mowlZih\ 1. Dhgkljmbjh\Zgb_lbiZ 2. J_]bkljZpbylbiZ 63
Ihke_ j_]bkljZpbb ijhba\h^guc lbi ^Zgguo fh`gh bkihevah\Zlv gZjy^m k ij_^hij_^_e_ggufblbiZfb\hi_jZpbyoi_j_kuedb\lhfqbke_b\dhee_dlb\guohi_jZpbyoIhke_aZ\_jr_gbyjZ[hlukijhba\h^guflbihf^Zgguo _]hj_dhf_g^m_lkyZggmebjh\ZlvIjbwlhf\k_ijhba\_^_ggu_gZ_]hhkgh\_ gh\u_lbiu^ZgguohklZxlkybfh]mlbkihevah\Zlvky^Zevr_ Ijhba\h^guclbi^ZgguooZjZdl_jbam_lkyihke_^h\Zl_evghklvx[Zah\uolbih\ ^Zgguo b gZ[hjhf p_ehqbke_gguo agZq_gbc kf_s_gby we_f_glh\ lbiZ hlghkbl_evghgZqZeZ[mn_jZh[f_gZKf_s_gbyfh]ml[ulvdZdiheh`bl_evgufblZdbhljbpZl_evgufbg_h[yaZgujZaebqZlvkyg_lj_[m_lkybomihjy^hq_gghklvLZdbfh[jZahfihke_^h\Zl_evghklvwe_f_glh\^Zgguo\ijhba\h^ghf lbi_ fh`_l hlebqZlvky hl ihke_^h\Zl_evghklb bkoh^gh]h lbiZ Z h^bg we_f_gl ^Zgguo fh`_l \klj_qZlvky \ dhgkljmbjm_fhf lbi_ fgh]hdjZlgh MPI_TYPE_CONTIGUOUS(COUNT, TYPE, NEWTYPE, IERR) INTEGER COUNT, TYPE, NEWTYPE, IERR Kha^Zgb_ gh\h]h lbiZ ^Zgguo NEWTYPE khklhys_]h ba COUNT ihke_^h\Zl_evgh jZkiheh`_gguo we_f_glh\ [Zah\h]h lbiZ ^Zgguo TYPE NZdlbq_kdb
kha^Z\Z_fuclbi^Zgguoij_^klZ\ey_lfZkkb\^Zgguo[Zah\h]hlbiZdZdhl^_evguch[t_dl
< ke_^mxs_f ijbf_j_ kha^Z_lky gh\uc lbi ^Zgguo newtype dhlhjuc \ ^Zevg_cr_fihke_j_]bkljZpbblbiZ fh`_lbkihevah\Zlvky^eyi_j_kuedb iylbjZkiheh`_gguoih^jy^p_euoqbk_e call MPI_TYPE_CONTIGUOUS(5, MPI_INTEGER, newtype, ierr) MPI_TYPE_VECTOR(COUNT, BLOCKLEN, STRIDE, TYPE, NEWTYPE, IERR) INTEGER COUNT, BLOCKLEN, STRIDE, TYPE, NEWTYPE, IERR Kha^Zgb_ gh\h]h lbiZ ^Zgguo NEWTYPE khklhys_]h ba COUNT [ehdh\ ih BLOCKLEN we_f_glh\ [Zah\h]h lbiZ ^Zgguo TYPE Ke_^mxsbc [ehd gZqbgZ_lky q_j_a STRIDE we_f_glh\ [Zah\h]h lbiZ ^Zgguo ihke_ gZqZeZ ij_^u^m-
s_]h[ehdZ
<ke_^mxs_fijbf_j_kha^Z_lkygh\uclbi^Zgguo newtypedhlhjucihke_ j_]bkljZpbb fh`_l [ulv bkihevah\Zg ^ey i_j_kuedb dZd _^bgh]h p_eh]h r_klb we_f_glh\ ^Zgguo dhlhju_ fh`gh ij_^klZ\blv ke_^mxsbf h[jZahf lbi we_f_glZ ^Zgguo dhebq_kl\h we_f_glh\ ^Zgguo hl gZqZeZ [mn_jZ ihkuedb {(MPI_REAL, 0), (MPI_REAL, 1), (MPI_REAL, 2), (MPI_REAL, 5), (MPI_REAL, 6), (MPI_REAL, 7)}
64
count = 2 blocklen = 3 stride = 5 call MPI_TYPE_VECTOR(count, blocklen, stride, & MPI_REAL, newtype, ierr) MPI_TYPE_HVECTOR(COUNT, BLOCKLEN, STRIDE, TYPE, NEWTYPE, IERR) INTEGER COUNT, BLOCKLEN, STRIDE, TYPE, NEWTYPE, IERR Kha^Zgb_ gh\h]h lbiZ ^Zgguo NEWTYPE khklhys_]h ba COUNT [ehdh\ ih BLOCKLEN we_f_glh\ [Zah\h]h lbiZ ^Zgguo TYPE Ke_^mxsbc [ehd gZqbgZ_lkyq_j_aSTRIDE[Zclihke_gZqZeZij_^u^ms_]h[ehdZ MPI_TYPE_INDEXED(COUNT, BLOCKLENS, DISPLS, TYPE, NEWTYPE, IERR) INTEGER COUNT, BLOCKLENS(*), DISPLS(*), TYPE, NEWTYPE, IERR Kha^Zgb_ gh\h]h lbiZ ^Zgguo NEWTYPE khklhys_]h ba COUNT [ehdh\ ih BLOCKLENS(I) we_f_glh\ [Zah\h]h lbiZ ^Zgguo I-c [ehd gZqbgZ_lky q_j_a DISPLS(I)we_f_glh\[Zah\h]hlbiZ^ZgguokgZqZeZ[mn_jZihkuedbIhem-
q_gguclbi^Zgguofh`ghkqblZlvh[h[s_gb_f\_dlhjgh]hlbiZ
< ke_^mxs_f ijbf_j_ aZ^Z_lky lbi ^Zgguo newtype ^ey hibkZgby gb`g_lj_m]hevghcfZljbpulbiZ double precision ijbwlhfmqblu\Z_lkyqlh\ yaud_NhjljZgfZkkb\uojZgylkyihklhe[pZf do i = 1, n blocklens(i) = n-i+1 displs(i) = n*(i-1)+i-1 end do call MPI_TYPE_INDEXED(n, blocklens, displs, MPI_DOUBLE_PRECISION, newtype, ierr) MPI_TYPE_HINDEXED(COUNT, BLOCKLENS, DISPLS, TYPE, NEWTYPE, IERR) INTEGER COUNT, BLOCKLENS(*), DISPLS(*), TYPE, NEWTYPE, IERR Kha^Zgb_ gh\h]h lbiZ ^Zgguo NEWTYPE khklhys_]h ba COUNT [ehdh\ ih BLOCKLENS(I) we_f_glh\ [Zah\h]h lbiZ ^Zgguo I-c [ehd gZqbgZ_lky q_j_a DISPLS(I)[ZclkgZqZeZ[mn_jZihkuedb MPI_TYPE_STRUCT(COUNT, BLOCKLENS, DISPLS, TYPES, NEWTYPE, IERR) INTEGER COUNT, BLOCKLENS(*), DISPLS(*), TYPES(*), NEWTYPE, IERR Kha^Zgb_ kljmdlmjgh]h lbiZ ^Zgguo NEWTYPE ba COUNT [ehdh\ ih BLOCKLENS(I) we_f_glh\ lbiZ TYPES(I). I-c [ehd gZqbgZ_lky q_j_a DISPLS(I)[ZclkgZqZeZ[mn_jZihkuedb
<ke_^mxs_fijbf_j_kha^Z_lkygh\uclbi^Zgguo newtypedhlhjucihke_ j_]bkljZpbbfh`_l[ulvbkihevah\Zg^eyi_j_kuedbdZd_^bgh]hp_eh]hiylb we_f_glh\ ^Zgguo dhlhju_ fh`gh ij_^klZ\blv ke_^mxsbf h[jZahf lbi we_f_glZ^Zgguodhebq_kl\h[ZclhlgZqZeZ[mn_jZihkuedb {(MPI_DOUBLE_PRECISION, 0), (MPI_DOUBLE_PRECISION, 8), 65
(MPI_DOUBLE_PRECISION, 16), (MPI_CHARACTER, 24), (MPI_CHARACTER, 25)} blocklens(1) = 3 blocklens(2) = 2 types(1) = MPI_DOUBLE_PRECISION types(2) = MPI_CHARACTER displs(1) = 0 displs(2) = 24 call MPI_TYPE_STRUCT(2, blocklens, displs, types, & newtype, ierr) MPI_TYPE_COMMIT(DATATYPE, IERR) INTEGER DATATYPE, IERR
J_]bkljZpbykha^Zggh]hijhba\h^gh]hlbiZ^Zgguo DATATYPEIhke_j_]bkljZpbb wlhl lbi ^Zgguo fh`gh bkihevah\Zlv \ hi_jZpbyo h[f_gZ gZjZ\g_ k ij_^hij_^_e_ggufblbiZfb^ZgguoIj_^hij_^_e_ggu_lbiu^Zgguoj_]bkljbjh\Zlvg_gm`gh MPI_TYPE_FREE(DATATYPE, IERR) INTEGER DATATYPE, IERR
:ggmebjh\Zgb_ ijhba\h^gh]h lbiZ ^Zgguo DATATYPE IZjZf_lj DATATYPE mklZgZ\eb\Z_lky \ agZq_gb_ MPI_DATATYPE_NULL =ZjZglbjm_lky qlh ex[hc gZqZluc h[f_g bkihevamxsbc ^Zggu_ Zggmebjm_fh]h lbiZ [m^_l ghjfZevgh aZ\_jr_g Ijb wlhf ijhba\h^gu_ hl DATATYPE lbiu ^Zgguo hklZxlky b fh]ml bkihevah\Zlvky ^Zevr_ Ij_^hij_^_e_ggu_ lbiu ^Zgguo g_fh]ml[ulvZggmebjh\Zgu MPI_TYPE_SIZE(DATATYPE, SIZE, IERR) INTEGER DATATYPE, SIZE, IERR Hij_^_e_gb_jZaf_jZ SIZElbiZ^Zgguo DATATYPE\[ZclZoh[t_fZiZfylb
aZgbfZ_fh]hh^gbfwe_f_glhf^Zggh]hlbiZ
MPI_ADDRESS(LOCATION, ADDRESS, IERR)
Hij_^_e_gb_ Z[khexlgh]h [Zcl-Z^j_kZ ADDRESS jZaf_s_gby fZkkb\Z LOCATION \ hi_jZlb\ghc iZfylb dhfivxl_jZ :^j_k hlkqblu\Z_lky hl [Zah\h]h Z^j_kZ agZq_gb_ dhlhjh]h kh^_j`blky \ kbkl_fghc dhgklZgl_ MPI_BOTTOM Ijhp_^mjZ iha\hey_l hij_^_eylv Z[khexlgu_ Z^j_kZ h[t_dlh\ dZd \ yaud_ NhjljZg lZd b \ Kb ohly \ Kb ^ey wlh]h ij_^mkfhlj_gu bgu_ kj_^kl\Z<yaud_KbiZjZf_ljADDRESSbf__llbiMPI_Aint. <ke_^mxs_fijbf_j_hibku\Z_lkygh\uclbi^Zgguonewtypedhlhjucihke_ j_]bkljZpbb bkihevam_lky ^ey i_j_kuedbdZd_^bgh]hp_eh]h^\mowe_f_glh\^Zgguolbih\ double precisionb character(1)<dZq_kl\_Z^j_kZ [mn_jZihkuedbbkihevam_lky[Zah\ucZ^j_k MPI_BOTTOMZ^eyhij_^_e_gby kf_s_gbc we_f_glh\ ^Zgguo dat1 b dat2 bkihevamxlky \uah\u ijhp_^mju 66
MPI_ADDRESSI_j_^i_j_kuedhcgh\uclbij_]bkljbjm_lkyijbihfhsb\uah\Zijhp_^mju MPI_TYPE_COMMITAZf_lbfqlhi_j_kueZ_lkyh^bgwe_f_gl
^Zgguo ijhba\h^gh]h lbiZ ohly hg b khklhbl ba ^\mo jZaghlbiguo we_f_glh\ blocklens(1) = 1 blocklens(2) = 1 types(1) = MPI_DOUBLE_PRECISION types(2) = MPI_CHARACTER call MPI_ADDRESS(dat1, address(1), ierr) displs(1) = address(1) call MPI_ADDRESS(dat2, address(2), ierr) displs(2) = address(2) call MPI_TYPE_STRUCT(2, blocklens, displs, types, & newtype, ierr) call MPI_TYPE_COMMIT(newtype, ierr) call MPI_SEND(MPI_BOTTOM, 1, newtype, dest, tag, & MPI_COMM_WORLD, ierr) MPI_TYPE_LB(DATATYPE, DISPL, IERR) INTEGER DATATYPE, DISPL, IERR Hij_^_e_gb_kf_s_gby DISPL\[ZclZogb`g_c]jZgbpuwe_f_glZlbiZ^ZgguoDATATYPEhlgZqZeZ[mn_jZ^Zgguo
MPI_TYPE_UB(DATATYPE, DISPL, IERR) INTEGER DATATYPE, DISPL, IERR Hij_^_e_gb_kf_s_gby DISPL\[ZclZo\_jog_c]jZgbpuwe_f_glZlbiZ^ZgguoDATATYPEhlgZqZeZ[mn_jZ^Zgguo MPI_TYPE_EXTENT(DATATYPE, EXTENT, IERR) INTEGER DATATYPE, EXTENT, IERR Hij_^_e_gb_ ^bZiZahgZ EXTENT jZagbpu f_`^m \_jog_c b gb`g_c ]jZgbpZfbwe_f_glZ^Zggh]hlbiZ lbiZ^ZgguoDATATYPE\[ZclZo
< ke_^mxs_f ijbf_j_ ijhba\h^guc lbi ^Zgguo bkihevam_lky ^ey i_j_klZgh\dbklhe[ph\fZljbpu\h[jZlghfihjy^d_Lbi^Zgguo matr_revkha^Z\Z_fucijhp_^mjhc MPI_TYPE_VECTORhibku\Z_lehdZevgmxqZklvfZljbpu ^Zggh]hijhp_kkZ\i_j_klZ\e_ggufb\h[jZlghfihjy^d_klhe[pZfbIhke_ j_]bkljZpbb wlhl lbi ^Zgguo fh`_l bkihevah\Zlvky ijb i_j_kued_ Ijh]jZffZ jZ[hlZ_l ijZ\bevgh _keb jZaf_j fZljbpu N ^_eblky gZp_eh gZ qbkehijhp_kkh\ijbeh`_gby
67
program example19 include 'mpif.h' integer ierr, rank, size, N, nl parameter (N = 8) double precision a(N, N), b(N, N) call MPI_INIT(ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) nl = (N-1)/size+1 call work(a, b, N, nl, size, rank) call MPI_FINALIZE(ierr) end subroutine work(a, b, n, nl, size, rank) include 'mpif.h' integer ierr, rank, size, n, nl, ii, matr_rev double precision a(n, nl), b(n, nl) integer i, j, status(MPI_STATUS_SIZE) do j = 1, nl do i = 1, n b(i,j) = 0.d0 ii = j+rank*nl a(i,j) = 100*ii+i enddo enddo call MPI_TYPE_VECTOR(nl, n, -n, MPI_DOUBLE_PRECISION, & matr_rev, ierr) call MPI_TYPE_COMMIT(matr_rev, ierr) call MPI_SENDRECV(a(1, nl), 1, MATR_REV, size-rank-1, 1, & b, nl*n, MPI_DOUBLE_PRECISION, & size-rank-1, 1, MPI_COMM_WORLD, & status, ierr) do j = 1, nl do i = 1, n print *, 'process ', rank, ': ', & j+rank*nl, ' ', i, a(i,j), ' ', b(i,j) enddo enddo end
MiZdh\dZ^Zgguo >eyi_j_kuehdjZaghjh^guo^ZgguogZjy^mkkha^Zgb_fijhba\h^guolbih\ fh`ghbkihevah\Zlvhi_jZpbbmiZdh\dbbjZkiZdh\db^ZgguoJZaghjh^gu_ bebjZkiheh`_ggu_g_\ihke_^h\Zl_evguoyq_cdZoiZfylb^Zggu_ihf_sZxlky\h^bgg_ij_ju\guc[mn_ji_j_kueZ_lkyZihlhfihemq_ggh_khh[s_gb_kgh\ZjZkij_^_ey_lkyihgm`gufyq_cdZfiZfylb
68
MPI_PACK(INBUF, INCOUNT, DATATYPE, OUTBUF, OUTSIZE, POSITION, COMM, IERR)
kueZlvkykhh[s_gb_>eyi_j_kuedbmiZdh\Zgguo^Zgguobkihevam_lkylbi ^ZgguoMPI_PACKED.
MPI_UNPACK(INBUF, INSIZE, POSITION, OUTBUF, OUTCOUNT, DATATYPE, COMM, IERR)
`_lij_\urZlvkmffmjZaf_jh\iZdm_fuowe_f_glh\^Zgguo
< ke_^mxs_f ijbf_j_ fZkkb\ bufbkihevam_lky\dZq_kl\_[mn_jZ^eymiZdh\db 10 we_f_glh\ fZkkb\Z a lbiZ real b 10 we_f_glh\ fZkkb\Z b lbiZ character Ihemq_ggh_ khh[s_gb_ i_j_kueZ_lky ijhp_^mjhc MPI_BCAST hl ijhp_kkZ 0\k_fhklZevgufijhp_kkZfihemq_ggh_khh[s_gb_jZkiZdh\u\Z_lkyijbihfhsb\uah\h\ijhp_^mjMPI_UNPACK. program example20 include 'mpif.h' integer ierr, rank, position real a(10) character b(10), buf(100) call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) do i = 1, 10 a(i) = rank + 1.0 if(rank .eq. 0) then b(i) = 'a' else b(i) = 'b' end if end do position=0 69
if(rank .eq. 0) then call MPI_PACK(a, 10, MPI_REAL, buf, 100, position, & MPI_COMM_WORLD, ierr) call MPI_PACK(b, 10, MPI_CHARACTER, buf, 100, position, & MPI_COMM_WORLD, ierr) call MPI_BCAST(buf, 100, MPI_PACKED, 0, & MPI_COMM_WORLD, ierr) else call MPI_BCAST(buf, 100, MPI_PACKED, 0, & MPI_COMM_WORLD, ierr) position=0 call MPI_UNPACK(buf, 100, position, a, 10, MPI_REAL, & MPI_COMM_WORLD, ierr) call MPI_UNPACK(buf, 100, position, b, 10, & MPI_CHARACTER, MPI_COMM_WORLD, ierr) end if print *, 'procecc ', rank, ' a=', a, ' b=', b call MPI_FINALIZE(ierr) end
AZ^Zgby • Kha^Zlv ijhba\h^guc lbi ^Zgguo ^ey i_j_kuehd ^bZ]hgZevghc fZljbpu • DZdkhhlghkylkyagZq_gby\ha\jZsZ_fu_ijhp_^mjZfbMPI_TYPE_SIZE bMPI_TYPE_EXTENT? • Fh`ghebbkihevah\Zlvijhba\h^gu_lbiu^Zgguo[_a\uah\Zijhp_^mjuMPI_TYPE_COMMIT? • I_j_keZlv gme_\hfm ijhp_kkm hl \k_o ijhp_kkh\ ijbeh`_gby kljmdlmjmkhklhysmxbajZg]Zijhp_kkZbgZa\ZgbymaeZgZdhlhjhf^Zgguc ijhp_kk aZims_g ihemq_ggh]h k ihfhsvx ijhp_^mju MPI_GET_PROCESSOR_NAME). • Ijyfhm]hevgZy fZljbpZ jZkij_^_e_gZ ih ijhp_kkZf ih kljhdZf I_j_klZ\blvkljhdbfZljbpu\h[jZlghfihjy^d_bkihevamy^eyi_j_kuehdijhba\h^guclbi^Zgguo • K^_eZlv ij_^u^msmx aZ^Zqm k bkihevah\Zgb_f i_j_kuehd miZdh\Zgguo^Zgguo • <q_fij_bfms_kl\Zbg_^hklZldbbkihevah\Zgbyi_j_kuehdmiZdh\Zgguo^ZgguoihkjZ\g_gbxki_j_kuedZfb^Zgguoijhba\h^guolbih\" • GZibkZlv ijh]jZffm ljZgkihgbjh\Zgby fZljbpu k bkihevah\Zgb_f ijhba\h^guolbih\^Zgguo
70
Ebl_jZlmjZ 1. MPI: A Message-Passing Interface Standard (Version 1.1) (http://parallel.ru/docs/Parallel/mpi1.1/mpi-report.html) 2.
71
Mq_[gh_ba^Zgb_
:glhgh\:e_dkZg^jK_j]__\bq I:J:EE?EVGH?IJH=J:FFBJH<:GB? KBKIHEVAH<:GB?FL?OGHEH=BB MPI
Ih^ibkZgh\i_qZlvNhjfZlo ;mfZ]Zhnk_lgZyI_qZlvjbahMkei_qe Mq-ba^eLbjZ`wdaAZdZa Hj^_gZAgZdIhq_lZBa^Zl_evkl\hFhkdh\kdh]hmgb\_jkbl_lZ Fhkd\Zme;GbdblkdZy MqZklhdhi_jZlb\ghci_qZlbGB