2016-05-12 32 views
0

Ich verwende einen Beispielcode aus einem MPI-Buch [wird den Namen in Kürze geben].Zwei MPI_Allreduce() Funktionen funktionieren nicht, gibt Fehler von NULL Communicator

Was sie tut, ist die folgende:

a) Es schafft zwei Kommunikatoren world = MPI_COMM_WORLD alle Prozesse und worker enthalten, die den random number generator server (den letzten Rang Prozess ausschließt).

b) So erzeugt die server Zufallszahl und dient sie die workers auf requests vom workers.

c) Was die workers tun, ist sie separat die Anzahl der Proben zählen fallen inside und outside ein unit circle innerhalb eines unit square.

d) Nach einem ausreichenden Maß an Genauigkeit, und die Zählwerte insideoutside sind Allreduce d den Wert von PI als ihr Verhältnis zu berechnen.

** Der Code wird gut kompiliert. Wenn jedoch mit dem folgenden Befehl ein (tatsächlich mit einem beliebigen Wert von n) **

>mpiexec -n 2 apple.exe 0.0001 

ich die folgenden Fehler zum Laufen bringen:

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 

bearbeiten: (((Entfernt: Aber wenn ich eine der beiden MPI_Allreduce() Funktionen entferne, läuft es ohne irgendwelche Laufzeitfehler, wenn auch mit falscher Antwort))

Code: hier

#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(); 
} 

Was ist der Fehler? Fehle ich etwas? Jede Hilfe oder Zeiger wird sehr geschätzt.

+0

Haben Sie versucht, mit 4 Prozessen zu laufen? – gsamaras

+0

@gsamaras Wie bereits oben erwähnt, bekomme ich bei jedem Wert von 'n' die gleichen Fehler (Anzahl der Fehler abhängig von' n'), sei es 'n = 2', 'n = 4',' n = 5'. –

Antwort

1

Sie befreien den workers Communicator, bevor Sie damit fertig sind. Verschieben Sie den MPI_Comm_free(&workers) Anruf nach der while(!done) { ... } Schleife.

+0

@ hristoIlliev Genau! Vielen Dank! –