MPI的拓扑(虚拟拓扑和笛卡尔拓扑)

MPI_Graph_create和MPI_Cart_create函数分别用于产生通常(图)的虚拟拓扑和笛卡尔拓扑

虚拟拓扑:
虚拟拓扑可以用图来表示,每个进程代表一个点,两点之间的连线代表通信联通,但是注意MPI在任意两个进程之间都可通信,未连接的两点之间不代表无法进行通信。但是虚拟拓扑有个很致命的缺点,就是无法直观的获得进程在拓扑间的信息。
笛卡尔拓扑:
要保证你新建的笛卡尔拓扑的节点数量和你原有的通信组的节点数量相等,多了或者少了都会引起相应的错误,当reorder是true时,新的通信组内的进程会被重新编号。

关于平移得到的相连关系,如果是非循环的平移,每次移动disp就意味着将有disp个进程被移出,否则这disp个进程将补于与移动方向反向的那端。
下面是一个例子:

#include <stdio.h>
#include <mpi.h>

int main( argc, argv )
int argc;
char **argv;
{
    int rank, value, size, false=0;
    int right_nbr, left_nbr;
    MPI_Comm ring_comm;
    MPI_Status status;

    MPI_Init( &argc, &argv );
    MPI_Comm_size( MPI_COMM_WORLD, &size );
    MPI_Cart_create( MPI_COMM_WORLD, 1, &size, &false, 1, &ring_comm );/*创建一维网格,false意味着没有周期性(两端外的进程标识为MPI_PROC_NULL),1表示可以重排序,得到的拓扑坐标相邻关系为:

       MPI_PROC_NULL, 0, 1, ... , size-1 , MPI_PROC_NULL

*/
    MPI_Cart_shift( ring_comm, 0, 1, &left_nbr, &right_nbr );/*通过在定义的网格上的平移得到左右侧进程的标识*/
    MPI_Comm_rank( ring_comm, &rank );/*得到在新拓扑中的标识或坐标*/
    MPI_Comm_size( ring_comm, &size );/*得到新通信域中进程的个数*/
    do {
    if (rank == 0) {/*进程0负责读入数据并向下一个进程传递数据*/
    scanf( "%d", &value );
    MPI_Send( &value, 1, MPI_INT, right_nbr, 0, ring_comm );/*将数据传送到右面的进程*/
  }
  else {
    MPI_Recv( &value, 1, MPI_INT, left_nbr, 0, ring_comm, 
      &status );/*后面的进程从左边的进程接收数据*/
    MPI_Send( &value, 1, MPI_INT, right_nbr, 0, ring_comm );/*将接收到的数据在传递给右面的进程*/
  }
  printf( "Process %d got %d\n", rank, value );/*各进程打印各自得到的数据*/
   } while (value >= 0);/*若读入的数据非负,则继续读入并传递*/

  MPI_Finalize( );
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值