Actual source code: commonmpvec.c

petsc-3.8.3 2017-12-09
Report Typos and Errors

  2:  #include <../src/vec/vec/impls/mpi/pvecimpl.h>

  4: /*
  5:   This is used in VecGhostGetLocalForm and VecGhostRestoreLocalForm to ensure
  6:   that the state is updated if either vector has changed since the last time
  7:   one of these functions was called.  It could apply to any PetscObject, but
  8:   VecGhost is quite different from other objects in that two separate vectors
  9:   look at the same memory.

 11:   In principle, we could only propagate state to the local vector on
 12:   GetLocalForm and to the global vector on RestoreLocalForm, but this version is
 13:   more conservative (i.e. robust against misuse) and simpler.

 15:   Note that this function is correct and changes nothing if both arguments are the
 16:   same, which is the case in serial.
 17: */
 18: static PetscErrorCode VecGhostStateSync_Private(Vec g,Vec l)
 19: {
 20:   PetscErrorCode   ierr;
 21:   PetscObjectState gstate,lstate;

 24:   PetscObjectStateGet((PetscObject)g,&gstate);
 25:   PetscObjectStateGet((PetscObject)l,&lstate);
 26:   PetscObjectStateSet((PetscObject)g,PetscMax(gstate,lstate));
 27:   PetscObjectStateSet((PetscObject)l,PetscMax(gstate,lstate));
 28:   return(0);
 29: }


 32: /*@
 33:     VecGhostGetLocalForm - Obtains the local ghosted representation of
 34:     a parallel vector (obtained with VecCreateGhost(), VecCreateGhostWithArray()
 35:     or VecCreateSeq()). Returns NULL if the Vec is not ghosted.

 37:     Logically Collective

 39:     Input Parameter:
 40: .   g - the global vector

 42:     Output Parameter:
 43: .   l - the local (ghosted) representation, NULL if g is not ghosted

 45:     Notes:
 46:     This routine does not actually update the ghost values, but rather it
 47:     returns a sequential vector that includes the locations for the ghost
 48:     values and their current values. The returned vector and the original
 49:     vector passed in share the same array that contains the actual vector data.

 51:     To update the ghost values from the locations on the other processes one must call
 52:     VecGhostUpdateBegin() and VecGhostUpdateEnd() before accessing the ghost values. Thus normal
 53:     usage is
 54: $     VecGhostUpdateBegin(x,INSERT_VALUES,SCATTER_FORWARD);
 55: $     VecGhostUpdateEnd(x,INSERT_VALUES,SCATTER_FORWARD);
 56: $     VecGhostGetLocalForm(x,&xlocal);
 57: $     VecGetArray(xlocal,&xvalues);
 58: $        // access the non-ghost values in locations xvalues[0:n-1] and ghost values in locations xvalues[n:n+nghost];
 59: $     VecRestoreArray(xlocal,&xvalues);
 60: $     VecGhostRestoreLocalForm(x,&xlocal);

 62:     One should call VecGhostRestoreLocalForm() or VecDestroy() once one is
 63:     finished using the object.

 65:     Level: advanced

 67:    Concepts: vectors^ghost point access

 69: .seealso: VecCreateGhost(), VecGhostRestoreLocalForm(), VecCreateGhostWithArray()

 71: @*/
 72: PetscErrorCode  VecGhostGetLocalForm(Vec g,Vec *l)
 73: {
 75:   PetscBool      isseq,ismpi;


 81:   PetscObjectTypeCompare((PetscObject)g,VECSEQ,&isseq);
 82:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
 83:   if (ismpi) {
 84:     Vec_MPI *v = (Vec_MPI*)g->data;
 85:     *l = v->localrep;
 86:   } else if (isseq) {
 87:     *l = g;
 88:   } else {
 89:     *l = NULL;
 90:   }
 91:   if (*l) {
 92:     VecGhostStateSync_Private(g,*l);
 93:     PetscObjectReference((PetscObject)*l);
 94:   }
 95:   return(0);
 96: }

 98: /*@
 99:     VecGhostIsLocalForm - Checks if a given vector is the local form of a global vector

101:     Not Collective

103:     Input Parameter:
104: +   g - the global vector
105: -   l - the local vector

107:     Output Parameter:
108: .   flg - PETSC_TRUE if local vector is local form

110:     Level: advanced

112:    Concepts: vectors^ghost point access

114: .seealso: VecCreateGhost(), VecGhostRestoreLocalForm(), VecCreateGhostWithArray(), VecGhostGetLocalForm()

116: @*/
117: PetscErrorCode VecGhostIsLocalForm(Vec g,Vec l,PetscBool *flg)
118: {
120:   PetscBool      isseq,ismpi;


126:   *flg = PETSC_FALSE;
127:   PetscObjectTypeCompare((PetscObject)g,VECSEQ,&isseq);
128:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
129:   if (ismpi) {
130:     Vec_MPI *v = (Vec_MPI*)g->data;
131:     if (l == v->localrep) *flg = PETSC_TRUE;
132:   } else if (isseq) {
133:     if (l == g) *flg = PETSC_TRUE;
134:   } else SETERRQ(PetscObjectComm((PetscObject)g),PETSC_ERR_ARG_WRONG,"Global vector is not ghosted");
135:   return(0);
136: }

138: /*@
139:     VecGhostRestoreLocalForm - Restores the local ghosted representation of
140:     a parallel vector obtained with VecGhostGetLocalForm().

142:     Logically Collective

144:     Input Parameter:
145: +   g - the global vector
146: -   l - the local (ghosted) representation

148:     Notes:
149:     This routine does not actually update the ghost values, but rather it
150:     returns a sequential vector that includes the locations for the ghost values
151:     and their current values.

153:     Level: advanced

155: .seealso: VecCreateGhost(), VecGhostGetLocalForm(), VecCreateGhostWithArray()
156: @*/
157: PetscErrorCode  VecGhostRestoreLocalForm(Vec g,Vec *l)
158: {

162:   if (*l) {
163:     VecGhostStateSync_Private(g,*l);
164:     PetscObjectDereference((PetscObject)*l);
165:   }
166:   return(0);
167: }

169: /*@
170:    VecGhostUpdateBegin - Begins the vector scatter to update the vector from
171:    local representation to global or global representation to local.

173:    Neighbor-wise Collective on Vec

175:    Input Parameters:
176: +  g - the vector (obtained with VecCreateGhost() or VecDuplicate())
177: .  insertmode - one of ADD_VALUES or INSERT_VALUES
178: -  scattermode - one of SCATTER_FORWARD or SCATTER_REVERSE

180:    Notes:
181:    Use the following to update the ghost regions with correct values from the owning process
182: .vb
183:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
184:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
185: .ve

187:    Use the following to accumulate the ghost region values onto the owning processors
188: .vb
189:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
190:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
191: .ve

193:    To accumulate the ghost region values onto the owning processors and then update
194:    the ghost regions correctly, call the later followed by the former, i.e.,
195: .vb
196:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
197:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
198:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
199:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
200: .ve

202:    Level: advanced

204: .seealso: VecCreateGhost(), VecGhostUpdateEnd(), VecGhostGetLocalForm(),
205:           VecGhostRestoreLocalForm(),VecCreateGhostWithArray()

207: @*/
208: PetscErrorCode  VecGhostUpdateBegin(Vec g,InsertMode insertmode,ScatterMode scattermode)
209: {
210:   Vec_MPI        *v;
212:   PetscBool      ismpi,isseq;

216:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
217:   PetscObjectTypeCompare((PetscObject)g,VECSEQ,&isseq);
218:   if (ismpi) {
219:     v = (Vec_MPI*)g->data;
220:     if (!v->localrep) SETERRQ(PetscObjectComm((PetscObject)g),PETSC_ERR_ARG_WRONG,"Vector is not ghosted");
221:     if (!v->localupdate) return(0);
222:     if (scattermode == SCATTER_REVERSE) {
223:       VecScatterBegin(v->localupdate,v->localrep,g,insertmode,scattermode);
224:     } else {
225:       VecScatterBegin(v->localupdate,g,v->localrep,insertmode,scattermode);
226:     }
227:   } else if (isseq) {
228:     /* Do nothing */
229:   } else SETERRQ(PetscObjectComm((PetscObject)g),PETSC_ERR_ARG_WRONG,"Vector is not ghosted");
230:   return(0);
231: }

233: /*@
234:    VecGhostUpdateEnd - End the vector scatter to update the vector from
235:    local representation to global or global representation to local.

237:    Neighbor-wise Collective on Vec

239:    Input Parameters:
240: +  g - the vector (obtained with VecCreateGhost() or VecDuplicate())
241: .  insertmode - one of ADD_VALUES or INSERT_VALUES
242: -  scattermode - one of SCATTER_FORWARD or SCATTER_REVERSE

244:    Notes:

246:    Use the following to update the ghost regions with correct values from the owning process
247: .vb
248:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
249:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
250: .ve

252:    Use the following to accumulate the ghost region values onto the owning processors
253: .vb
254:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
255:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
256: .ve

258:    To accumulate the ghost region values onto the owning processors and then update
259:    the ghost regions correctly, call the later followed by the former, i.e.,
260: .vb
261:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
262:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
263:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
264:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
265: .ve

267:    Level: advanced

269: .seealso: VecCreateGhost(), VecGhostUpdateBegin(), VecGhostGetLocalForm(),
270:           VecGhostRestoreLocalForm(),VecCreateGhostWithArray()

272: @*/
273: PetscErrorCode  VecGhostUpdateEnd(Vec g,InsertMode insertmode,ScatterMode scattermode)
274: {
275:   Vec_MPI        *v;
277:   PetscBool      ismpi;

281:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
282:   if (ismpi) {
283:     v = (Vec_MPI*)g->data;
284:     if (!v->localrep) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Vector is not ghosted");
285:     if (!v->localupdate) return(0);
286:     if (scattermode == SCATTER_REVERSE) {
287:       VecScatterEnd(v->localupdate,v->localrep,g,insertmode,scattermode);
288:     } else {
289:       VecScatterEnd(v->localupdate,g,v->localrep,insertmode,scattermode);
290:     }
291:   }
292:   return(0);
293: }