并行群集通信:全互换 Alltoall
2015-01-23 10:37
246 查看
函数原型:
MPI_ALLTOALL(sendbuf, sendcount, sendtype, recvbuf, recvcount,
recvtype, comm)
IN sendbuf 发送消息缓冲区的起始地址(可选数据类型)
IN sendcount 发送到每个进程的数据个数(整型)
IN sendtype 发送消息缓冲区中的数据类型(句柄)
OUT recvbuf 接收消息缓冲区的起始地址(可选数据类型)
IN recvcount 从每个进程中接收的元素个数(整型)
IN recvtype 接收消息缓冲区的数据类型(句柄)
IN comm 通信域(句柄)
int MPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm)
MPI_ALLTOALL(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT,
RECVTYPE, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, COMM,
IERROR
MPI_ALLTOALL是组内进程之间完全的消息交换,其中每一个进程都向其它所有的进程发送消息,同时,每一个进程都从其它所有的进程接收消息。
MPI_ALLGATHER每个进程散发一个相同的消息给所有的进程,MPI_ALLTOALL散发给不同进程的消息是不同的,因此它的发送缓冲区也 是一个数组。MPI_ALLTOALL的每个进程可以向每个接收者发送数目不同的数据。第i个进程发送的第j块数据将被第j个进程接收并存放在其接收消息 缓冲区recvbuf的第i块。每个进程的sendcount和sendtype的类型必须和所有其他进程的recvcount和recvtype相同, 这就意谓着在每个进程和根进程之间,发送的数据量必须和接收的数据量相等。
调用MPI_ALLTOALL相当于每个进程依次将它的发送缓冲区的第i块数据发送给第i个进程。同时每个进程又都依次从第j个进程接收数据放到各自接收缓冲区的第j块数据区的位置。
Alltoall 的示意图:
![](http://img.blog.163.com/photo/3POLv-zLqCkQ0ZdS2kqArw==/4800274252824098071.jpg)
Alltoall 的例子:
/**计算结果
tlu:lecture$ mpirun -np 3 ./alltoall.exe
Sendbuf on process 0 holds 3 data :
0 1 2
Sendbuf on process 1 holds 3 data :
3 4 5
Sendbuf on process 2 holds 3 data :
6 7 8
Recvbuf on process 0 holds 3 data :
0 3 6
Recvbuf on process 1 holds 3 data :
1 4 7
Recvbuf on process 2 holds 3 data :
2 5 8
*/
原文链接:http://motioo.blog.163.com/blog/static/117718291200954102827725/
MPI_ALLTOALL(sendbuf, sendcount, sendtype, recvbuf, recvcount,
recvtype, comm)
IN sendbuf 发送消息缓冲区的起始地址(可选数据类型)
IN sendcount 发送到每个进程的数据个数(整型)
IN sendtype 发送消息缓冲区中的数据类型(句柄)
OUT recvbuf 接收消息缓冲区的起始地址(可选数据类型)
IN recvcount 从每个进程中接收的元素个数(整型)
IN recvtype 接收消息缓冲区的数据类型(句柄)
IN comm 通信域(句柄)
int MPI_Alltoall(void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm)
MPI_ALLTOALL(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT,
RECVTYPE, COMM, IERROR)
<type> SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, COMM,
IERROR
MPI_ALLTOALL是组内进程之间完全的消息交换,其中每一个进程都向其它所有的进程发送消息,同时,每一个进程都从其它所有的进程接收消息。
MPI_ALLGATHER每个进程散发一个相同的消息给所有的进程,MPI_ALLTOALL散发给不同进程的消息是不同的,因此它的发送缓冲区也 是一个数组。MPI_ALLTOALL的每个进程可以向每个接收者发送数目不同的数据。第i个进程发送的第j块数据将被第j个进程接收并存放在其接收消息 缓冲区recvbuf的第i块。每个进程的sendcount和sendtype的类型必须和所有其他进程的recvcount和recvtype相同, 这就意谓着在每个进程和根进程之间,发送的数据量必须和接收的数据量相等。
调用MPI_ALLTOALL相当于每个进程依次将它的发送缓冲区的第i块数据发送给第i个进程。同时每个进程又都依次从第j个进程接收数据放到各自接收缓冲区的第j块数据区的位置。
Alltoall 的示意图:
![](http://img.blog.163.com/photo/3POLv-zLqCkQ0ZdS2kqArw==/4800274252824098071.jpg)
Alltoall 的例子:
/* * ===================================================================================== * * Filename: alltoall.cpp * * Description: MPI_Alltoall 函数 * * Version: 1.0 * Created: 2007年11月13日 23时07分12秒 CST * Revision: none * Compiler: mpicxx -DMPICH_IGNORE_CXX_SEEK -o alltoall.exe alltoall.cpp * * Author: Tiao Lu, tlu@math.pku.edu.cn * Company: School of Mathematical Sciences, Peking University * edit: DH,USTC ,2105,1,23. * ===================================================================================== */ #include <iostream> #include "mpi.h" using namespace std; int main(int argc, char * argv[]){ int rank, size; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); //任意一个CPU 向别的CPU发送的数据长度都一样。 //这个例子中,我们使用的数据长度是1. //你可以改成2 看看有什么不同。 int sendcount = 1; //recvcount 和 sendcount 必须相等 int recvcount = sendcount; //发送缓冲区和接收缓冲区的数据长度 int len = sendcount*size; int *sendbuf = new int[len]; int *recvbuf = new int[len]; //给发送缓冲区赋值 for(int i =0; i< len ; i ++) sendbuf[i] = i+size*rank; MPI_Alltoall(sendbuf, sendcount, MPI_INT, recvbuf, recvcount, MPI_INT, MPI_COMM_WORLD); //输出发送缓冲区的值 for(int i=0;i<size;i++){ if(i==rank){ cout<<"Sendbuf on process "<<rank<<" holds " <<len<< " data :"<<endl; for(int j=0;j<len;j++) cout<<sendbuf[j]<<" "; cout<<endl; } MPI_Barrier(MPI_COMM_WORLD); } if(rank==0) cout<<endl; MPI_Barrier(MPI_COMM_WORLD); //输出接收缓冲区的值 for(int i=0;i<size;i++){ if(i==rank){ cout<<"Recvbuf on process "<<rank<<" holds " <<len<< " data :"<<endl; for(int j=0;j<len;j++) cout<<recvbuf[j]<<" "; cout<<endl; } MPI_Barrier(MPI_COMM_WORLD); } delete [] sendbuf; delete [] recvbuf; MPI_Finalize(); // return EXIT_SUCCESS; return 0; }
/**计算结果
tlu:lecture$ mpirun -np 3 ./alltoall.exe
Sendbuf on process 0 holds 3 data :
0 1 2
Sendbuf on process 1 holds 3 data :
3 4 5
Sendbuf on process 2 holds 3 data :
6 7 8
Recvbuf on process 0 holds 3 data :
0 3 6
Recvbuf on process 1 holds 3 data :
1 4 7
Recvbuf on process 2 holds 3 data :
2 5 8
*/
原文链接:http://motioo.blog.163.com/blog/static/117718291200954102827725/
相关文章推荐
- 采用MPI_Send 和MPI_Recv 编写代码来实现包括MPI_Bcast、MPI_Alltoall、MPI_Gather、MPI_Scatter 等MPI 群集通信函数的功能
- [MPI] MPI 组通信 -- 全互换 MPI_Alltoall
- one-to-all及all-to-all网络通信模式
- MPI全局通信之MPI_Alltoall和MPI_Alltoallv
- Experience all that SharePoint 15 has to offer. Start now or Remind me later.
- Find all the narcissistic numbers from 100 to 999
- 配置Tensorlayer的时候安装出现unable to find vcvarsall.bat
- LINQ to SQL语句(7)之Exists/In/Any/All/Contains
- python安装PIL模块时Unable to find vcvarsall.bat错误的解决方法
- All about TAF - How To Configure Server Side Transparent Application Failover [ID 460982.1]
- Simple VBScript program to extract data from all worksheets in an Excel spreadsheet
- Error:All flavors must now belong to a named flavor dimension. The flavor 'flavor_name' is ...
- python ---解决“Unable to find vcvarsall.bat”错误
- 彻底解决安装Python扩展包时Unable to find vcvarsall.bat
- Shell / sed Program To Remove All C and C++ Comments From Program File
- 解决Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com
- [转]Resolving Python error: Unable to find vcvarsall.bat
- warning LNK4089: all references to "USER32.dll" discarded by /OPT:REF
- VB.Net to C# 代码转换(互换互转)工具
- python扩展问题”unable to find vcvarsall.bat“的解决