#include "mpi.h"
#include <stdio.h>
#include "ic_nxtval.h"
#define ICTAG 0
int MPE_Counter_create_ic(MPI_Comm oldcomm, MPI_Comm *smaller_comm,
MPI_Comm *counter_comm)
{
int counter = 0, message, done = 0, myid, numprocs, server;
int color, remote_leader_rank;
MPI_Status status;
MPI_Comm oldcommdup, splitcomm;
MPI_Comm_dup(oldcomm, &oldcommdup);
MPI_Comm_size(oldcommdup, &numprocs);
MPI_Comm_rank(oldcommdup, &myid);
server = numprocs-1; /* last proc is server */
/* server = 0; */
color = (myid == server); /* split into server and rest */
MPI_Comm_split(oldcomm, color, myid, &splitcomm);
/* build intercommunicator using bridge w/ oldcommdup */
if(!color) { /* I am not the server */
/* 1) the non-server leader process is chosen to have rank
"0" in the peer comm. oldcommdup != rank of server
guaranteed that this leader "0" has rank "0" in both
oldcommdup and in this splitcomm too, by virtue of
MPI_Comm_split
2) server has rank "server" in oldcommdup */
remote_leader_rank = server; /* server rank, oldcommdup */
*smaller_comm = splitcomm; /* return new, smaller world */
}
else {
remote_leader_rank = 0; /* non-server leader, oldcommdup */
*smaller_comm = MPI_COMM_NULL;
}
MPI_Intercomm_create(splitcomm, 0, oldcommdup,
remote_leader_rank, ICTAG, counter_comm);
MPI_Comm_free(&oldcommdup); /* not needed after
Intercomm_create */
/* The rest is the same code as in nxtval_create.c */
if (myid == server) { /* I am the server */
while (!done) {
MPI_Recv(&message, 1, MPI_INT, MPI_ANY_SOURCE,
MPI_ANY_TAG, *counter_comm, &status );
if (status.MPI_TAG == REQUEST) {
MPI_Send(&counter, 1, MPI_INT, status.MPI_SOURCE,
VALUE, *counter_comm );
counter++;
}
else if (status.MPI_TAG == GOAWAY) {
done = 1;
}
else {
fprintf(stderr, "bad tag %d sent to MPE counter\n",
status.MPI_TAG );
MPI_Abort( *counter_comm, 1 );
}
}
MPI_Comm_free( counter_comm );
}
}