Actual source code: mpiu.c

petsc-3.5.1 2014-08-06
Report Typos and Errors
  2: #include <petscsys.h>        /*I  "petscsys.h"  I*/
  3: /*
  4:     Note that tag of 0 is ok because comm is a private communicator
  5:   generated below just for these routines.
  6: */

 10: PetscErrorCode PetscSequentialPhaseBegin_Private(MPI_Comm comm,int ng)
 11: {
 13:   PetscMPIInt    rank,size,tag = 0;
 14:   MPI_Status     status;

 17:   MPI_Comm_size(comm,&size);
 18:   if (size == 1) return(0);
 19:   MPI_Comm_rank(comm,&rank);
 20:   if (rank) {
 21:     MPI_Recv(0,0,MPI_INT,rank-1,tag,comm,&status);
 22:   }
 23:   /* Send to the next process in the group unless we are the last process */
 24:   if ((rank % ng) < ng - 1 && rank != size - 1) {
 25:     MPI_Send(0,0,MPI_INT,rank + 1,tag,comm);
 26:   }
 27:   return(0);
 28: }

 32: PetscErrorCode PetscSequentialPhaseEnd_Private(MPI_Comm comm,int ng)
 33: {
 35:   PetscMPIInt    rank,size,tag = 0;
 36:   MPI_Status     status;

 39:   MPI_Comm_rank(comm,&rank);
 40:   MPI_Comm_size(comm,&size);
 41:   if (size == 1) return(0);

 43:   /* Send to the first process in the next group */
 44:   if ((rank % ng) == ng - 1 || rank == size - 1) {
 45:     MPI_Send(0,0,MPI_INT,(rank + 1) % size,tag,comm);
 46:   }
 47:   if (!rank) {
 48:     MPI_Recv(0,0,MPI_INT,size-1,tag,comm,&status);
 49:   }
 50:   return(0);
 51: }

 53: /* ---------------------------------------------------------------------*/
 54: /*
 55:     The variable Petsc_Seq_keyval is used to indicate an MPI attribute that
 56:   is attached to a communicator that manages the sequential phase code below.
 57: */
 58: static int Petsc_Seq_keyval = MPI_KEYVAL_INVALID;

 62: /*@
 63:    PetscSequentialPhaseBegin - Begins a sequential section of code.

 65:    Collective on MPI_Comm

 67:    Input Parameters:
 68: +  comm - Communicator to sequentialize.
 69: -  ng   - Number in processor group.  This many processes are allowed to execute
 70:    at the same time (usually 1)

 72:    Level: intermediate

 74:    Notes:
 75:    PetscSequentialPhaseBegin() and PetscSequentialPhaseEnd() provide a
 76:    way to force a section of code to be executed by the processes in
 77:    rank order.  Typically, this is done with
 78: .vb
 79:       PetscSequentialPhaseBegin(comm, 1);
 80:       <code to be executed sequentially>
 81:       PetscSequentialPhaseEnd(comm, 1);
 82: .ve

 84:    Often, the sequential code contains output statements (e.g., printf) to
 85:    be executed.  Note that you may need to flush the I/O buffers before
 86:    calling PetscSequentialPhaseEnd().  Also, note that some systems do
 87:    not propagate I/O in any order to the controling terminal (in other words,
 88:    even if you flush the output, you may not get the data in the order
 89:    that you want).

 91: .seealso: PetscSequentialPhaseEnd()

 93:    Concepts: sequential stage

 95: @*/
 96: PetscErrorCode  PetscSequentialPhaseBegin(MPI_Comm comm,int ng)
 97: {
 99:   PetscMPIInt    size;
100:   MPI_Comm       local_comm,*addr_local_comm;

103:   MPI_Comm_size(comm,&size);
104:   if (size == 1) return(0);

106:   /* Get the private communicator for the sequential operations */
107:   if (Petsc_Seq_keyval == MPI_KEYVAL_INVALID) {
108:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Seq_keyval,0);
109:   }

111:   MPI_Comm_dup(comm,&local_comm);
112:   PetscMalloc(sizeof(MPI_Comm),&addr_local_comm);

114:   *addr_local_comm = local_comm;

116:   MPI_Attr_put(comm,Petsc_Seq_keyval,(void*)addr_local_comm);
117:   PetscSequentialPhaseBegin_Private(local_comm,ng);
118:   return(0);
119: }

123: /*@
124:    PetscSequentialPhaseEnd - Ends a sequential section of code.

126:    Collective on MPI_Comm

128:    Input Parameters:
129: +  comm - Communicator to sequentialize.
130: -  ng   - Number in processor group.  This many processes are allowed to execute
131:    at the same time (usually 1)

133:    Level: intermediate

135:    Notes:
136:    See PetscSequentialPhaseBegin() for more details.

138: .seealso: PetscSequentialPhaseBegin()

140:    Concepts: sequential stage

142: @*/
143: PetscErrorCode  PetscSequentialPhaseEnd(MPI_Comm comm,int ng)
144: {
146:   PetscMPIInt    size,flag;
147:   MPI_Comm       local_comm,*addr_local_comm;

150:   MPI_Comm_size(comm,&size);
151:   if (size == 1) return(0);

153:   MPI_Attr_get(comm,Petsc_Seq_keyval,(void**)&addr_local_comm,&flag);
154:   if (!flag) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Wrong MPI communicator; must pass in one used with PetscSequentialPhaseBegin()");
155:   local_comm = *addr_local_comm;

157:   PetscSequentialPhaseEnd_Private(local_comm,ng);

159:   PetscFree(addr_local_comm);
160:   MPI_Comm_free(&local_comm);
161:   MPI_Attr_delete(comm,Petsc_Seq_keyval);
162:   return(0);
163: }