C语言 何时释放MPI子组?

myzjeezk  于 2023-02-07  发布在  其他
关注(0)|答案(1)|浏览(166)

我正在一个执行任务的循环中创建MPI组,但是当我想要释放组时,计算中止。我应该何时释放组?
我得到的错误是:

[KLArch:13617] *** An error occurred in MPI_Comm_free
[KLArch:13617] *** reported by process [1712324609,2]
[KLArch:13617] *** on communicator MPI_COMM_WORLD
[KLArch:13617] *** MPI_ERR_COMM: invalid communicator
[KLArch:13617] *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
[KLArch:13617] ***    and potentially your MPI job)
[KLArch:13611] 2 more processes have sent help message help-mpi-errors.txt / mpi_errors_are_fatal
[KLArch:13611] Set MCA parameter "orte_base_help_aggregate" to 0 to see all help / error messages

我打算做的是并行执行一个进程数量不断增加的计算,作为MPI的基准,即只用1个进程执行整个计算,花点时间,用2个进程运行相同的计算,花点时间,用4个进程运行相同的计算,花点时间......然后比较问题如何随进程数量而扩展。
MWE:

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

int main(int argc, char *argv[])
{
    int j = 0;
    int size = 0;
    int rank = 0;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    // Get the group of processes in MPI_COMM_WORLD
    MPI_Group world_group;
    MPI_Comm_group(MPI_COMM_WORLD, &world_group);

    // Construct a group containing all of the ranks smaller than i in MPI_COMM_WORLD
    for (i = 1; i <= size; i++)
    {
        int group_ranks[i];
        for (int j = 0; j < i; j++)
        {
            group_ranks[j] = j;
        }

        // Construct a group with all the ranks smaller than i
        MPI_Group sub_group;
        MPI_Group_incl(world_group, i, group_ranks, &sub_group);

        // Create a communicator based on the group
        MPI_Comm sub_comm;
        MPI_Comm_create(MPI_COMM_WORLD, sub_group, &sub_comm);

        int sub_rank = -1;
        int sub_size = -1;
        // If this rank isn't in the new communicator, it will be
        // MPI_COMM_NULL. Using MPI_COMM_NULL for MPI_Comm_rank or
        // MPI_Comm_size is erroneous
        if (MPI_COMM_NULL != sub_comm)
        {
            MPI_Comm_rank(sub_comm, &sub_rank);
            MPI_Comm_size(sub_comm, &sub_size);
        }

        // Do some work
        printf("WORLD RANK/SIZE: %d/%d \t Group RANK/SIZE: %d/%d\n",
               rank, size, sub_rank, sub_size);

        // Free the communicator and group
        MPI_Barrier(MPI_COMM_WORLD);
        //MPI_Comm_free(&sub_comm);
        //MPI_Group_free(&sub_group);
        j = 0;
    }
    MPI_Group_free(&world_group);

    MPI_Finalize();
    return 0;
}

如果我在循环结束时取消注解MPI_Comm_free(&sub_comm);MPI_Group_free(&sub_group);,代码将抛出错误。

fykwrbwg

fykwrbwg1#

让我收集一些关于这段代码的注解。
1.不需要该屏障。
1.如果您在多节点系统上进行测试,则必须注意您进程分布并不均匀:3个6核节点上的13个进程会给予你6+6+1,这是不平衡的。你会想要5+4+4左右。你的mpiexec会正确地做到这一点;在你的代码中实现这一点有点困难。2只要意识到这一点,因为你正在做基准测试。
1.这段代码的编写有点麻烦,当你创建一个子组的时候,所有的进程对于这个组都有相同的值,包括那些不在这个组里的进程,比如他们没有得到MPI_GROUP_NULL,那么你必须在大型通信器上集体调用MPI_Comm_create;不在组中的进程得到MPI_COMM_NULL作为结果。它们不参与subcommunicator上的操作。另外,这是您的问题:它们不释放子通信器,但是它们释放子组。
(That最后一点也是@GillesGouaillardet指出的)

相关问题