新通信器无效MPI

3

我希望创建一个新的通信器,仅保存在处理中使用的排名。如果有24个可用处理器,而我只需要10个,则该组应仅保留这10个,否则将保存所有处理器。但是,当我尝试创建通信器时,一切都执行成功,但是当我尝试获取新通信器的大小或排名时,MPI会停止并出现错误。

 80     float **matrix;
 81     int *ranksArr;
 82     MPI_Comm default_comm;
 83     MPI_Group world_grp, new_grp;
 84     MPI_Comm_rank(MPI_COMM_WORLD, &proc_rank);
 85     MPI_Comm_size(MPI_COMM_WORLD, &proc_avail);
 86     MPI_Comm_group(MPI_COMM_WORLD, &world_grp);

 91     compute_block_size(&block, proc_avail);
 92
 93     if(block.procsUsed == proc_avail)
 94     {
 95         ranksArr = alloc_ranks_arr(proc_avail);
 96     }
 97     else
 98     {
 99         ranksArr = alloc_ranks_arr(block.procsUsed);
100         proc_avail = block.procsUsed;
101     }
102
103     MPI_Group_incl(world_grp, proc_avail, ranksArr, &new_grp);
104     MPI_Comm_create(MPI_COMM_WORLD, new_grp, &default_comm);
105     //MPI_Comm_size(default_comm, &proc_avail); //ERROR, default_comm
106
107     MPI_Comm_rank(default_comm, &proc_rank);
108
111     matrix = create_matrix_sub(&block, proc_rank);
112
113
114     dealloc_matrix(matrix);

178 int* alloc_ranks_arr(int totalRanks)
179 {
180     int *ranksToGroup = malloc(totalRanks * sizeof(int));
181     int i;
182
183     for(i = 0; i < totalRanks ; i++)
184     {
185         ranksToGroup[i] = i;
186     }
187
188     return ranksToGroup;
189 }

[cluster-srv2:24701] * 在 MPI_Comm_rank 中发生错误 [cluster-srv2:24701] *,通信器为 MPI_COMM_WORLD [cluster-srv2:24701] * MPI_ERR_COMM: 无效的通信器 [cluster-srv2:24701] * MPI_ERRORS_ARE_FATAL (你的 MPI 作业将会中止)

文档中指出:

MPI_ERR_COMM 无效的通信器。一个常见的错误是在调用中使用空通信器(甚至不允许在 MPI_Comm_rank 中使用)。

但是我在调用 Comm_rank 之前创建了通信器,并且 MPI_Comm_create 的返回值给出了 MPI_SUCCESS。所以我不知道为什么会发生这种情况。


在查看了不同的示例后,我认为我理解了这个问题。因为我只为组生成0-9,所以另外13个处理器从未被包含在其中,我怀疑当非组成员的排名调用新创建的通信时,这会使其无效。由于我不想使用那些处理器,我考虑在我不使用的每个排名上调用MPI_Finalize。我不确定这种方法是否可行,但现在可能只能这样做。 - Patrick.SE
1个回答

5

快速查看 MPI_Comm_create 的文档,得知:

如果进程使用一个它不属于的 group,例如 MPI_GROUP_EMPTY,那么将返回 MPI_COMM_NULL 作为 newcomm

因此,即使 MPI_Comm_create() 调用成功,进程11-24 在 default_comm 中接收到 MPI_COMM_NULL,这在任何操作中都是非法的。

在调用 MPI_Comm_create 后,应根据进程是否在新通信子中进行分支,最好通过检查 default_comm == MPI_COMM_NULL 来实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接