Actual source code: commonmpvec.c
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: PetscObjectState gstate, lstate;
22: PetscObjectStateGet((PetscObject)g, &gstate);
23: PetscObjectStateGet((PetscObject)l, &lstate);
24: PetscObjectStateSet((PetscObject)g, PetscMax(gstate, lstate));
25: PetscObjectStateSet((PetscObject)l, PetscMax(gstate, lstate));
26: return 0;
27: }
29: /*@
30: VecGhostGetLocalForm - Obtains the local ghosted representation of
31: a parallel vector (obtained with VecCreateGhost(), VecCreateGhostWithArray()
32: or VecCreateSeq()). Returns NULL if the Vec is not ghosted.
34: Logically Collective
36: Input Parameter:
37: . g - the global vector
39: Output Parameter:
40: . l - the local (ghosted) representation, NULL if g is not ghosted
42: Notes:
43: This routine does not actually update the ghost values, but rather it
44: returns a sequential vector that includes the locations for the ghost
45: values and their current values. The returned vector and the original
46: vector passed in share the same array that contains the actual vector data.
48: To update the ghost values from the locations on the other processes one must call
49: VecGhostUpdateBegin() and VecGhostUpdateEnd() before accessing the ghost values. Thus normal
50: usage is
51: $ VecGhostUpdateBegin(x,INSERT_VALUES,SCATTER_FORWARD);
52: $ VecGhostUpdateEnd(x,INSERT_VALUES,SCATTER_FORWARD);
53: $ VecGhostGetLocalForm(x,&xlocal);
54: $ VecGetArray(xlocal,&xvalues);
55: $ // access the non-ghost values in locations xvalues[0:n-1] and ghost values in locations xvalues[n:n+nghost];
56: $ VecRestoreArray(xlocal,&xvalues);
57: $ VecGhostRestoreLocalForm(x,&xlocal);
59: One should call VecGhostRestoreLocalForm() or VecDestroy() once one is
60: finished using the object.
62: Level: advanced
64: .seealso: `VecCreateGhost()`, `VecGhostRestoreLocalForm()`, `VecCreateGhostWithArray()`
66: @*/
67: PetscErrorCode VecGhostGetLocalForm(Vec g, Vec *l)
68: {
69: PetscBool isseq, ismpi;
74: PetscObjectTypeCompare((PetscObject)g, VECSEQ, &isseq);
75: PetscObjectTypeCompare((PetscObject)g, VECMPI, &ismpi);
76: if (ismpi) {
77: Vec_MPI *v = (Vec_MPI *)g->data;
78: *l = v->localrep;
79: } else if (isseq) {
80: *l = g;
81: } else {
82: *l = NULL;
83: }
84: if (*l) {
85: VecGhostStateSync_Private(g, *l);
86: PetscObjectReference((PetscObject)*l);
87: }
88: return 0;
89: }
91: /*@
92: VecGhostIsLocalForm - Checks if a given vector is the local form of a global vector
94: Not Collective
96: Input Parameters:
97: + g - the global vector
98: - l - the local vector
100: Output Parameter:
101: . flg - PETSC_TRUE if local vector is local form
103: Level: advanced
105: .seealso: `VecCreateGhost()`, `VecGhostRestoreLocalForm()`, `VecCreateGhostWithArray()`, `VecGhostGetLocalForm()`
107: @*/
108: PetscErrorCode VecGhostIsLocalForm(Vec g, Vec l, PetscBool *flg)
109: {
110: PetscBool isseq, ismpi;
115: *flg = PETSC_FALSE;
116: PetscObjectTypeCompare((PetscObject)g, VECSEQ, &isseq);
117: PetscObjectTypeCompare((PetscObject)g, VECMPI, &ismpi);
118: if (ismpi) {
119: Vec_MPI *v = (Vec_MPI *)g->data;
120: if (l == v->localrep) *flg = PETSC_TRUE;
121: } else if (isseq) {
122: if (l == g) *flg = PETSC_TRUE;
123: } else SETERRQ(PetscObjectComm((PetscObject)g), PETSC_ERR_ARG_WRONG, "Global vector is not ghosted");
124: return 0;
125: }
127: /*@
128: VecGhostRestoreLocalForm - Restores the local ghosted representation of
129: a parallel vector obtained with VecGhostGetLocalForm().
131: Logically Collective
133: Input Parameters:
134: + g - the global vector
135: - l - the local (ghosted) representation
137: Notes:
138: This routine does not actually update the ghost values, but rather it
139: returns a sequential vector that includes the locations for the ghost values
140: and their current values.
142: Level: advanced
144: .seealso: `VecCreateGhost()`, `VecGhostGetLocalForm()`, `VecCreateGhostWithArray()`
145: @*/
146: PetscErrorCode VecGhostRestoreLocalForm(Vec g, Vec *l)
147: {
148: if (*l) {
149: VecGhostStateSync_Private(g, *l);
150: PetscObjectDereference((PetscObject)*l);
151: }
152: return 0;
153: }
155: /*@
156: VecGhostUpdateBegin - Begins the vector scatter to update the vector from
157: local representation to global or global representation to local.
159: Neighbor-wise Collective
161: Input Parameters:
162: + g - the vector (obtained with `VecCreateGhost()` or `VecDuplicate()`)
163: . insertmode - one of ADD_VALUES, MAX_VALUES, MIN_VALUES or INSERT_VALUES
164: - scattermode - one of SCATTER_FORWARD or SCATTER_REVERSE
166: Notes:
167: Use the following to update the ghost regions with correct values from the owning process
168: .vb
169: VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
170: VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
171: .ve
173: Use the following to accumulate the ghost region values onto the owning processors
174: .vb
175: VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
176: VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
177: .ve
179: To accumulate the ghost region values onto the owning processors and then update
180: the ghost regions correctly, call the latter followed by the former, i.e.,
181: .vb
182: VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
183: VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
184: VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
185: VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
186: .ve
188: Level: advanced
190: .seealso: `VecCreateGhost()`, `VecGhostUpdateEnd()`, `VecGhostGetLocalForm()`,
191: `VecGhostRestoreLocalForm()`, `VecCreateGhostWithArray()`
193: @*/
194: PetscErrorCode VecGhostUpdateBegin(Vec g, InsertMode insertmode, ScatterMode scattermode)
195: {
196: Vec_MPI *v;
197: PetscBool ismpi, isseq;
200: PetscObjectTypeCompare((PetscObject)g, VECMPI, &ismpi);
201: PetscObjectTypeCompare((PetscObject)g, VECSEQ, &isseq);
202: if (ismpi) {
203: v = (Vec_MPI *)g->data;
205: if (!v->localupdate) return 0;
206: if (scattermode == SCATTER_REVERSE) {
207: VecScatterBegin(v->localupdate, v->localrep, g, insertmode, scattermode);
208: } else {
209: VecScatterBegin(v->localupdate, g, v->localrep, insertmode, scattermode);
210: }
211: } else if (isseq) {
212: /* Do nothing */
213: } else SETERRQ(PetscObjectComm((PetscObject)g), PETSC_ERR_ARG_WRONG, "Vector is not ghosted");
214: return 0;
215: }
217: /*@
218: VecGhostUpdateEnd - End the vector scatter to update the vector from
219: local representation to global or global representation to local.
221: Neighbor-wise Collective
223: Input Parameters:
224: + g - the vector (obtained with `VecCreateGhost()` or `VecDuplicate()`)
225: . insertmode - one of ADD_VALUES, MAX_VALUES, MIN_VALUES or INSERT_VALUES
226: - scattermode - one of SCATTER_FORWARD or SCATTER_REVERSE
228: Notes:
230: Use the following to update the ghost regions with correct values from the owning process
231: .vb
232: VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
233: VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
234: .ve
236: Use the following to accumulate the ghost region values onto the owning processors
237: .vb
238: VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
239: VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
240: .ve
242: To accumulate the ghost region values onto the owning processors and then update
243: the ghost regions correctly, call the later followed by the former, i.e.,
244: .vb
245: VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
246: VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
247: VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
248: VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
249: .ve
251: Level: advanced
253: .seealso: `VecCreateGhost()`, `VecGhostUpdateBegin()`, `VecGhostGetLocalForm()`,
254: `VecGhostRestoreLocalForm()`, `VecCreateGhostWithArray()`
256: @*/
257: PetscErrorCode VecGhostUpdateEnd(Vec g, InsertMode insertmode, ScatterMode scattermode)
258: {
259: Vec_MPI *v;
260: PetscBool ismpi;
263: PetscObjectTypeCompare((PetscObject)g, VECMPI, &ismpi);
264: if (ismpi) {
265: v = (Vec_MPI *)g->data;
267: if (!v->localupdate) return 0;
268: if (scattermode == SCATTER_REVERSE) {
269: VecScatterEnd(v->localupdate, v->localrep, g, insertmode, scattermode);
270: } else {
271: VecScatterEnd(v->localupdate, g, v->localrep, insertmode, scattermode);
272: }
273: }
274: return 0;
275: }