📄 mpi411.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>第四章: 集合通信</TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.0Gold (X11; I; SunOS 5.4 sun4m) [Netscape]">
</HEAD>
<BODY BGCOLOR="#F0F8FF">
<TABLE WIDTH="100%" >
<TR>
<TD align=left><B><FONT SIZE=+1>4.11 搜索(Scan)</FONT></B></TD>
<TD align=right><A HREF="mpi410.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi410.htm"><IMG SRC="backward.gif" tppabs="http://arch.cs.pku.edu.cn/image/backward.gif" ALT="BACKWARD" HEIGHT=32 WIDTH=32></A><A HREF="mpi412.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi412.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>
<P>
<HR WIDTH="100%"></P>
<PRE>MPI_SCAN(sendbuf, recvbuf, count, datatype, op, comm)
IN sendbuf 发送消息缓冲区的起始地址(可变)
OUT recvbuf 接收消息缓冲区的起始地址(可变)
IN count 输入缓冲区中元素的个数(整型)
IN datatype 输入缓冲区中元素的类型(句柄)
IN op 操作(句柄)
IN comm 通信子(句柄)
int MPI_Scan(void* sendbuf, void* recvbuf, int count,
MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
MPI_SCAN(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER COUNT, DATATYPE, OP, COMM, IERROR</PRE>
<P>MPI_SCAN常用于对分布于组中的数据作前置归约操作.此操作将序列号为0,...
,i(包括i)的进程发送缓冲区的值的归约结果存入序列号为i 的进程的接收消息缓冲区中,这种操作支持的类型、语义以及对发送及接收缓冲区的限制和MPI_REDUCE相同.</P>
<P><A NAME="section1"></A><B><FONT SIZE=+1>4.11.1 使用MPI_SCAN的例子</FONT></B></P>
<P>例4.22: 本例用一个用户自定义的操作进行段扫描,一个段扫描将一组值和一组逻辑量作为输入,其中逻辑值将输入分割成不同的段.例如对于以下数据:</P>
<UL>
<P><IMG SRC="formu5.gif" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/formu5.gif" HEIGHT=71 WIDTH=512></P>
</UL>
<P>操作符产生的结果是:</P>
<UL>
<P><IMG SRC="formu6.gif" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/formu6.gif" HEIGHT=81 WIDTH=262></P>
</UL>
<P>这里</P>
<UL>
<P><IMG SRC="formu7.gif" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/formu7.gif" HEIGHT=81 WIDTH=245></P>
</UL>
<P>注意这是一个非交换操作.它的C代码如下:</P>
<PRE> typedef struct {
double val;
int log;
} SegScanPair;
/* 用户自定义的函数 */
void segScan(SegScanPair *in, SegScanPair *inout, int *len,
MPI_Datatype *dptr)
{
int i;
SegScanPair c;
for (i=0; i<*len; ++i) {
if (in->log == inout->log)
c.val = in->val + inout->val;
else
c.val = inout->val;
c.log = inout->log;
*inout = c;
in++; inout++;
}
}</PRE>
<P><BR>
注意用户自定义操作的参数inout与操作的右端操作数相对应,当使用这个操作符时,应注意将它描述成一个非交换的,如下所示:</P>
<PRE> int i,base;
SeqScanPair a, answer;
MPI_Op myOp;
MPI_Datatype type[2] = {MPI_DOUBLE, MPI_INT};
MPI_Aint disp[2];
int blocklen[2] = {1, 1};
MPI_Datatype sspair;
/* 告之MPI SegScanPair类型是如何定义的 */
MPI_Address(a, disp);
MPI_Address(a.log, disp+1);
base = disp[0];
for (i=0; i<2; ++i) disp[i] -= base;
MPI_Type_struct(2, blocklen, disp, type, &sspair);
MPI_Type_commit(&sspair);
/* 生成段扫描的用户op */
MPI_Op_create(segScan, False, &myOp);
......
MPI_Scan(a, answer, 1, sspair, myOp, root, comm);
</PRE>
<P>
<HR WIDTH="100%"></P>
<TABLE WIDTH="100%" >
<TR>
<TD align=left>Copyright: NPACT </TD>
<TD align=right><A HREF="mpi410.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi410.htm"><IMG SRC="backward.gif" tppabs="http://arch.cs.pku.edu.cn/image/backward.gif" ALT="BACKWARD" HEIGHT=32 WIDTH=32></A><A HREF="mpi412.htm" tppabs="http://arch.cs.pku.edu.cn/parallelprogramming/mpispec/mpi412.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 + -