Actual source code: mpiu.c
1: /*$Id: mpiu.c,v 1.100 2001/03/23 23:20:45 balay Exp $*/
3: #include petsc.h
5: #undef __FUNCT__
7: int PetscSequentialPhaseBegin_Private(MPI_Comm comm,int ng)
8: {
9: int lidx,np,tag = 0,ierr;
10: MPI_Status status;
13: MPI_Comm_size(comm,&np);
14: if (np == 1) return(0);
15: MPI_Comm_rank(comm,&lidx);
16: if (lidx != 0) {
17: MPI_Recv(0,0,MPI_INT,lidx-1,tag,comm,&status);
18: }
19: /* Send to the next process in the group unless we are the last process */
20: if ((lidx % ng) < ng - 1 && lidx != np - 1) {
21: MPI_Send(0,0,MPI_INT,lidx + 1,tag,comm);
22: }
23: return(0);
24: }
26: #undef __FUNCT__
28: int PetscSequentialPhaseEnd_Private(MPI_Comm comm,int ng)
29: {
30: int lidx,np,tag = 0,ierr;
31: MPI_Status status;
34: MPI_Comm_rank(comm,&lidx);
35: MPI_Comm_size(comm,&np);
36: if (np == 1) return(0);
38: /* Send to the first process in the next group */
39: if ((lidx % ng) == ng - 1 || lidx == np - 1) {
40: MPI_Send(0,0,MPI_INT,(lidx + 1) % np,tag,comm);
41: }
42: if (!lidx) {
43: MPI_Recv(0,0,MPI_INT,np-1,tag,comm,&status);
44: }
45: return(0);
46: }
48: /* ---------------------------------------------------------------------*/
49: /*
50: The variable Petsc_Seq_keyval is used to indicate an MPI attribute that
51: is attached to a communicator that manages the sequential phase code below.
52: */
53: static int Petsc_Seq_keyval = MPI_KEYVAL_INVALID;
55: #undef __FUNCT__
57: /*@C
58: PetscSequentialPhaseBegin - Begins a sequential section of code.
60: Collective on MPI_Comm
62: Input Parameters:
63: + comm - Communicator to sequentialize.
64: - ng - Number in processor group. This many processes are allowed to execute
65: at the same time (usually 1)
67: Level: intermediate
69: Notes:
70: PetscSequentialPhaseBegin() and PetscSequentialPhaseEnd() provide a
71: way to force a section of code to be executed by the processes in
72: rank order. Typically, this is done with
73: .vb
74: PetscSequentialPhaseBegin(comm, 1);
75: <code to be executed sequentially>
76: PetscSequentialPhaseEnd(comm, 1);
77: .ve
79: Often, the sequential code contains output statements (e.g., printf) to
80: be executed. Note that you may need to flush the I/O buffers before
81: calling PetscSequentialPhaseEnd(). Also, note that some systems do
82: not propagate I/O in any order to the controling terminal (in other words,
83: even if you flush the output, you may not get the data in the order
84: that you want).
86: .seealso: PetscSequentialPhaseEnd()
88: Concepts: sequential stage
90: @*/
91: int PetscSequentialPhaseBegin(MPI_Comm comm,int ng)
92: {
93: int ierr,np;
94: MPI_Comm local_comm,*addr_local_comm;
97: MPI_Comm_size(comm,&np);
98: if (np == 1) return(0);
100: /* Get the private communicator for the sequential operations */
101: if (Petsc_Seq_keyval == MPI_KEYVAL_INVALID) {
102: MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Seq_keyval,0);
103: }
105: MPI_Comm_dup(comm,&local_comm);
106: PetscMalloc(sizeof(MPI_Comm),&addr_local_comm);
107: *addr_local_comm = local_comm;
108: MPI_Attr_put(comm,Petsc_Seq_keyval,(void*)addr_local_comm);
109: PetscSequentialPhaseBegin_Private(local_comm,ng);
110: return(0);
111: }
113: #undef __FUNCT__
115: /*@C
116: PetscSequentialPhaseEnd - Ends a sequential section of code.
118: Collective on MPI_Comm
120: Input Parameters:
121: + comm - Communicator to sequentialize.
122: - ng - Number in processor group. This many processes are allowed to execute
123: at the same time (usually 1)
125: Level: intermediate
127: Notes:
128: See PetscSequentialPhaseBegin() for more details.
130: .seealso: PetscSequentialPhaseBegin()
132: Concepts: sequential stage
134: @*/
135: int PetscSequentialPhaseEnd(MPI_Comm comm,int ng)
136: {
137: int ierr,np,flag;
138: MPI_Comm local_comm,*addr_local_comm;
141: MPI_Comm_size(comm,&np);
142: if (np == 1) return(0);
144: MPI_Attr_get(comm,Petsc_Seq_keyval,(void **)&addr_local_comm,&flag);
145: if (!flag) {
146: SETERRQ(1,"Wrong MPI communicator; must pass in one used with PetscSequentialPhaseBegin()");
147: }
148: local_comm = *addr_local_comm;
150: PetscSequentialPhaseEnd_Private(local_comm,ng);
152: PetscFree(addr_local_comm);
153: MPI_Comm_free(&local_comm);
154: MPI_Attr_delete(comm,Petsc_Seq_keyval);
156: return(0);
157: }