📄 mpi312.htm
字号:
</UL>
<P><TT>C 发送100行以列顺序接收 </TT></P>
<UL>
<P><TT>CALL MPI_SENDRECV(a, 100, row1, myrank, 1, b, 100*100, MPI_REAL,
myrank, 0, MPI_COMM_WORLD, status, ierr) </TT></P>
</UL>
<P>例3.33 操作一个结构数组 </P>
<UL>
<P><TT>struct Partstruct </TT></P>
<P><TT>{ </TT></P>
<P><TT>int class; /* particle class */ </TT></P>
<P><TT>double d[6]; /* particle cooordinates */ </TT></P>
<P><TT>char b[7]; /* some additional information */ </TT></P>
<P><TT>}; </TT></P>
<P><TT>struct Partstruct particle[1000]; </TT></P>
<P><TT>int i, dest, rank; </TT></P>
<P><TT>MPI_Comm comm; </TT></P>
<P><TT>/* 创建数据类型描述结构 */ </TT></P>
<P><TT>MPI_Datatype Particletype; </TT></P>
<P><TT>MPI_Datatype type[3] = {MPI_INT, MPI_DOUBLE, MPI_CHAR}; </TT></P>
<P><TT>int blocklen[3] = {1, 6, 7}; </TT></P>
<P><TT>MPI_Aint disp[3]; </TT></P>
<P><TT>int base; </TT></P>
<P><TT>/* 计算结构中各部分偏移 */ </TT></P>
<P><TT>MPI_Adress(particle, disp); </TT></P>
<P><TT>MPI_Adress(particle[0].d, disp+1); </TT></P>
<P><TT>MPI_Adress(particle[0].b, disp+2); </TT></P>
<P><TT>base = disp[0]; </TT></P>
<P><TT>for(i=0; i<3; i++) disp[i] -= base; </TT></P>
<P><TT>MPI_Type_struct(3, blocklen, disp, type, &Particletype); </TT></P>
<P><TT>/* 如果编译器确实用神秘方式填充, 下面的做法可能更安全 */ </TT></P>
<P><TT>MPI_Datatype type1[4]= {MPI_INT, MPI_DOUBLE, MPI_CHAR, MPI_UB};
</TT></P>
<P><TT>int blocklen1[4]={1, 6, 7, 1}; </TT></P>
<P><TT>MPI_Aint disp1[4]; </TT></P>
<P><TT>/* 计算结构中各部分偏移 */ </TT></P>
<P><TT>MPI_Adress(particle, disp1); </TT></P>
<P><TT>MPI_Adress(particle[0].d, disp1+1); </TT></P>
<P><TT>MPI_Adress(particle[0].b, disp1+2); </TT></P>
<P><TT>MPI_Adress(particle+1, disp1+3); </TT></P>
<P><TT>base = disp1[0]; </TT></P>
<P><TT>for(i=0; i<4; i++) disp[i] -= base; </TT></P>
<P><TT>/* 创建数据类型描述结构 */</TT></P>
<P><TT>MPI_Type_struct(4, blocklen, disp1, type1, &Particletype); </TT></P>
<P><TT>/* 4.1: 发送整个数组 */ </TT></P>
<P><TT>MPI_Type_commit(&Particletype); </TT></P>
<P><TT>MPI_Send(particle, 1000, Particletype, dest, tag, comm); </TT></P>
<P><TT>/* 4.2: 只发送class=0的项, 前面加这样的项的序号 */ </TT></P>
<P><TT>MPI_Datatype Zparticles; </TT></P>
<P><TT>/* datatype describing all particles with class zero (needs to be
recomputed if classes change) */ </TT></P>
<P><TT>MPI_Datatype Ztype; </TT></P>
<P><TT>MPI_Aint zdisp[1000]; </TT></P>
<P><TT>int zblock[1000], j, k; </TT></P>
<P><TT>int zzblock[2] = {1, 1}; </TT></P>
<P><TT>MPI_Aint zzdisp[2]; </TT></P>
<P><TT>MPI_Datatype zztype[2]; </TT></P>
<P><TT>/* 计算class=0部分的偏移量 */ </TT></P>
<P><TT>j = 0; </TT></P>
<P><TT>for(i=0; i< 1000; i++) </TT></P>
<UL>
<P><TT>if (particle[i].class==0) { </TT></P>
<UL>
<P><TT>zdisp[j] = i; </TT></P>
<P><TT>zblock[j] = 1; </TT></P>
<P><TT>j++; } </TT></P>
</UL>
<P><TT>/* 为class=0 的部分创建数据类型 */ </TT></P>
<P><TT>MPI_Type_indexed( j, zblock, zdisp, Particletype, &Zparticles);
</TT></P>
<P><TT>/* prepend particle count */ </TT></P>
<P><TT>MPI_Address(&j,zzdisp); </TT></P>
<P><TT>MPI_Address(particle,zzdisp+1); </TT></P>
<P><TT>zztype[0]=MPI_INT; </TT></P>
<P><TT>zztype[1]=Zparticles; </TT></P>
<P><TT>MPI_Type_struct(2,zzblock,zzdisp,zztype,&Ztype); </TT></P>
<P><TT>MPI_Type_commit(&Ztype); </TT></P>
<P><TT>MPI_Send(MPI_BTOTOM,Ztype,dest,tag,comm); </TT></P>
<P><TT>/* 一种可能更有效的定义Zparticles 的方法 */ </TT></P>
<P><TT>/* 索引为0的连续部分被作为一个块处理 */ </TT></P>
<P><TT>j=0; </TT></P>
<P><TT>for (i=0;i<1000;i++) </TT></P>
<UL>
<P><TT>if (particle[i].index==0) { </TT></P>
<UL>
<P><TT>for (k=i+1;(k<1000)&&(particle[k].index==0);k++); </TT></P>
<P><TT>zdisp[j]=i; </TT></P>
<P><TT>zblock[j]=k-i; </TT></P>
<P><TT>j++; </TT></P>
<P><TT>i=k; } </TT></P>
</UL>
</UL>
<P><TT>MPI_Type_indexed(j,zblock,zdisp,Particletype,&Zparticles); </TT></P>
<P><TT>/* 4.3: send the first two coordinates of all entries*/ </TT></P>
<P><TT>MPI_Datatype Allpairs; </TT></P>
<P><TT>/* datatype for all pairs of coordinates */ </TT></P>
<P><TT>MPI_Aint sizeofentry; </TT></P>
<P><TT>MPI_Type_extent( Particletype, &sizeofentry); </TT></P>
<P><TT>/* sizeofentry can also be computed by subtracting the address of
particle[0] from the address of particle[1] */</TT></P>
<P><TT>MPI_Type_hvector(1000,2,sizeofentry,MPI_DOUBLE, &Allpairs);
</TT></P>
<P><TT>MPI_Type_commit( &Allpairs); </TT></P>
<P><TT>MPI_Send(particle[0].d,1,Allpairs,dest,tag,comm); </TT></P>
<P><TT>/* an alternative solution to 4.3 */ </TT></P>
<P><TT>MPI_Datatype Onepair; </TT></P>
<P><TT>/* datatype for one pair of coordinates,with the extent of one particle
entry */ </TT></P>
<P><TT>MPI_Aint disp2[3]; </TT></P>
<P><TT>MPI_Datatype type2[3] ={MPI_LB, MPI_DOUBLE,MPI_UB}; </TT></P>
<P><TT>int blocklen2[3] ={1,2,1}; </TT></P>
<P><TT>MPI_Address( particle,disp2); </TT></P>
<P><TT>MPI_Address( particle[0].d, disp2+1); </TT></P>
<P><TT>MPI_Adrress( particle+1, disp2+2); </TT></P>
<P><TT>base = disp2[0]; </TT></P>
<P><TT>for (i=0; i<2; i++) disp2[i] -= base; </TT></P>
<P><TT>MPI_Type_struct(3,blocklen2,disp2,type2,&Onepair); </TT></P>
<P><TT>MPI_Type_commit( &Onepair); </TT></P>
<P><TT>MPI_Send( particle[0].d,1000,Onepair,dest,tag,comm); </TT></P>
</UL>
</UL>
<P>例 3.34 和上例相同的操作, 只是数据类型中改用绝对地址. </P>
<UL>
<P><TT>struct Partsruct { </TT></P>
<UL>
<P><TT>int class ; </TT></P>
<P><TT>double d[6]; </TT></P>
<P><TT>char b[7]; </TT></P>
</UL>
<P><TT>}; </TT></P>
<P><TT>struct Partstruct particle[1000]; </TT></P>
<P><TT>/* build datatype describing first array entry */ </TT></P>
<P><TT>MPI_Datatype Particletype; </TT></P>
<P><TT>MPI_Datatype type[3] ={MPI_INT, MPI_DOUBLE,MPI_CHAR}; </TT></P>
<P><TT>int block[3] ={1,6,7}; </TT></P>
<P><TT>MPI_Aint disp[3];</TT></P>
<P><TT>MPI_Address( particle,disp); </TT></P>
<P><TT>MPI_Address( particle[0].d,disp+1); </TT></P>
<P><TT>MPI_Address( particle[0].b,disp+2);</TT></P>
<P><TT>MPI_Type_struct( 3, block, disp, type, &Partilcetype); </TT></P>
<P><TT>/* Particletype describes first array entry -- using absolute addresses
*/ </TT></P>
<P><TT>/*5.1: send the entries of class zero, preceded by the number of
such entries */ </TT></P>
<P><TT>MPI_Datatype Zparticles,Ztype; </TT></P>
<P><TT>MPI_Aint zdisp[1000] int zblock[1000],i,j,k; </TT></P>
<P><TT>int zzblock[2] ={1,1}; </TT></P>
<P><TT>MPI_Datatype zztype[2]; </TT></P>
<P><TT>MPI_Aint zzdisp[2]; </TT></P>
<P><TT>j=0; </TT></P>
<P><TT>for (i=0; i<1000;i++) </TT></P>
<UL>
<P><TT>if (particle[i].index==0) { </TT></P>
<UL>
<P><TT>for (k=i+1; (k <1000)&&(particle[k].index =0);k++); </TT></P>
<P><TT>zdisp[j] = i; </TT></P>
<P><TT>zblock[j] = k-i; </TT></P>
<P><TT>j++; </TT></P>
<P><TT>i=k; </TT></P>
</UL>
<P><TT>} </TT></P>
</UL>
<P><TT>MPI_Type_indexed( j,zblock,zdisp,Particletype,&Zpartilces);
</TT></P>
<P><TT>/* Zparticles describ particles with class zero, using their absolute
addresses */ </TT></P>
<P><TT>/* prepend particle count */ </TT></P>
<P><TT>MPI_Address(&j, zzdisp); </TT></P>
<P><TT>zzdisp[1] = MPI_BOTTOM; </TT></P>
<P><TT>zztype[0] = MPI_INT; </TT></P>
<P><TT>zztype[1] = Zparticles; </TT></P>
<P><TT>MPI_Type_struct(2,zzblock,zzdisp,zztype,&Ztype); </TT></P>
<P><TT>MPI_Type_commit( & Ztype); </TT></P>
<P><TT>MPI_Send(MPI_BOTTOM,1,Ztype,dest,tag,comm); </TT></P>
</UL>
<P>例 3.35 处理union </P>
<UL>
<P><TT>union { </TT></P>
<UL>
<P><TT>int ival; </TT></P>
<P><TT>float fval; } u[1000] </TT></P>
</UL>
<P><TT>int utype; </TT></P>
<P><TT>/* All entries of have indentical type; varible utype keeps track
of their current type */ </TT></P>
<P><TT>MPI_Datatype type [2]; </TT></P>
<P><TT>int blocklen[2]={1,1}; </TT></P>
<P><TT>MPI_Aint disp[2]; </TT></P>
<P><TT>MPI_Datatype mpi_utype [2]; </TT></P>
<P><TT>MPI_Aint i,j; </TT></P>
<P><TT>/* compute an MPI datatype for each possible union type ; assume
values are left-aligned in union storage. */ </TT></P>
<P><TT>MPI_Address(um&i); </TT></P>
<P><TT>MPI_Address(u+1,&j); </TT></P>
<P><TT>disp[0] =0; </TT></P>
<P><TT>disp[1] =j-i; </TT></P>
<P><TT>type[1] =MPI_UB; </TT></P>
<P><TT>type[0] = MPI_INT;</TT></P>
<P><TT>MPI_Type_struct(2,blocklen,disp,type,&mpi_utype[0]); </TT></P>
<P><TT>type[0] = MPI_FLOAT; </TT></P>
<P><TT>MPI_Type_struct(2,blocklen,disp,type,&mpi_utype[1]); </TT></P>
<P><TT>for (i=0; i<2; i++) MPI_Type_commit(&mpi_utype[i]); </TT></P>
<P><TT>/* actual communication */ </TT></P>
<P><TT>MPI_Send(u,1000, mpi_utype[utype], dest, tag, comm); </TT></P>
</UL>
<P>
<HR WIDTH="100%"></P>
<TABLE WIDTH="100%" >
<TR>
<TD align=left>Copyright: NPACT </TD>
<TD align=right><A HREF="mpi310.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi310.htm"><IMG SRC="backward.gif" tppabs="http://arch.cs.pku.edu.cn/image/backward.gif" ALT="BACKWARD" HEIGHT=32 WIDTH=32></A><A HREF="mpi313.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi313.htm"><IMG SRC="forward.gif" tppabs="http://arch.cs.pku.edu.cn/image/forward.gif" ALT="FORWARD" HEIGHT=32 WIDTH=32></A>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -