MPI学习五 组通信MPI程序设计

集合通信是包含在通信因子中的所有进程都参加操作 
集合通信一般实现三个功能

  • 通信:组内数据的传输
  • 同步:组内所有进程在特定的地点在执行进度上取得一致
  • 计算:对给定的数据完成一定的操作

集合操作的三种类型:

  • 通信:广播(broadcast)、分散(scatter)、收集(gather)、全互换(alltoall)等
  • 同步(barrier):集合中所有进程都到达后,每个进程再接着运行
  • 规约(reduction):集合中的其中一个进程收集所有进程的数据并计算(如:求最大值、求最小值、加、乘等)

1. 组通信的通信功能

1.1 一对多集合通信函数

一对多通信,在一个通信域内,以其中一个进程为根进程,向其他所有进程(包括该进程自身)发送数据。包括MPI_Bcast(广播)和MPI_Scatter(散发)两种操作方式。
1.1.1 广播 MPI_Bcast

int MPI_Bcast ( void *buf,int count, MPI_Datatype datatype, int root, MPI_Comm comm )

  • 根进程将消息广播发送到通信域内所有其他进程(包括该进程自身)
  • 所有进程(包括自身)都使用同一个通信域 comm 和根进程标识 root
  • 其他进程指定的通信元素个数、数据类型必须与跟进程指定的通信 元素个数、数据类型保持一致
 
 
 
  1. /*
  2. * 根进程(进程0)向组内的每个进程广播1个整型数据。
  3. */
  4. #include<stdio.h>
  5. #include"mpi.h"
  6. void main(int argc,char *argv[])
  7. {
  8. int rank,size;
  9. int value;
  10. MPI_Init(&argc,&argv);
  11. MPI_Comm_rank(MPI_COMM_WORLD,&rank);
  12. MPI_Comm_size(MPI_COMM_WORLD,&size);
  13. if(rank==0)
  14. {
  15. fprintf(stderr,"Process %d: Please input value: \n",rank);
  16. scanf("%d",&value);
  17. }
  18. MPI_Bcast(&value,1,MPI_INT,0,MPI_COMM_WORLD);
  19. fprintf(stderr,"Process %d received value %d \n",rank,value);
  20. MPI_Finalize();
  21. }
运行结果(图片传不上来。。。)
[root@dl1 mpi]# mpirun -np 4 ./test-13-2
Process 0: Please input value:
2000000
Process 0 received value 2000000
Process 1 received value 2000000
Process 2 received value 2000000
Process 3 received value 2000000

1.1.2 散发 MPI_Scatter/MPI_Scatterv

int MPI_Scatter ( void *sendbuf, int sendcount, MPI_Datatype datatype, void *recvbuf, int recvcount, MPI_Datatype datatype, int root, MPI_Comm comm )

与广播不同,散发操作的root向其他进程发送的数据可以是不同的。对于非根进程,发送消息缓冲区被忽略。接受数据元素的个数、类型必须与所有接受数据元素的个数类型相同。

 
 
 
  1. /*
  2. * 根进程(进程0)向组内的每个进程分散10个整型数据。
  3. */
  4. #include "mpi.h"
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <malloc.h>
  8. #include <time.h>
  9. void main(int argc, char *argv[])
  10. {
  11. int rank,size;
  12. int recvArray[10],*sendbuf;
  13. int root = 0;
  14. int recvnum = 10,sendnum;
  15. int i;
  16. MPI_Init(&argc,&argv);
  17. MPI_Comm_rank(MPI_COMM_WORLD,&rank);
  18. MPI_Comm_size(MPI_COMM_WORLD,&size);
  19. sendnum = recvnum * size;
  20. // root进程中的数组sendbuf分配内存并赋初值(1~9之间的随机整数)
  21. srand((unsigned)time(NULL));
  22. if(rank == root)
  23. {
  24. sendbuf = (int *)malloc(sendnum * sizeof(int)); // 动态分配内存
  25. for(i=0;i<sendnum;i++)
  26. sendbuf[i] = rand()%9+1;
  27. }
  28. //散发
  29. MPI_Scatter(sendbuf,recvnum,MPI_INT,recvArray,recvnum,MPI_INT,root,MPI_COMM_WORLD);
  30. if(rank == root)
  31. {
  32. fprintf(stderr,"\nRoot Process %d, Scattered %d data:",rank,sendnum);
  33. for(i=0;i<sendnum;i++)
  34. fprintf(stderr,"%d,",sendbuf[i]);
  35. fprintf(stderr,"\n");
  36. free(sendbuf); //释放内存
  37. }
  38. MPI_Barrier(MPI_COMM_WORLD); //同步
  39. fprintf(stderr,"\nProcess %d receive %d data:",rank,recvnum);
  40. for(i=0;i<recvnum;i++)
  41. fprintf(stderr,"%d,",recvArray[i]);
  42. fprintf(stderr,"\n");
  43. MPI_Finalize();
  44. }

运行结果
[root@dl1 mpi]#  mpirun -np 4 ./test-13-4-1

Root Process 0, Scattered 40 data:6,5,4,4,1,7,7,4,7,3,9,5,1,7,4,2,8,3,3,6,5,4,5,7,8,4,5,9,1,2,4,6,4,7,9,2,4,5,3,8,

Process 0 receive 10 data:6,5,4,4,1,7,7,4,7,3,

Process 1 receive 10 data:9,5,1,7,4,2,8,3,3,6,

Process 2 receive 10 data:5,4,5,7,8,4,5,9,1,2,

Process 3 receive 10 data:4,6,4,7,9,2,4,5,3,8,

int MPI_Scatterv ( void *sendbuf, int *sendcounts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值