两个 MPI_Allreduce() 函数不起作用,给出 NULL Communicator 错误

Two MPI_Allreduce() functions not working, gives error of NULL Communicator

我正在使用 MPI 书中的示例代码 [稍后将给出名称]。

它的作用如下:

a) 它创建两个通信器 world = MPI_COMM_WORLD 包含所有进程和 worker 排除 random number generator server (最后一个等级进程)。

b) 因此,server 生成随机数并将它们从 workers.

提供给 requests 上的 workers

c) workers 所做的是他们分别计算落在 insideoutsideunit circleunit square 的样本数量。

d) 在达到足够的准确度后,计数 insideoutsideAllreduced 以计算 PI 的值作为它们的比率。

**代码编译良好。但是,当运行下面的命令(实际上是n的任意值)**

>mpiexec -n 2 apple.exe 0.0001

我收到以下错误:

Fatal error in MPI_Allreduce: Invalid communicator, error stack:
MPI_Allreduce(855): MPI_Allreduce(sbuf=000000000022EDCC, rbuf=000000000022EDDC,
count=1, MPI_INT, MPI_SUM, MPI_COMM_NULL) failed
MPI_Allreduce(780): Null communicator
pi =  0.00000000000000000000
job aborted:
rank: node: exit code[: error message]
0: PC: 1: process 0 exited without calling finalize
1: PC: 123

编辑: (((删除:但是当我删除两个MPI_Allreduce()函数中的任何一个时,它是运行排除任何运行时错误,尽管答案错误。))

代码:

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

#define CHUNKSIZE 1000
/* message tags */
#define REQUEST 1
#define REPLY 2

int main(int argc, char *argv[])
{
    int iter;
    int in, out, i, iters, max, ix, iy, ranks [1], done, temp;
    double x, y, Pi, error, epsilon;
    int numprocs, myid, server, totalin, totalout, workerid;
    int rands[CHUNKSIZE], request;
    MPI_Comm world, workers;
    MPI_Group world_group, worker_group;
    MPI_Status status;
    MPI_Init(&argc,&argv);
    world = MPI_COMM_WORLD;
    MPI_Comm_size(world,&numprocs);
    MPI_Comm_rank(world,&myid);
    server = numprocs-1; /* last proc is server */
    if(myid==0) sscanf(argv[1], "%lf", &epsilon);
    MPI_Bcast(&epsilon, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    MPI_Comm_group(world, &world_group);
    ranks[0] = server;
    MPI_Group_excl(world_group, 1, ranks, &worker_group);
    MPI_Comm_create(world, worker_group, &workers);
    MPI_Group_free(&worker_group);
    if(myid==server)   /* I am the rand server */
    {
        srand(time(NULL));
        do
        {
            MPI_Recv(&request, 1, MPI_INT, MPI_ANY_SOURCE, REQUEST, world, &status);
            if(request)
            {
                for(i=0; i<CHUNKSIZE;)
                {
                    rands[i] = rand();
                    if(rands[i]<=INT_MAX) ++i;
                }
                MPI_Send(rands, CHUNKSIZE, MPI_INT,status.MPI_SOURCE, REPLY, world);
            }
        }
        while(request>0);
    }
    else   /* I am a worker process */
    {
        request = 1;
        done = in = out = 0;
        max = INT_MAX; /* max int, for normalization */
        MPI_Send(&request, 1, MPI_INT, server, REQUEST, world);
        MPI_Comm_rank(workers, &workerid);
        iter = 0;
        while(!done)
        {
            ++iter;
            request = 1;
            MPI_Recv(rands, CHUNKSIZE, MPI_INT, server, REPLY, world, &status);
            for(i=0; i<CHUNKSIZE;)
            {
                x = (((double) rands[i++])/max)*2-1;
                y = (((double) rands[i++])/max)*2-1;
                if(x*x+y*y<1.0) ++in;
                else ++out;
            }

            /* ** see error here ** */
            MPI_Allreduce(&in, &totalin, 1, MPI_INT, MPI_SUM, workers);
            MPI_Allreduce(&out, &totalout, 1, MPI_INT, MPI_SUM, workers);
            /* only one of the above two MPI_Allreduce() functions working */

            Pi = (4.0*totalin)/(totalin+totalout);
            error = fabs( Pi-3.141592653589793238462643);
            done = (error<epsilon||(totalin+totalout)>1000000);
            request = (done)?0:1;
            if(myid==0)
            {
                printf("\rpi = %23.20f", Pi);
                MPI_Send(&request, 1, MPI_INT, server, REQUEST, world);
            }
            else
            {
                if(request)
                    MPI_Send(&request, 1, MPI_INT, server, REQUEST, world);
            }
            MPI_Comm_free(&workers);
        }
    }
    if(myid==0)
    {
        printf("\npoints: %d\nin: %d, out: %d, <ret> to exit\n", totalin+totalout, totalin, totalout);
        getchar();
    }
    MPI_Finalize();
}

这里有什么错误?我错过了什么吗?任何帮助或指示将不胜感激。

您正在释放 workers 通信器,然后再使用它。在 while(!done) { ... } 循环之后移动 MPI_Comm_free(&workers) 调用。