- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
比如说,我有 8 个进程。当我执行以下操作时,MPU_COMM_WORLD 通信器将分成两个通信器。 id 为偶数的进程将属于一个 communicator,id 为奇数的进程将属于另一个 communicator。
color=myid % 2;
MPI_Comm_split(MPI_COMM_WORLD,color,myid,&NEW_COMM);
MPI_Comm_rank( NEW_COMM, &new_id);
我的问题是这两个通信器的句柄在哪里。拆分后,之前为 0 1 2 3 4 5 6 7 的处理器 ID 将变为 0 2 4 6 | 1 3 5 7.
现在,我的问题是:假设我想在一个特定的通信器中发送和接收,比如托管偶数 ID 的通信器,那么当我使用错误的通信器从 0 发送消息到 2 时,消息可能最终出现在第二个通讯器,这是正确的吗?预先感谢您的澄清!
if(new_id < 2){
MPI_Send(&my_num, 1, MPI_INT, 2 + new_id, 0, NEW_COMM);
MPI_Recv(&my_received, 1, MPI_INT, 2 + new_id, 0, NEW_COMM, MPI_STATUS_IGNORE);
}
else
{
MPI_Recv(&my_received, 1, MPI_INT, new_id - 2, 0, NEW_COMM, MPI_STATUS_IGNORE);
MPI_Send(&my_num, 1, MPI_INT, new_id - 2 , 0, NEW_COMM);
}
完整代码
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <math.h>
int main(argc,argv)
int argc;
char *argv[];
{
int myid, numprocs;
int color,Zero_one,new_id,new_nodes;
MPI_Comm NEW_COMM;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
int my_num, my_received;
int old_id;
switch(myid){
case 0:
my_num = 0;
old_id = 0;
break;
case 1:
my_num = 1;
old_id = 1;
break;
case 2:
my_num = 2;
old_id = 2;
break;
case 3:
my_num = 3;
old_id = 3;
break;
case 4:
my_num = 4;
old_id = 4;
break;
case 5:
my_num = 5;
old_id = 5;
break;
case 6:
my_num = 6;
old_id = 6;
break;
case 7:
my_num = 7;
old_id = 7;
break;
}
color=myid % 2;
MPI_Comm_split(MPI_COMM_WORLD,color,myid,&NEW_COMM);
MPI_Comm_rank( NEW_COMM, &new_id);
MPI_Comm_rank( NEW_COMM, &new_nodes);
// 0 1 2 3 4 5 6 7 //After splits we have these nums for 8 processors
// 2 3 0 1 6 7 4 5 //After the below exchange we should have this...each two elements in each communicator will exchange to next two elements in that same communicator
if(new_id < 2){
MPI_Send(&my_num, 1, MPI_INT, 2 + new_id, 0, NEW_COMM);
MPI_Recv(&my_received, 1, MPI_INT, 2 + new_id, 0, NEW_COMM, MPI_STATUS_IGNORE);
}
else
{
MPI_Recv(&my_received, 1, MPI_INT, new_id - 2, 0, NEW_COMM, MPI_STATUS_IGNORE);
MPI_Send(&my_num, 1, MPI_INT, new_id - 2 , 0, NEW_COMM);
}
printf("old_id= %d received num= %d\n", old_id, my_received);
MPI_Finalize();
}
最佳答案
我已经编辑了您的问题,使其更清晰。此外,我修复了与通过调用 MPI_Comm_split 创建的两个新通信器相关的 ID。
第一个问题。调用 MPI_Comm_split 后的单个进程最多可以获得一个新创建的通信器的句柄(实际上,对于传递 MPI_UNDEFINED 作为颜色参数值的进程,返回的通信器最多可能等于 MPI_COMM_NULL)。这就是为什么初学者通常不理解这个调用的语义的原因:MPI_Comm_split 是一个集体调用,因此它必须被原始通信器中的所有进程调用。因此,每个进程调用它一次,但该函数返回 $k$ 个通信器,具体取决于所有进程提供的颜色参数值,将进程划分为 $k$ 个组。如果您对这种强大的机制不满意并且只想创建一个通信器,只需在进程进行的每个调用中提供 MPI_UNDEFINED 作为颜色参数的值,该进程不得属于新创建的通信器。但是,您应该使用其他允许创建通信器的可用函数,而不是 MPI_Comm_split。
第二个问题。如果语义现在很清楚,您将立即认识到使用 MPI_Comm_split 返回的通信器进行点对点或集体通信的进程永远不会与作为 MPI_Comm_split 返回的另一个通信器的一部分的进程交换数据。通信器提供了一个不同的通信器世界,因为每个通信器都关联了一组不同的进程。
现在,即使被属于 even ids communicator 的进程调用,您的代码片段也不会起作用。为什么 ?因为当 new_id < 2 时执行的代码将正确地从新通信器中等级为 0 的进程发送到新通信器中等级为 2 的进程,而新通信器中等级为 0 的进程将从新通信器中等级为 2 的进程接收新的传播者。然而,else 分支是有缺陷的。实际上,新通信器中偶数等级 >= 2 的所有进程都将执行它,而不仅仅是等级 2 的进程。在这种情况下,该分支将由新偶数中等级为 2、4 和 6 的进程执行ID 通讯器。当然,排名为 4 和 6 的进程将永远挂起,分别阻塞进程 2 和 4 从未发送过的消息。
最后,由于相同的代码也将由另一个新创建的 communicator 中具有奇数 id 的进程执行,因此 rank 1 的进程将尝试从 process 3 发送和接收,而在 else 分支中 ranks 3 的进程, 5 和 7 也会尝试发送和接收。在这种情况下,进程 5 和 7 将永远挂起,分别阻塞进程 3 和 5 从未发送过的消息。
如果您想在等级为 0 和 2 的进程之间交换数据,代码很容易修复。只需使用显式 ID 0 和 2 并重写 if 如下:
if(!new_id){
MPI_Send(&my_num, 1, MPI_INT, 2, 0, NEW_COMM);
MPI_Recv(&my_received, 1, MPI_INT, 2 + new_id, 0, NEW_COMM, MPI_STATUS_IGNORE);
}
if(new_id == 2){
MPI_Recv(&my_received, 1, MPI_INT, 0, 0, NEW_COMM, MPI_STATUS_IGNORE);
MPI_Send(&my_num, 1, MPI_INT, 0, 0, NEW_COMM);
}
关于c - MPI_Comm_split 之后句柄如何分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22737842/
调用 MPI_Comm_split 的成本是多少?它是否以 O(n)、O(log(n)) 或其他方式运行(n 是要拆分的 comm 中的等级数)? 我正在编写针对基于 infiniband 的 sup
比如说,我有 8 个进程。当我执行以下操作时,MPU_COMM_WORLD 通信器将分成两个通信器。 id 为偶数的进程将属于一个 communicator,id 为奇数的进程将属于另一个 commu
有人可以解释并告诉我更多关于 MPI_Comm_split 通信器的信息吗? MPI_Comm_split(MPI_COMM_WORLD, my_row, my_rank,&my_row_comm);
我正在类里面使用 C 语言学习 MPI。我目前正在尝试了解您何时使用 MPI_Comm_split 以及其优点是什么。如果我不使用组或者如果我的所有进程都在一个组中,我也想弄清楚使用它是否比仅使用 M
我遇到了一个 MPI_Split_comm 问题,似乎只有在使用 openmpi 1.4.3 时才会出现。示例代码: #include #include #include const size_
我是一名优秀的程序员,十分优秀!