1 /*
2 Provides the interface functions for vector operations that do NOT have PetscScalar/PetscReal in the signature
3 These are the vector functions the user calls.
4 */
5 #include <petsc/private/vecimpl.h> /*I "petscvec.h" I*/
6 #include <petsc/private/deviceimpl.h>
7
8 /* Logging support */
9 PetscClassId VEC_CLASSID;
10 PetscLogEvent VEC_View, VEC_Max, VEC_Min, VEC_Dot, VEC_MDot, VEC_TDot;
11 PetscLogEvent VEC_Norm, VEC_Normalize, VEC_Scale, VEC_Shift, VEC_Copy, VEC_Set, VEC_AXPY, VEC_AYPX, VEC_WAXPY;
12 PetscLogEvent VEC_MTDot, VEC_MAXPY, VEC_Swap, VEC_AssemblyBegin, VEC_ScatterBegin, VEC_ScatterEnd;
13 PetscLogEvent VEC_AssemblyEnd, VEC_PointwiseMult, VEC_PointwiseDivide, VEC_Reciprocal, VEC_SetValues, VEC_Load, VEC_SetPreallocateCOO, VEC_SetValuesCOO;
14 PetscLogEvent VEC_SetRandom, VEC_ReduceArithmetic, VEC_ReduceCommunication, VEC_ReduceBegin, VEC_ReduceEnd, VEC_Ops;
15 PetscLogEvent VEC_DotNorm2, VEC_AXPBYPCZ;
16 PetscLogEvent VEC_ViennaCLCopyFromGPU, VEC_ViennaCLCopyToGPU;
17 PetscLogEvent VEC_CUDACopyFromGPU, VEC_CUDACopyToGPU;
18 PetscLogEvent VEC_HIPCopyFromGPU, VEC_HIPCopyToGPU;
19
20 /*@
21 VecStashGetInfo - Gets how many values are currently in the vector stash, i.e. need
22 to be communicated to other processors during the `VecAssemblyBegin()`/`VecAssemblyEnd()` process
23
24 Not Collective
25
26 Input Parameter:
27 . vec - the vector
28
29 Output Parameters:
30 + nstash - the size of the stash
31 . reallocs - the number of additional mallocs incurred in building the stash
32 . bnstash - the size of the block stash
33 - breallocs - the number of additional mallocs incurred in building the block stash (from `VecSetValuesBlocked()`)
34
35 Level: advanced
36
37 .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecStashSetInitialSize()`, `VecStashView()`
38 @*/
VecStashGetInfo(Vec vec,PetscInt * nstash,PetscInt * reallocs,PetscInt * bnstash,PetscInt * breallocs)39 PetscErrorCode VecStashGetInfo(Vec vec, PetscInt *nstash, PetscInt *reallocs, PetscInt *bnstash, PetscInt *breallocs)
40 {
41 PetscFunctionBegin;
42 PetscCall(VecStashGetInfo_Private(&vec->stash, nstash, reallocs));
43 PetscCall(VecStashGetInfo_Private(&vec->bstash, bnstash, breallocs));
44 PetscFunctionReturn(PETSC_SUCCESS);
45 }
46
47 /*@
48 VecSetLocalToGlobalMapping - Sets a local numbering to global numbering used
49 by the routine `VecSetValuesLocal()` to allow users to insert vector entries
50 using a local (per-processor) numbering.
51
52 Logically Collective
53
54 Input Parameters:
55 + x - vector
56 - mapping - mapping created with `ISLocalToGlobalMappingCreate()` or `ISLocalToGlobalMappingCreateIS()`
57
58 Level: intermediate
59
60 Notes:
61 All vectors obtained with `VecDuplicate()` from this vector inherit the same mapping.
62
63 Vectors obtained with `DMCreateGlobaVector()` will often have this attribute attached to the vector so this call is not needed
64
65 .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesLocal()`,
66 `VecGetLocalToGlobalMapping()`, `VecSetValuesBlockedLocal()`
67 @*/
VecSetLocalToGlobalMapping(Vec x,ISLocalToGlobalMapping mapping)68 PetscErrorCode VecSetLocalToGlobalMapping(Vec x, ISLocalToGlobalMapping mapping)
69 {
70 PetscFunctionBegin;
71 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
72 if (mapping) PetscValidHeaderSpecific(mapping, IS_LTOGM_CLASSID, 2);
73 if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x, setlocaltoglobalmapping, mapping);
74 else PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->map, mapping));
75 PetscFunctionReturn(PETSC_SUCCESS);
76 }
77
78 /*@
79 VecGetLocalToGlobalMapping - Gets the local-to-global numbering set by `VecSetLocalToGlobalMapping()`
80
81 Not Collective
82
83 Input Parameter:
84 . X - the vector
85
86 Output Parameter:
87 . mapping - the mapping
88
89 Level: advanced
90
91 .seealso: [](ch_vectors), `Vec`, `VecSetValuesLocal()`, `VecSetLocalToGlobalMapping()`
92 @*/
VecGetLocalToGlobalMapping(Vec X,ISLocalToGlobalMapping * mapping)93 PetscErrorCode VecGetLocalToGlobalMapping(Vec X, ISLocalToGlobalMapping *mapping)
94 {
95 PetscFunctionBegin;
96 PetscValidHeaderSpecific(X, VEC_CLASSID, 1);
97 PetscValidType(X, 1);
98 PetscAssertPointer(mapping, 2);
99 if (X->ops->getlocaltoglobalmapping) PetscUseTypeMethod(X, getlocaltoglobalmapping, mapping);
100 else *mapping = X->map->mapping;
101 PetscFunctionReturn(PETSC_SUCCESS);
102 }
103
104 /*@
105 VecAssemblyBegin - Begins assembling the vector; that is ensuring all the vector's entries are stored on the correct MPI process. This routine should
106 be called after completing all calls to `VecSetValues()`.
107
108 Collective
109
110 Input Parameter:
111 . vec - the vector
112
113 Level: beginner
114
115 .seealso: [](ch_vectors), `Vec`, `VecAssemblyEnd()`, `VecSetValues()`
116 @*/
VecAssemblyBegin(Vec vec)117 PetscErrorCode VecAssemblyBegin(Vec vec)
118 {
119 PetscFunctionBegin;
120 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
121 PetscValidType(vec, 1);
122 PetscCall(VecStashViewFromOptions(vec, NULL, "-vec_view_stash"));
123 PetscCall(PetscLogEventBegin(VEC_AssemblyBegin, vec, 0, 0, 0));
124 PetscTryTypeMethod(vec, assemblybegin);
125 PetscCall(PetscLogEventEnd(VEC_AssemblyBegin, vec, 0, 0, 0));
126 PetscCall(PetscObjectStateIncrease((PetscObject)vec));
127 PetscFunctionReturn(PETSC_SUCCESS);
128 }
129
130 /*@
131 VecAssemblyEnd - Completes assembling the vector. This routine should be called after `VecAssemblyBegin()`.
132
133 Collective
134
135 Input Parameter:
136 . vec - the vector
137
138 Options Database Keys:
139 + -vec_view - Prints vector in `PETSC_VIEWER_DEFAULT` format
140 . -vec_view ::ascii_matlab - Prints vector in `PETSC_VIEWER_ASCII_MATLAB` format to stdout
141 . -vec_view matlab:filename - Prints vector in MATLAB .mat file to filename (requires PETSc configured with --with-matlab)
142 . -vec_view draw - Activates vector viewing using drawing tools
143 . -display <name> - Sets display name (default is host)
144 . -draw_pause <sec> - Sets number of seconds to pause after display
145 - -vec_view socket - Activates vector viewing using a socket
146
147 Level: beginner
148
149 .seealso: [](ch_vectors), `Vec`, `VecAssemblyBegin()`, `VecSetValues()`
150 @*/
VecAssemblyEnd(Vec vec)151 PetscErrorCode VecAssemblyEnd(Vec vec)
152 {
153 PetscFunctionBegin;
154 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
155 PetscCall(PetscLogEventBegin(VEC_AssemblyEnd, vec, 0, 0, 0));
156 PetscValidType(vec, 1);
157 PetscTryTypeMethod(vec, assemblyend);
158 PetscCall(PetscLogEventEnd(VEC_AssemblyEnd, vec, 0, 0, 0));
159 PetscCall(VecViewFromOptions(vec, NULL, "-vec_view"));
160 PetscFunctionReturn(PETSC_SUCCESS);
161 }
162
163 /*@
164 VecSetPreallocationCOO - set preallocation for a vector using a coordinate format of the entries with global indices
165
166 Collective
167
168 Input Parameters:
169 + x - vector being preallocated
170 . ncoo - number of entries
171 - coo_i - entry indices
172
173 Level: beginner
174
175 Notes:
176 This and `VecSetValuesCOO()` provide an alternative API to using `VecSetValues()` to provide vector values.
177
178 This API is particularly efficient for use on GPUs.
179
180 Entries can be repeated, see `VecSetValuesCOO()`. Negative indices are not allowed unless vector option `VEC_IGNORE_NEGATIVE_INDICES` is set,
181 in which case they, along with the corresponding entries in `VecSetValuesCOO()`, are ignored. If vector option `VEC_NO_OFF_PROC_ENTRIES` is set,
182 remote entries are ignored, otherwise, they will be properly added or inserted to the vector.
183
184 The array coo_i[] may be freed immediately after calling this function.
185
186 .seealso: [](ch_vectors), `Vec`, `VecSetValuesCOO()`, `VecSetPreallocationCOOLocal()`
187 @*/
VecSetPreallocationCOO(Vec x,PetscCount ncoo,const PetscInt coo_i[])188 PetscErrorCode VecSetPreallocationCOO(Vec x, PetscCount ncoo, const PetscInt coo_i[])
189 {
190 PetscFunctionBegin;
191 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
192 PetscValidType(x, 1);
193 if (ncoo) PetscAssertPointer(coo_i, 3);
194 PetscCall(PetscLogEventBegin(VEC_SetPreallocateCOO, x, 0, 0, 0));
195 PetscCall(PetscLayoutSetUp(x->map));
196 if (x->ops->setpreallocationcoo) {
197 PetscUseTypeMethod(x, setpreallocationcoo, ncoo, coo_i);
198 } else {
199 PetscInt ncoo_i;
200 IS is_coo_i;
201
202 PetscCall(PetscIntCast(ncoo, &ncoo_i));
203 PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo_i, coo_i, PETSC_COPY_VALUES, &is_coo_i));
204 PetscCall(PetscObjectCompose((PetscObject)x, "__PETSc_coo_i", (PetscObject)is_coo_i));
205 PetscCall(ISDestroy(&is_coo_i));
206 }
207 PetscCall(PetscLogEventEnd(VEC_SetPreallocateCOO, x, 0, 0, 0));
208 PetscFunctionReturn(PETSC_SUCCESS);
209 }
210
211 /*@
212 VecSetPreallocationCOOLocal - set preallocation for vectors using a coordinate format of the entries with local indices
213
214 Collective
215
216 Input Parameters:
217 + x - vector being preallocated
218 . ncoo - number of entries
219 - coo_i - row indices (local numbering; may be modified)
220
221 Level: beginner
222
223 Notes:
224 This and `VecSetValuesCOO()` provide an alternative API to using `VecSetValuesLocal()` to provide vector values.
225
226 This API is particularly efficient for use on GPUs.
227
228 The local indices are translated using the local to global mapping, thus `VecSetLocalToGlobalMapping()` must have been
229 called prior to this function.
230
231 The indices coo_i may be modified within this function. They might be translated to corresponding global
232 indices, but the caller should not rely on them having any specific value after this function returns. The arrays
233 can be freed or reused immediately after this function returns.
234
235 Entries can be repeated. Negative indices and remote indices might be allowed. see `VecSetPreallocationCOO()`.
236
237 .seealso: [](ch_vectors), `Vec`, `VecSetPreallocationCOO()`, `VecSetValuesCOO()`
238 @*/
VecSetPreallocationCOOLocal(Vec x,PetscCount ncoo,PetscInt coo_i[])239 PetscErrorCode VecSetPreallocationCOOLocal(Vec x, PetscCount ncoo, PetscInt coo_i[])
240 {
241 PetscInt ncoo_i;
242 ISLocalToGlobalMapping ltog;
243
244 PetscFunctionBegin;
245 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
246 PetscValidType(x, 1);
247 if (ncoo) PetscAssertPointer(coo_i, 3);
248 PetscCall(PetscIntCast(ncoo, &ncoo_i));
249 PetscCall(PetscLayoutSetUp(x->map));
250 PetscCall(VecGetLocalToGlobalMapping(x, <og));
251 if (ltog) PetscCall(ISLocalToGlobalMappingApply(ltog, ncoo_i, coo_i, coo_i));
252 PetscCall(VecSetPreallocationCOO(x, ncoo, coo_i));
253 PetscFunctionReturn(PETSC_SUCCESS);
254 }
255
256 /*@
257 VecSetValuesCOO - set values at once in a vector preallocated using `VecSetPreallocationCOO()`
258
259 Collective
260
261 Input Parameters:
262 + x - vector being set
263 . coo_v - the value array
264 - imode - the insert mode
265
266 Level: beginner
267
268 Note:
269 This and `VecSetPreallocationCOO() or ``VecSetPreallocationCOOLocal()` provide an alternative API to using `VecSetValues()` to provide vector values.
270
271 This API is particularly efficient for use on GPUs.
272
273 The values must follow the order of the indices prescribed with `VecSetPreallocationCOO()` or `VecSetPreallocationCOOLocal()`.
274 When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of `imode`.
275 The imode flag indicates if `coo_v` must be added to the current values of the vector (`ADD_VALUES`) or overwritten (`INSERT_VALUES`).
276 `VecAssemblyBegin()` and `VecAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process.
277
278 .seealso: [](ch_vectors), `Vec`, `VecSetPreallocationCOO()`, `VecSetPreallocationCOOLocal()`, `VecSetValues()`
279 @*/
VecSetValuesCOO(Vec x,const PetscScalar coo_v[],InsertMode imode)280 PetscErrorCode VecSetValuesCOO(Vec x, const PetscScalar coo_v[], InsertMode imode)
281 {
282 PetscFunctionBegin;
283 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
284 PetscValidType(x, 1);
285 PetscValidLogicalCollectiveEnum(x, imode, 3);
286 PetscCall(PetscLogEventBegin(VEC_SetValuesCOO, x, 0, 0, 0));
287 if (x->ops->setvaluescoo) {
288 PetscUseTypeMethod(x, setvaluescoo, coo_v, imode);
289 PetscCall(PetscObjectStateIncrease((PetscObject)x));
290 } else {
291 IS is_coo_i;
292 const PetscInt *coo_i;
293 PetscInt ncoo;
294 PetscMemType mtype;
295
296 PetscCall(PetscGetMemType(coo_v, &mtype));
297 PetscCheck(mtype == PETSC_MEMTYPE_HOST, PetscObjectComm((PetscObject)x), PETSC_ERR_ARG_WRONG, "The basic VecSetValuesCOO() only supports v[] on host");
298 PetscCall(PetscObjectQuery((PetscObject)x, "__PETSc_coo_i", (PetscObject *)&is_coo_i));
299 PetscCheck(is_coo_i, PetscObjectComm((PetscObject)x), PETSC_ERR_COR, "Missing coo_i IS");
300 PetscCall(ISGetLocalSize(is_coo_i, &ncoo));
301 PetscCall(ISGetIndices(is_coo_i, &coo_i));
302 if (imode != ADD_VALUES) PetscCall(VecZeroEntries(x));
303 PetscCall(VecSetValues(x, ncoo, coo_i, coo_v, ADD_VALUES));
304 PetscCall(ISRestoreIndices(is_coo_i, &coo_i));
305 PetscCall(VecAssemblyBegin(x));
306 PetscCall(VecAssemblyEnd(x));
307 }
308 PetscCall(PetscLogEventEnd(VEC_SetValuesCOO, x, 0, 0, 0));
309 PetscFunctionReturn(PETSC_SUCCESS);
310 }
311
VecPointwiseApply_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx,PetscLogEvent event,const char async_name[],PetscErrorCode (* const pointwise_op)(Vec,Vec,Vec))312 static PetscErrorCode VecPointwiseApply_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx, PetscLogEvent event, const char async_name[], PetscErrorCode (*const pointwise_op)(Vec, Vec, Vec))
313 {
314 PetscErrorCode (*async_fn)(Vec, Vec, Vec, PetscDeviceContext) = NULL;
315
316 PetscFunctionBegin;
317 PetscValidHeaderSpecific(w, VEC_CLASSID, 1);
318 PetscValidHeaderSpecific(x, VEC_CLASSID, 2);
319 PetscValidHeaderSpecific(y, VEC_CLASSID, 3);
320 PetscValidType(w, 1);
321 PetscValidType(x, 2);
322 PetscValidType(y, 3);
323 PetscCheckSameTypeAndComm(x, 2, y, 3);
324 PetscCheckSameTypeAndComm(y, 3, w, 1);
325 VecCheckSameSize(w, 1, x, 2);
326 VecCheckSameSize(w, 1, y, 3);
327 VecCheckAssembled(x);
328 VecCheckAssembled(y);
329 PetscCall(VecSetErrorIfLocked(w, 1));
330 PetscValidFunction(pointwise_op, 5);
331
332 if (dctx) PetscCall(PetscObjectQueryFunction((PetscObject)w, async_name, &async_fn));
333 if (event) PetscCall(PetscLogEventBegin(event, x, y, w, 0));
334 if (async_fn) {
335 PetscCall((*async_fn)(w, x, y, dctx));
336 } else {
337 PetscCall((*pointwise_op)(w, x, y));
338 }
339 if (event) PetscCall(PetscLogEventEnd(event, x, y, w, 0));
340 PetscCall(PetscObjectStateIncrease((PetscObject)w));
341 PetscFunctionReturn(PETSC_SUCCESS);
342 }
343
VecPointwiseMaxAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)344 PetscErrorCode VecPointwiseMaxAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
345 {
346 PetscFunctionBegin;
347 // REVIEW ME: no log event?
348 PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMax), w->ops->pointwisemax));
349 PetscFunctionReturn(PETSC_SUCCESS);
350 }
351
352 /*@
353 VecPointwiseMax - Computes the component-wise maximum `w[i] = max(x[i], y[i])`.
354
355 Logically Collective
356
357 Input Parameters:
358 + x - the first input vector
359 - y - the second input vector
360
361 Output Parameter:
362 . w - the result
363
364 Level: advanced
365
366 Notes:
367 Any subset of the `x`, `y`, and `w` may be the same vector.
368
369 For complex numbers compares only the real part
370
371 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
372 @*/
VecPointwiseMax(Vec w,Vec x,Vec y)373 PetscErrorCode VecPointwiseMax(Vec w, Vec x, Vec y)
374 {
375 PetscFunctionBegin;
376 PetscCall(VecPointwiseMaxAsync_Private(w, x, y, NULL));
377 PetscFunctionReturn(PETSC_SUCCESS);
378 }
379
VecPointwiseMinAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)380 PetscErrorCode VecPointwiseMinAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
381 {
382 PetscFunctionBegin;
383 // REVIEW ME: no log event?
384 PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMin), w->ops->pointwisemin));
385 PetscFunctionReturn(PETSC_SUCCESS);
386 }
387
388 /*@
389 VecPointwiseMin - Computes the component-wise minimum `w[i] = min(x[i], y[i])`.
390
391 Logically Collective
392
393 Input Parameters:
394 + x - the first input vector
395 - y - the second input vector
396
397 Output Parameter:
398 . w - the result
399
400 Level: advanced
401
402 Notes:
403 Any subset of the `x`, `y`, and `w` may be the same vector.
404
405 For complex numbers compares only the real part
406
407 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
408 @*/
VecPointwiseMin(Vec w,Vec x,Vec y)409 PetscErrorCode VecPointwiseMin(Vec w, Vec x, Vec y)
410 {
411 PetscFunctionBegin;
412 PetscCall(VecPointwiseMinAsync_Private(w, x, y, NULL));
413 PetscFunctionReturn(PETSC_SUCCESS);
414 }
415
VecPointwiseMaxAbsAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)416 PetscErrorCode VecPointwiseMaxAbsAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
417 {
418 PetscFunctionBegin;
419 // REVIEW ME: no log event?
420 PetscCall(VecPointwiseApply_Private(w, x, y, dctx, 0, VecAsyncFnName(PointwiseMaxAbs), w->ops->pointwisemaxabs));
421 PetscFunctionReturn(PETSC_SUCCESS);
422 }
423
424 /*@
425 VecPointwiseMaxAbs - Computes the component-wise maximum of the absolute values `w[i] = max(abs(x[i]), abs(y[i]))`.
426
427 Logically Collective
428
429 Input Parameters:
430 + x - the first input vector
431 - y - the second input vector
432
433 Output Parameter:
434 . w - the result
435
436 Level: advanced
437
438 Notes:
439 Any subset of the `x`, `y`, and `w` may be the same vector.
440
441 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMax()`, `VecMaxPointwiseDivide()`
442 @*/
VecPointwiseMaxAbs(Vec w,Vec x,Vec y)443 PetscErrorCode VecPointwiseMaxAbs(Vec w, Vec x, Vec y)
444 {
445 PetscFunctionBegin;
446 PetscCall(VecPointwiseMaxAbsAsync_Private(w, x, y, NULL));
447 PetscFunctionReturn(PETSC_SUCCESS);
448 }
449
VecPointwiseDivideAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)450 PetscErrorCode VecPointwiseDivideAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
451 {
452 PetscFunctionBegin;
453 PetscCall(VecPointwiseApply_Private(w, x, y, dctx, VEC_PointwiseDivide, VecAsyncFnName(PointwiseDivide), w->ops->pointwisedivide));
454 PetscFunctionReturn(PETSC_SUCCESS);
455 }
456
457 /*@
458 VecPointwiseDivide - Computes the component-wise division `w[i] = x[i] / y[i]`.
459
460 Logically Collective
461
462 Input Parameters:
463 + x - the numerator vector
464 - y - the denominator vector
465
466 Output Parameter:
467 . w - the result
468
469 Level: advanced
470
471 Note:
472 Any subset of the `x`, `y`, and `w` may be the same vector.
473
474 .seealso: [](ch_vectors), `Vec`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
475 @*/
VecPointwiseDivide(Vec w,Vec x,Vec y)476 PetscErrorCode VecPointwiseDivide(Vec w, Vec x, Vec y)
477 {
478 PetscFunctionBegin;
479 PetscCall(VecPointwiseDivideAsync_Private(w, x, y, NULL));
480 PetscFunctionReturn(PETSC_SUCCESS);
481 }
482
VecPointwiseMultAsync_Private(Vec w,Vec x,Vec y,PetscDeviceContext dctx)483 PetscErrorCode VecPointwiseMultAsync_Private(Vec w, Vec x, Vec y, PetscDeviceContext dctx)
484 {
485 PetscFunctionBegin;
486 PetscValidHeaderSpecific(w, VEC_CLASSID, 1);
487 PetscCall(VecPointwiseApply_Private(w, x, y, dctx, VEC_PointwiseMult, VecAsyncFnName(PointwiseMult), w->ops->pointwisemult));
488 PetscFunctionReturn(PETSC_SUCCESS);
489 }
490
491 /*@
492 VecPointwiseMult - Computes the component-wise multiplication `w[i] = x[i] * y[i]`.
493
494 Logically Collective
495
496 Input Parameters:
497 + x - the first vector
498 - y - the second vector
499
500 Output Parameter:
501 . w - the result
502
503 Level: advanced
504
505 Note:
506 Any subset of the `x`, `y`, and `w` may be the same vector.
507
508 .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
509 @*/
VecPointwiseMult(Vec w,Vec x,Vec y)510 PetscErrorCode VecPointwiseMult(Vec w, Vec x, Vec y)
511 {
512 PetscFunctionBegin;
513 PetscCall(VecPointwiseMultAsync_Private(w, x, y, NULL));
514 PetscFunctionReturn(PETSC_SUCCESS);
515 }
516
517 /*@
518 VecDuplicate - Creates a new vector of the same type as an existing vector.
519
520 Collective
521
522 Input Parameter:
523 . v - a vector to mimic
524
525 Output Parameter:
526 . newv - location to put new vector
527
528 Level: beginner
529
530 Notes:
531 `VecDuplicate()` DOES NOT COPY the vector entries, but rather allocates storage
532 for the new vector. Use `VecCopy()` to copy a vector.
533
534 Use `VecDestroy()` to free the space. Use `VecDuplicateVecs()` to get several
535 vectors.
536
537 .seealso: [](ch_vectors), `Vec`, `VecDestroy()`, `VecDuplicateVecs()`, `VecCreate()`, `VecCopy()`
538 @*/
VecDuplicate(Vec v,Vec * newv)539 PetscErrorCode VecDuplicate(Vec v, Vec *newv)
540 {
541 PetscFunctionBegin;
542 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
543 PetscAssertPointer(newv, 2);
544 PetscValidType(v, 1);
545 PetscUseTypeMethod(v, duplicate, newv);
546 #if PetscDefined(HAVE_DEVICE)
547 if (v->boundtocpu && v->bindingpropagates) {
548 PetscCall(VecSetBindingPropagates(*newv, PETSC_TRUE));
549 PetscCall(VecBindToCPU(*newv, PETSC_TRUE));
550 }
551 #endif
552 PetscCall(PetscObjectStateIncrease((PetscObject)*newv));
553 PetscFunctionReturn(PETSC_SUCCESS);
554 }
555
556 /*@
557 VecDestroy - Destroys a vector.
558
559 Collective
560
561 Input Parameter:
562 . v - the vector
563
564 Level: beginner
565
566 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDuplicate()`, `VecDestroyVecs()`
567 @*/
VecDestroy(Vec * v)568 PetscErrorCode VecDestroy(Vec *v)
569 {
570 PetscFunctionBegin;
571 PetscAssertPointer(v, 1);
572 if (!*v) PetscFunctionReturn(PETSC_SUCCESS);
573 PetscValidHeaderSpecific(*v, VEC_CLASSID, 1);
574 if (--((PetscObject)*v)->refct > 0) {
575 *v = NULL;
576 PetscFunctionReturn(PETSC_SUCCESS);
577 }
578
579 PetscCall(PetscObjectSAWsViewOff((PetscObject)*v));
580 /* destroy the internal part */
581 PetscTryTypeMethod(*v, destroy);
582 PetscCall(PetscFree((*v)->defaultrandtype));
583 /* destroy the external/common part */
584 PetscCall(PetscLayoutDestroy(&(*v)->map));
585 PetscCall(PetscHeaderDestroy(v));
586 PetscFunctionReturn(PETSC_SUCCESS);
587 }
588
589 /*@C
590 VecDuplicateVecs - Creates several vectors of the same type as an existing vector.
591
592 Collective
593
594 Input Parameters:
595 + m - the number of vectors to obtain
596 - v - a vector to mimic
597
598 Output Parameter:
599 . V - location to put pointer to array of vectors
600
601 Level: intermediate
602
603 Notes:
604 Use `VecDestroyVecs()` to free the space. Use `VecDuplicate()` to form a single
605 vector.
606
607 Some implementations ensure that the arrays accessed by each vector are contiguous in memory. Certain `VecMDot()` and `VecMAXPY()`
608 implementations utilize this property to use BLAS 2 operations for higher efficiency. This is especially useful in `KSPGMRES`, see
609 `KSPGMRESSetPreAllocateVectors()`.
610
611 Fortran Note:
612 .vb
613 Vec, pointer :: V(:)
614 .ve
615
616 .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDestroyVecs()`, `VecDuplicate()`, `VecCreate()`, `VecMDot()`, `VecMAXPY()`, `KSPGMRES`,
617 `KSPGMRESSetPreAllocateVectors()`
618 @*/
VecDuplicateVecs(Vec v,PetscInt m,Vec * V[])619 PetscErrorCode VecDuplicateVecs(Vec v, PetscInt m, Vec *V[])
620 {
621 PetscFunctionBegin;
622 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
623 PetscAssertPointer(V, 3);
624 PetscValidType(v, 1);
625 PetscUseTypeMethod(v, duplicatevecs, m, V);
626 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
627 if (v->boundtocpu && v->bindingpropagates) {
628 PetscInt i;
629
630 for (i = 0; i < m; i++) {
631 /* Since ops->duplicatevecs might itself propagate the value of boundtocpu,
632 * avoid unnecessary overhead by only calling VecBindToCPU() if the vector isn't already bound. */
633 if (!(*V)[i]->boundtocpu) {
634 PetscCall(VecSetBindingPropagates((*V)[i], PETSC_TRUE));
635 PetscCall(VecBindToCPU((*V)[i], PETSC_TRUE));
636 }
637 }
638 }
639 #endif
640 PetscFunctionReturn(PETSC_SUCCESS);
641 }
642
643 /*@C
644 VecDestroyVecs - Frees a block of vectors obtained with `VecDuplicateVecs()`.
645
646 Collective
647
648 Input Parameters:
649 + m - the number of vectors previously obtained, if zero no vectors are destroyed
650 - vv - pointer to pointer to array of vector pointers, if `NULL` no vectors are destroyed
651
652 Level: intermediate
653
654 .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDuplicateVecs()`, `VecDestroyVecsf90()`
655 @*/
VecDestroyVecs(PetscInt m,Vec * vv[])656 PetscErrorCode VecDestroyVecs(PetscInt m, Vec *vv[])
657 {
658 PetscFunctionBegin;
659 PetscAssertPointer(vv, 2);
660 PetscCheck(m >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of vectors %" PetscInt_FMT, m);
661 if (!m || !*vv) {
662 *vv = NULL;
663 PetscFunctionReturn(PETSC_SUCCESS);
664 }
665 PetscValidHeaderSpecific(**vv, VEC_CLASSID, 2);
666 PetscValidType(**vv, 2);
667 PetscCall((*(**vv)->ops->destroyvecs)(m, *vv));
668 *vv = NULL;
669 PetscFunctionReturn(PETSC_SUCCESS);
670 }
671
672 /*@
673 VecViewFromOptions - View a vector based on values in the options database
674
675 Collective
676
677 Input Parameters:
678 + A - the vector
679 . obj - optional object that provides the options prefix for this viewing, use 'NULL' to use the prefix of `A`
680 - name - command line option
681
682 Level: intermediate
683
684 Note:
685 See `PetscObjectViewFromOptions()` to see the `PetscViewer` and PetscViewerFormat` available
686
687 .seealso: [](ch_vectors), `Vec`, `VecView`, `PetscObjectViewFromOptions()`, `VecCreate()`
688 @*/
VecViewFromOptions(Vec A,PeOp PetscObject obj,const char name[])689 PetscErrorCode VecViewFromOptions(Vec A, PeOp PetscObject obj, const char name[])
690 {
691 PetscFunctionBegin;
692 PetscValidHeaderSpecific(A, VEC_CLASSID, 1);
693 PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
694 PetscFunctionReturn(PETSC_SUCCESS);
695 }
696
697 /*@
698 VecView - Views a vector object.
699
700 Collective
701
702 Input Parameters:
703 + vec - the vector
704 - viewer - an optional `PetscViewer` visualization context
705
706 Level: beginner
707
708 Notes:
709 The available visualization contexts include
710 + `PETSC_VIEWER_STDOUT_SELF` - for sequential vectors
711 . `PETSC_VIEWER_STDOUT_WORLD` - for parallel vectors created on `PETSC_COMM_WORLD`
712 - `PETSC_VIEWER_STDOUT`_(comm) - for parallel vectors created on MPI communicator comm
713
714 You can change the format the vector is printed using the
715 option `PetscViewerPushFormat()`.
716
717 The user can open alternative viewers with
718 + `PetscViewerASCIIOpen()` - Outputs vector to a specified file
719 . `PetscViewerBinaryOpen()` - Outputs vector in binary to a
720 specified file; corresponding input uses `VecLoad()`
721 . `PetscViewerDrawOpen()` - Outputs vector to an X window display
722 . `PetscViewerSocketOpen()` - Outputs vector to Socket viewer
723 - `PetscViewerHDF5Open()` - Outputs vector to HDF5 file viewer
724
725 The user can call `PetscViewerPushFormat()` to specify the output
726 format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`,
727 `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include
728 + `PETSC_VIEWER_DEFAULT` - default, prints vector contents
729 . `PETSC_VIEWER_ASCII_MATLAB` - prints vector contents in MATLAB format
730 . `PETSC_VIEWER_ASCII_INDEX` - prints vector contents, including indices of vector elements
731 - `PETSC_VIEWER_ASCII_COMMON` - prints vector contents, using a
732 format common among all vector types
733
734 You can pass any number of vector objects, or other PETSc objects to the same viewer.
735
736 In the debugger you can do call `VecView`(v,0) to display the vector. (The same holds for any PETSc object viewer).
737
738 Notes for binary viewer:
739 If you pass multiple vectors to a binary viewer you can read them back in the same order
740 with `VecLoad()`.
741
742 If the blocksize of the vector is greater than one then you must provide a unique prefix to
743 the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
744 vector to be stored and then set that same unique prefix on the vector that you pass to `VecLoad()`. The blocksize
745 information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
746 filename. If you copy the binary file, make sure you copy the associated .info file with it.
747
748 See the manual page for `VecLoad()` on the exact format the binary viewer stores
749 the values in the file.
750
751 Notes for HDF5 Viewer:
752 The name of the `Vec` (given with `PetscObjectSetName()` is the name that is used
753 for the object in the HDF5 file. If you wish to store the same Vec into multiple
754 datasets in the same file (typically with different values), you must change its
755 name each time before calling the `VecView()`. To load the same vector,
756 the name of the Vec object passed to `VecLoad()` must be the same.
757
758 If the block size of the vector is greater than 1 then it is used as the first dimension in the HDF5 array.
759 If the function `PetscViewerHDF5SetBaseDimension2()`is called then even if the block size is one it will
760 be used as the first dimension in the HDF5 array (that is the HDF5 array will always be two dimensional)
761 See also `PetscViewerHDF5SetTimestep()` which adds an additional complication to reading and writing `Vec`
762 with the HDF5 viewer.
763
764 .seealso: [](ch_vectors), `Vec`, `VecViewFromOptions()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`,
765 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
766 `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
767 @*/
VecView(Vec vec,PetscViewer viewer)768 PetscErrorCode VecView(Vec vec, PetscViewer viewer)
769 {
770 PetscBool isascii;
771 PetscViewerFormat format;
772 PetscMPIInt size;
773
774 PetscFunctionBegin;
775 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
776 PetscValidType(vec, 1);
777 VecCheckAssembled(vec);
778 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
779 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
780 PetscCall(PetscViewerGetFormat(viewer, &format));
781 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
782 if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS);
783
784 PetscCheck(!vec->stash.n && !vec->bstash.n, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call VecAssemblyBegin/End() before viewing this vector");
785
786 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
787 if (isascii) {
788 PetscInt rows, bs;
789
790 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)vec, viewer));
791 if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
792 PetscCall(PetscViewerASCIIPushTab(viewer));
793 PetscCall(VecGetSize(vec, &rows));
794 PetscCall(VecGetBlockSize(vec, &bs));
795 if (bs != 1) {
796 PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, bs));
797 } else {
798 PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT "\n", rows));
799 }
800 PetscCall(PetscViewerASCIIPopTab(viewer));
801 }
802 }
803 PetscCall(VecLockReadPush(vec));
804 PetscCall(PetscLogEventBegin(VEC_View, vec, viewer, 0, 0));
805 if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
806 PetscUseTypeMethod(vec, viewnative, viewer);
807 } else {
808 PetscUseTypeMethod(vec, view, viewer);
809 }
810 PetscCall(VecLockReadPop(vec));
811 PetscCall(PetscLogEventEnd(VEC_View, vec, viewer, 0, 0));
812 PetscFunctionReturn(PETSC_SUCCESS);
813 }
814
815 #if defined(PETSC_USE_DEBUG)
816 #include <../src/sys/totalview/tv_data_display.h>
TV_display_type(const struct _p_Vec * v)817 PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
818 {
819 const PetscScalar *values;
820 char type[32];
821
822 TV_add_row("Local rows", "int", &v->map->n);
823 TV_add_row("Global rows", "int", &v->map->N);
824 TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
825 PetscCall(VecGetArrayRead((Vec)v, &values));
826 PetscCall(PetscSNPrintf(type, 32, "double[%" PetscInt_FMT "]", v->map->n));
827 TV_add_row("values", type, values);
828 PetscCall(VecRestoreArrayRead((Vec)v, &values));
829 return TV_format_OK;
830 }
831 #endif
832
833 /*@C
834 VecViewNative - Views a vector object with the original type specific viewer
835
836 Collective
837
838 Input Parameters:
839 + vec - the vector
840 - viewer - an optional `PetscViewer` visualization context
841
842 Level: developer
843
844 Note:
845 This can be used with, for example, vectors obtained with `DMCreateGlobalVector()` for a `DMDA` to display the vector
846 in the PETSc storage format (each MPI process values follow the previous MPI processes) instead of the "natural" grid
847 ordering.
848
849 .seealso: [](ch_vectors), `Vec`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`, `VecView()`
850 `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
851 `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
852 @*/
VecViewNative(Vec vec,PetscViewer viewer)853 PetscErrorCode VecViewNative(Vec vec, PetscViewer viewer)
854 {
855 PetscFunctionBegin;
856 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
857 PetscValidType(vec, 1);
858 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
859 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
860 PetscUseTypeMethod(vec, viewnative, viewer);
861 PetscFunctionReturn(PETSC_SUCCESS);
862 }
863
864 /*@
865 VecGetSize - Returns the global number of elements of the vector.
866
867 Not Collective
868
869 Input Parameter:
870 . x - the vector
871
872 Output Parameter:
873 . size - the global length of the vector
874
875 Level: beginner
876
877 .seealso: [](ch_vectors), `Vec`, `VecGetLocalSize()`
878 @*/
VecGetSize(Vec x,PetscInt * size)879 PetscErrorCode VecGetSize(Vec x, PetscInt *size)
880 {
881 PetscFunctionBegin;
882 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
883 PetscAssertPointer(size, 2);
884 PetscValidType(x, 1);
885 PetscUseTypeMethod(x, getsize, size);
886 PetscFunctionReturn(PETSC_SUCCESS);
887 }
888
889 /*@
890 VecGetLocalSize - Returns the number of elements of the vector stored
891 in local memory (that is on this MPI process)
892
893 Not Collective
894
895 Input Parameter:
896 . x - the vector
897
898 Output Parameter:
899 . size - the length of the local piece of the vector
900
901 Level: beginner
902
903 .seealso: [](ch_vectors), `Vec`, `VecGetSize()`
904 @*/
VecGetLocalSize(Vec x,PetscInt * size)905 PetscErrorCode VecGetLocalSize(Vec x, PetscInt *size)
906 {
907 PetscFunctionBegin;
908 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
909 PetscAssertPointer(size, 2);
910 PetscValidType(x, 1);
911 PetscUseTypeMethod(x, getlocalsize, size);
912 PetscFunctionReturn(PETSC_SUCCESS);
913 }
914
915 /*@
916 VecGetOwnershipRange - Returns the range of indices owned by
917 this process. The vector is laid out with the
918 first `n1` elements on the first processor, next `n2` elements on the
919 second, etc. For certain parallel layouts this range may not be
920 well defined.
921
922 Not Collective
923
924 Input Parameter:
925 . x - the vector
926
927 Output Parameters:
928 + low - the first local element, pass in `NULL` if not interested
929 - high - one more than the last local element, pass in `NULL` if not interested
930
931 Level: beginner
932
933 Notes:
934 If the `Vec` was obtained from a `DM` with `DMCreateGlobalVector()`, then the range values are determined by the specific `DM`.
935
936 If the `Vec` was created directly the range values are determined by the local size passed to `VecSetSizes()` or `VecCreateMPI()`.
937 If `PETSC_DECIDE` was passed as the local size, then the vector uses default values for the range using `PetscSplitOwnership()`.
938
939 The high argument is one more than the last element stored locally.
940
941 For certain `DM`, such as `DMDA`, it is better to use `DM` specific routines, such as `DMDAGetGhostCorners()`, to determine
942 the local values in the vector.
943
944 .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRanges()`, `PetscSplitOwnership()`,
945 `VecSetSizes()`, `VecCreateMPI()`, `PetscLayout`, `DMDAGetGhostCorners()`, `DM`
946 @*/
VecGetOwnershipRange(Vec x,PetscInt * low,PetscInt * high)947 PetscErrorCode VecGetOwnershipRange(Vec x, PetscInt *low, PetscInt *high)
948 {
949 PetscFunctionBegin;
950 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
951 PetscValidType(x, 1);
952 if (low) PetscAssertPointer(low, 2);
953 if (high) PetscAssertPointer(high, 3);
954 if (low) *low = x->map->rstart;
955 if (high) *high = x->map->rend;
956 PetscFunctionReturn(PETSC_SUCCESS);
957 }
958
959 /*@C
960 VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
961 The vector is laid out with the
962 first `n1` elements on the first processor, next `n2` elements on the
963 second, etc. For certain parallel layouts this range may not be
964 well defined.
965
966 Not Collective
967
968 Input Parameter:
969 . x - the vector
970
971 Output Parameter:
972 . ranges - array of length `size` + 1 with the start and end+1 for each process
973
974 Level: beginner
975
976 Notes:
977 If the `Vec` was obtained from a `DM` with `DMCreateGlobalVector()`, then the range values are determined by the specific `DM`.
978
979 If the `Vec` was created directly the range values are determined by the local size passed to `VecSetSizes()` or `VecCreateMPI()`.
980 If `PETSC_DECIDE` was passed as the local size, then the vector uses default values for the range using `PetscSplitOwnership()`.
981
982 The high argument is one more than the last element stored locally.
983
984 For certain `DM`, such as `DMDA`, it is better to use `DM` specific routines, such as `DMDAGetGhostCorners()`, to determine
985 the local values in the vector.
986
987 The high argument is one more than the last element stored locally.
988
989 If `ranges` are used after all vectors that share the ranges has been destroyed, then the program will crash accessing `ranges`.
990
991 Fortran Note:
992 The argument `ranges` must be declared as
993 .vb
994 PetscInt, pointer :: ranges(:)
995 .ve
996 and you have to return it with a call to `VecRestoreOwnershipRanges()` when no longer needed
997
998 .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRange()`, `PetscSplitOwnership()`,
999 `VecSetSizes()`, `VecCreateMPI()`, `PetscLayout`, `DMDAGetGhostCorners()`, `DM`
1000 @*/
VecGetOwnershipRanges(Vec x,const PetscInt * ranges[])1001 PetscErrorCode VecGetOwnershipRanges(Vec x, const PetscInt *ranges[])
1002 {
1003 PetscFunctionBegin;
1004 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1005 PetscValidType(x, 1);
1006 PetscCall(PetscLayoutGetRanges(x->map, ranges));
1007 PetscFunctionReturn(PETSC_SUCCESS);
1008 }
1009
1010 // PetscClangLinter pragma disable: -fdoc-section-header-unknown
1011 /*@
1012 VecSetOption - Sets an option for controlling a vector's behavior.
1013
1014 Collective
1015
1016 Input Parameters:
1017 + x - the vector
1018 . op - the option
1019 - flag - turn the option on or off
1020
1021 Supported Options:
1022 + `VEC_IGNORE_OFF_PROC_ENTRIES` - which causes `VecSetValues()` to ignore
1023 entries destined to be stored on a separate processor. This can be used
1024 to eliminate the global reduction in the `VecAssemblyBegin()` if you know
1025 that you have only used `VecSetValues()` to set local elements
1026 . `VEC_IGNORE_NEGATIVE_INDICES` - which means you can pass negative indices
1027 in ix in calls to `VecSetValues()` or `VecGetValues()`. These rows are simply
1028 ignored.
1029 - `VEC_SUBSET_OFF_PROC_ENTRIES` - which causes `VecAssemblyBegin()` to assume that the off-process
1030 entries will always be a subset (possibly equal) of the off-process entries set on the
1031 first assembly which had a true `VEC_SUBSET_OFF_PROC_ENTRIES` and the vector has not
1032 changed this flag afterwards. If this assembly is not such first assembly, then this
1033 assembly can reuse the communication pattern setup in that first assembly, thus avoiding
1034 a global reduction. Subsequent assemblies setting off-process values should use the same
1035 InsertMode as the first assembly.
1036
1037 Level: intermediate
1038
1039 Developer Notes:
1040 The `InsertMode` restriction could be removed by packing the stash messages out of place.
1041
1042 .seealso: [](ch_vectors), `Vec`, `VecSetValues()`
1043 @*/
VecSetOption(Vec x,VecOption op,PetscBool flag)1044 PetscErrorCode VecSetOption(Vec x, VecOption op, PetscBool flag)
1045 {
1046 PetscFunctionBegin;
1047 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1048 PetscValidType(x, 1);
1049 PetscTryTypeMethod(x, setoption, op, flag);
1050 PetscFunctionReturn(PETSC_SUCCESS);
1051 }
1052
1053 /* Default routines for obtaining and releasing; */
1054 /* may be used by any implementation */
VecDuplicateVecs_Default(Vec w,PetscInt m,Vec * V[])1055 PetscErrorCode VecDuplicateVecs_Default(Vec w, PetscInt m, Vec *V[])
1056 {
1057 PetscFunctionBegin;
1058 PetscCheck(m > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "m must be > 0: m = %" PetscInt_FMT, m);
1059 PetscCall(PetscMalloc1(m, V));
1060 for (PetscInt i = 0; i < m; i++) PetscCall(VecDuplicate(w, *V + i));
1061 PetscFunctionReturn(PETSC_SUCCESS);
1062 }
1063
VecDestroyVecs_Default(PetscInt m,Vec v[])1064 PetscErrorCode VecDestroyVecs_Default(PetscInt m, Vec v[])
1065 {
1066 PetscInt i;
1067
1068 PetscFunctionBegin;
1069 PetscAssertPointer(v, 2);
1070 for (i = 0; i < m; i++) PetscCall(VecDestroy(&v[i]));
1071 PetscCall(PetscFree(v));
1072 PetscFunctionReturn(PETSC_SUCCESS);
1073 }
1074
1075 /*@
1076 VecResetArray - Resets a vector to use its default memory. Call this
1077 after the use of `VecPlaceArray()`.
1078
1079 Not Collective
1080
1081 Input Parameter:
1082 . vec - the vector
1083
1084 Level: developer
1085
1086 .seealso: [](ch_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`
1087 @*/
VecResetArray(Vec vec)1088 PetscErrorCode VecResetArray(Vec vec)
1089 {
1090 PetscFunctionBegin;
1091 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1092 PetscValidType(vec, 1);
1093 PetscUseTypeMethod(vec, resetarray);
1094 PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1095 PetscFunctionReturn(PETSC_SUCCESS);
1096 }
1097
1098 /*@
1099 VecLoad - Loads a vector that has been stored in binary or HDF5 format
1100 with `VecView()`.
1101
1102 Collective
1103
1104 Input Parameters:
1105 + vec - the newly loaded vector, this needs to have been created with `VecCreate()` or
1106 some related function before the call to `VecLoad()`.
1107 - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or
1108 HDF5 file viewer, obtained from `PetscViewerHDF5Open()`
1109
1110 Level: intermediate
1111
1112 Notes:
1113 Defaults to the standard `VECSEQ` or `VECMPI`, if you want some other type of `Vec` call `VecSetFromOptions()`
1114 before calling this.
1115
1116 The input file must contain the full global vector, as
1117 written by the routine `VecView()`.
1118
1119 If the type or size of `vec` is not set before a call to `VecLoad()`, PETSc
1120 sets the type and the local and global sizes based on the vector it is reading in. If type and/or
1121 sizes are already set, then the same are used.
1122
1123 If using the binary viewer and the blocksize of the vector is greater than one then you must provide a unique prefix to
1124 the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
1125 vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
1126 information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
1127 filename. If you copy the binary file, make sure you copy the associated .info file with it.
1128
1129 If using HDF5, you must assign the `Vec` the same name as was used in the Vec
1130 that was stored in the file using `PetscObjectSetName()`. Otherwise you will
1131 get the error message: "Cannot H5DOpen2() with `Vec` name NAMEOFOBJECT".
1132
1133 If the HDF5 file contains a two dimensional array the first dimension is treated as the block size
1134 in loading the vector. Hence, for example, using MATLAB notation h5create('vector.dat','/Test_Vec',[27 1]);
1135 will load a vector of size 27 and block size 27 thus resulting in all 27 entries being on the first process of
1136 vectors communicator and the rest of the processes having zero entries
1137
1138 Notes for advanced users when using the binary viewer:
1139 Most users should not need to know the details of the binary storage
1140 format, since `VecLoad()` and `VecView()` completely hide these details.
1141 But for anyone who's interested, the standard binary vector storage
1142 format is
1143 .vb
1144 PetscInt VEC_FILE_CLASSID
1145 PetscInt number of rows
1146 PetscScalar *values of all entries
1147 .ve
1148
1149 In addition, PETSc automatically uses byte swapping to work on all machines; the files
1150 are written ALWAYS using big-endian ordering. On small-endian machines the numbers
1151 are converted to the small-endian format when they are read in from the file.
1152 See PetscBinaryRead() and PetscBinaryWrite() to see how this may be done.
1153
1154 .seealso: [](ch_vectors), `Vec`, `PetscViewerBinaryOpen()`, `VecView()`, `MatLoad()`
1155 @*/
VecLoad(Vec vec,PetscViewer viewer)1156 PetscErrorCode VecLoad(Vec vec, PetscViewer viewer)
1157 {
1158 PetscViewerFormat format;
1159
1160 PetscFunctionBegin;
1161 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1162 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1163 PetscCheckSameComm(vec, 1, viewer, 2);
1164
1165 PetscCall(VecSetErrorIfLocked(vec, 1));
1166 if (!((PetscObject)vec)->type_name && !vec->ops->create) PetscCall(VecSetType(vec, VECSTANDARD));
1167 PetscCall(PetscLogEventBegin(VEC_Load, viewer, 0, 0, 0));
1168 PetscCall(PetscViewerGetFormat(viewer, &format));
1169 if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
1170 PetscUseTypeMethod(vec, loadnative, viewer);
1171 } else {
1172 PetscUseTypeMethod(vec, load, viewer);
1173 }
1174 PetscCall(PetscLogEventEnd(VEC_Load, viewer, 0, 0, 0));
1175 PetscFunctionReturn(PETSC_SUCCESS);
1176 }
1177
1178 /*@
1179 VecReciprocal - Replaces each component of a vector by its reciprocal.
1180
1181 Logically Collective
1182
1183 Input Parameter:
1184 . vec - the vector
1185
1186 Output Parameter:
1187 . vec - the vector reciprocal
1188
1189 Level: intermediate
1190
1191 Note:
1192 Vector entries with value 0.0 are not changed
1193
1194 .seealso: [](ch_vectors), `Vec`, `VecLog()`, `VecExp()`, `VecSqrtAbs()`
1195 @*/
VecReciprocal(Vec vec)1196 PetscErrorCode VecReciprocal(Vec vec)
1197 {
1198 PetscFunctionBegin;
1199 PetscCall(VecReciprocalAsync_Private(vec, NULL));
1200 PetscFunctionReturn(PETSC_SUCCESS);
1201 }
1202
1203 /*@C
1204 VecSetOperation - Allows the user to override a particular vector operation.
1205
1206 Logically Collective; No Fortran Support
1207
1208 Input Parameters:
1209 + vec - The vector to modify
1210 . op - The name of the operation
1211 - f - The function that provides the operation.
1212
1213 Level: advanced
1214
1215 Example Usage:
1216 .vb
1217 // some new VecView() implementation, must have the same signature as the function it seeks
1218 // to replace
1219 PetscErrorCode UserVecView(Vec x, PetscViewer viewer)
1220 {
1221 PetscFunctionBeginUser;
1222 // ...
1223 PetscFunctionReturn(PETSC_SUCCESS);
1224 }
1225
1226 // Create a VECMPI which has a pre-defined VecView() implementation
1227 VecCreateMPI(comm, n, N, &x);
1228 // Calls the VECMPI implementation for VecView()
1229 VecView(x, viewer);
1230
1231 VecSetOperation(x, VECOP_VIEW, (PetscErrorCodeFn *)UserVecView);
1232 // Now calls UserVecView()
1233 VecView(x, viewer);
1234 .ve
1235
1236 Notes:
1237 `f` may be `NULL` to remove the operation from `vec`. Depending on the operation this may be
1238 allowed, however some always expect a valid function. In these cases an error will be raised
1239 when calling the interface routine in question.
1240
1241 See `VecOperation` for an up-to-date list of override-able operations. The operations listed
1242 there have the form `VECOP_<OPERATION>`, where `<OPERATION>` is the suffix (in all capital
1243 letters) of the public interface routine (e.g., `VecView()` -> `VECOP_VIEW`).
1244
1245 Overriding a particular `Vec`'s operation has no affect on any other `Vec`s past, present,
1246 or future. The user should also note that overriding a method is "destructive"; the previous
1247 method is not retained in any way.
1248
1249 Each function MUST return `PETSC_SUCCESS` on success and
1250 nonzero on failure.
1251
1252 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecGetOperation()`, `MatSetOperation()`, `MatShellSetOperation()`
1253 @*/
VecSetOperation(Vec vec,VecOperation op,PetscErrorCodeFn * f)1254 PetscErrorCode VecSetOperation(Vec vec, VecOperation op, PetscErrorCodeFn *f)
1255 {
1256 PetscFunctionBegin;
1257 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1258 if (op == VECOP_VIEW && !vec->ops->viewnative) {
1259 vec->ops->viewnative = vec->ops->view;
1260 } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
1261 vec->ops->loadnative = vec->ops->load;
1262 }
1263 ((PetscErrorCodeFn **)vec->ops)[(int)op] = f;
1264 PetscFunctionReturn(PETSC_SUCCESS);
1265 }
1266
1267 /*@
1268 VecStashSetInitialSize - sets the sizes of the vec-stash, that is
1269 used during the assembly process to store values that belong to
1270 other processors.
1271
1272 Not Collective, different processes can have different size stashes
1273
1274 Input Parameters:
1275 + vec - the vector
1276 . size - the initial size of the stash.
1277 - bsize - the initial size of the block-stash(if used).
1278
1279 Options Database Keys:
1280 + -vecstash_initial_size <size> or <size0,size1,...sizep-1> - set initial size
1281 - -vecstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1> - set initial block size
1282
1283 Level: intermediate
1284
1285 Notes:
1286 The block-stash is used for values set with `VecSetValuesBlocked()` while
1287 the stash is used for values set with `VecSetValues()`
1288
1289 Run with the option -info and look for output of the form
1290 VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
1291 to determine the appropriate value, MM, to use for size and
1292 VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
1293 to determine the value, BMM to use for bsize
1294
1295 PETSc attempts to smartly manage the stash size so there is little likelihood setting a
1296 a specific value here will affect performance
1297
1298 .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecStashView()`
1299 @*/
VecStashSetInitialSize(Vec vec,PetscInt size,PetscInt bsize)1300 PetscErrorCode VecStashSetInitialSize(Vec vec, PetscInt size, PetscInt bsize)
1301 {
1302 PetscFunctionBegin;
1303 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1304 PetscCall(VecStashSetInitialSize_Private(&vec->stash, size));
1305 PetscCall(VecStashSetInitialSize_Private(&vec->bstash, bsize));
1306 PetscFunctionReturn(PETSC_SUCCESS);
1307 }
1308
1309 /*@
1310 VecSetRandom - Sets all components of a vector to random numbers.
1311
1312 Logically Collective
1313
1314 Input Parameters:
1315 + x - the vector
1316 - rctx - the random number context, formed by `PetscRandomCreate()`, or use `NULL` and it will create one internally.
1317
1318 Output Parameter:
1319 . x - the vector
1320
1321 Example of Usage:
1322 .vb
1323 PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
1324 VecSetRandom(x,rctx);
1325 PetscRandomDestroy(&rctx);
1326 .ve
1327
1328 Level: intermediate
1329
1330 .seealso: [](ch_vectors), `Vec`, `VecSet()`, `VecSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()`
1331 @*/
VecSetRandom(Vec x,PetscRandom rctx)1332 PetscErrorCode VecSetRandom(Vec x, PetscRandom rctx)
1333 {
1334 PetscRandom randObj = NULL;
1335
1336 PetscFunctionBegin;
1337 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1338 if (rctx) PetscValidHeaderSpecific(rctx, PETSC_RANDOM_CLASSID, 2);
1339 PetscValidType(x, 1);
1340 VecCheckAssembled(x);
1341 PetscCall(VecSetErrorIfLocked(x, 1));
1342
1343 if (!rctx) {
1344 PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)x), &randObj));
1345 PetscCall(PetscRandomSetType(randObj, x->defaultrandtype));
1346 PetscCall(PetscRandomSetFromOptions(randObj));
1347 rctx = randObj;
1348 }
1349
1350 PetscCall(PetscLogEventBegin(VEC_SetRandom, x, rctx, 0, 0));
1351 PetscUseTypeMethod(x, setrandom, rctx);
1352 PetscCall(PetscLogEventEnd(VEC_SetRandom, x, rctx, 0, 0));
1353
1354 PetscCall(PetscRandomDestroy(&randObj));
1355 PetscCall(PetscObjectStateIncrease((PetscObject)x));
1356 PetscFunctionReturn(PETSC_SUCCESS);
1357 }
1358
1359 /*@
1360 VecZeroEntries - puts a `0.0` in each element of a vector
1361
1362 Logically Collective
1363
1364 Input Parameter:
1365 . vec - The vector
1366
1367 Level: beginner
1368
1369 Note:
1370 If the norm of the vector is known to be zero then this skips the unneeded zeroing process
1371
1372 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`, `VecSet()`, `VecSetValues()`
1373 @*/
VecZeroEntries(Vec vec)1374 PetscErrorCode VecZeroEntries(Vec vec)
1375 {
1376 PetscFunctionBegin;
1377 PetscCall(VecSet(vec, 0));
1378 PetscFunctionReturn(PETSC_SUCCESS);
1379 }
1380
1381 /*
1382 VecSetTypeFromOptions_Private - Sets the type of vector from user options. Defaults to a PETSc sequential vector on one
1383 processor and a PETSc MPI vector on more than one processor.
1384
1385 Collective
1386
1387 Input Parameter:
1388 . vec - The vector
1389
1390 Level: intermediate
1391
1392 .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`, `VecSetType()`
1393 */
VecSetTypeFromOptions_Private(Vec vec,PetscOptionItems PetscOptionsObject)1394 static PetscErrorCode VecSetTypeFromOptions_Private(Vec vec, PetscOptionItems PetscOptionsObject)
1395 {
1396 PetscBool opt;
1397 VecType defaultType;
1398 char typeName[256];
1399 PetscMPIInt size;
1400
1401 PetscFunctionBegin;
1402 if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
1403 else {
1404 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
1405 if (size > 1) defaultType = VECMPI;
1406 else defaultType = VECSEQ;
1407 }
1408
1409 PetscCall(VecRegisterAll());
1410 PetscCall(PetscOptionsFList("-vec_type", "Vector type", "VecSetType", VecList, defaultType, typeName, 256, &opt));
1411 if (opt) {
1412 PetscCall(VecSetType(vec, typeName));
1413 } else {
1414 PetscCall(VecSetType(vec, defaultType));
1415 }
1416 PetscFunctionReturn(PETSC_SUCCESS);
1417 }
1418
1419 /*@
1420 VecSetFromOptions - Configures the vector from the options database.
1421
1422 Collective
1423
1424 Input Parameter:
1425 . vec - The vector
1426
1427 Level: beginner
1428
1429 Notes:
1430 To see all options, run your program with the -help option.
1431
1432 Must be called after `VecCreate()` but before the vector is used.
1433
1434 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`
1435 @*/
VecSetFromOptions(Vec vec)1436 PetscErrorCode VecSetFromOptions(Vec vec)
1437 {
1438 PetscBool flg;
1439 PetscInt bind_below = 0;
1440
1441 PetscFunctionBegin;
1442 PetscValidHeaderSpecific(vec, VEC_CLASSID, 1);
1443
1444 PetscObjectOptionsBegin((PetscObject)vec);
1445 /* Handle vector type options */
1446 PetscCall(VecSetTypeFromOptions_Private(vec, PetscOptionsObject));
1447
1448 /* Handle specific vector options */
1449 PetscTryTypeMethod(vec, setfromoptions, PetscOptionsObject);
1450
1451 /* Bind to CPU if below a user-specified size threshold.
1452 * This perhaps belongs in the options for the GPU Vec types, but VecBindToCPU() does nothing when called on non-GPU types,
1453 * and putting it here makes is more maintainable than duplicating this for all. */
1454 PetscCall(PetscOptionsInt("-vec_bind_below", "Set the size threshold (in local entries) below which the Vec is bound to the CPU", "VecBindToCPU", bind_below, &bind_below, &flg));
1455 if (flg && vec->map->n < bind_below) PetscCall(VecBindToCPU(vec, PETSC_TRUE));
1456
1457 /* process any options handlers added with PetscObjectAddOptionsHandler() */
1458 PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)vec, PetscOptionsObject));
1459 PetscOptionsEnd();
1460 PetscFunctionReturn(PETSC_SUCCESS);
1461 }
1462
1463 /*@
1464 VecSetSizes - Sets the local and global sizes, and checks to determine compatibility of the sizes
1465
1466 Collective
1467
1468 Input Parameters:
1469 + v - the vector
1470 . n - the local size (or `PETSC_DECIDE` to have it set)
1471 - N - the global size (or `PETSC_DETERMINE` to have it set)
1472
1473 Level: intermediate
1474
1475 Notes:
1476 `N` cannot be `PETSC_DETERMINE` if `n` is `PETSC_DECIDE`
1477
1478 If one processor calls this with `N` of `PETSC_DETERMINE` then all processors must, otherwise the program will hang.
1479
1480 If `n` is not `PETSC_DECIDE`, then the value determines the `PetscLayout` of the vector and the ranges returned by
1481 `VecGetOwnershipRange()` and `VecGetOwnershipRanges()`
1482
1483 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecCreateSeq()`, `VecCreateMPI()`, `VecGetSize()`, `PetscSplitOwnership()`, `PetscLayout`,
1484 `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`, `MatSetSizes()`
1485 @*/
VecSetSizes(Vec v,PetscInt n,PetscInt N)1486 PetscErrorCode VecSetSizes(Vec v, PetscInt n, PetscInt N)
1487 {
1488 PetscFunctionBegin;
1489 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1490 if (N >= 0) {
1491 PetscValidLogicalCollectiveInt(v, N, 3);
1492 PetscCheck(n <= N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " cannot be larger than global size %" PetscInt_FMT, n, N);
1493 }
1494 PetscCheck(!(v->map->n >= 0 || v->map->N >= 0) || !(v->map->n != n || v->map->N != N), PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot change/reset vector sizes to %" PetscInt_FMT " local %" PetscInt_FMT " global after previously setting them to %" PetscInt_FMT " local %" PetscInt_FMT " global", n, N,
1495 v->map->n, v->map->N);
1496 v->map->n = n;
1497 v->map->N = N;
1498 PetscTryTypeMethod(v, create);
1499 v->ops->create = NULL;
1500 PetscFunctionReturn(PETSC_SUCCESS);
1501 }
1502
1503 /*@
1504 VecSetBlockSize - Sets the block size for future calls to `VecSetValuesBlocked()`
1505 and `VecSetValuesBlockedLocal()`.
1506
1507 Logically Collective
1508
1509 Input Parameters:
1510 + v - the vector
1511 - bs - the blocksize
1512
1513 Level: advanced
1514
1515 Note:
1516 All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1517
1518 Vectors obtained with `DMCreateGlobalVector()` and `DMCreateLocalVector()` generally already have a blocksize set based on the state of the `DM`
1519
1520 .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecGetBlockSize()`
1521 @*/
VecSetBlockSize(Vec v,PetscInt bs)1522 PetscErrorCode VecSetBlockSize(Vec v, PetscInt bs)
1523 {
1524 PetscFunctionBegin;
1525 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1526 PetscValidLogicalCollectiveInt(v, bs, 2);
1527 PetscCall(PetscLayoutSetBlockSize(v->map, bs));
1528 v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
1529 PetscFunctionReturn(PETSC_SUCCESS);
1530 }
1531
1532 /*@
1533 VecGetBlockSize - Gets the blocksize for the vector, i.e. what is used for `VecSetValuesBlocked()`
1534 and `VecSetValuesBlockedLocal()`.
1535
1536 Not Collective
1537
1538 Input Parameter:
1539 . v - the vector
1540
1541 Output Parameter:
1542 . bs - the blocksize
1543
1544 Level: advanced
1545
1546 Note:
1547 All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1548
1549 .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecSetBlockSize()`
1550 @*/
VecGetBlockSize(Vec v,PetscInt * bs)1551 PetscErrorCode VecGetBlockSize(Vec v, PetscInt *bs)
1552 {
1553 PetscFunctionBegin;
1554 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1555 PetscAssertPointer(bs, 2);
1556 PetscCall(PetscLayoutGetBlockSize(v->map, bs));
1557 PetscFunctionReturn(PETSC_SUCCESS);
1558 }
1559
1560 /*@
1561 VecSetOptionsPrefix - Sets the prefix used for searching for all
1562 `Vec` options in the database.
1563
1564 Logically Collective
1565
1566 Input Parameters:
1567 + v - the `Vec` context
1568 - prefix - the prefix to prepend to all option names
1569
1570 Level: advanced
1571
1572 Note:
1573 A hyphen (-) must NOT be given at the beginning of the prefix name.
1574 The first character of all runtime options is AUTOMATICALLY the hyphen.
1575
1576 .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`
1577 @*/
VecSetOptionsPrefix(Vec v,const char prefix[])1578 PetscErrorCode VecSetOptionsPrefix(Vec v, const char prefix[])
1579 {
1580 PetscFunctionBegin;
1581 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1582 PetscCall(PetscObjectSetOptionsPrefix((PetscObject)v, prefix));
1583 PetscFunctionReturn(PETSC_SUCCESS);
1584 }
1585
1586 /*@
1587 VecAppendOptionsPrefix - Appends to the prefix used for searching for all
1588 `Vec` options in the database.
1589
1590 Logically Collective
1591
1592 Input Parameters:
1593 + v - the `Vec` context
1594 - prefix - the prefix to prepend to all option names
1595
1596 Level: advanced
1597
1598 Note:
1599 A hyphen (-) must NOT be given at the beginning of the prefix name.
1600 The first character of all runtime options is AUTOMATICALLY the hyphen.
1601
1602 .seealso: [](ch_vectors), `Vec`, `VecGetOptionsPrefix()`
1603 @*/
VecAppendOptionsPrefix(Vec v,const char prefix[])1604 PetscErrorCode VecAppendOptionsPrefix(Vec v, const char prefix[])
1605 {
1606 PetscFunctionBegin;
1607 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1608 PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)v, prefix));
1609 PetscFunctionReturn(PETSC_SUCCESS);
1610 }
1611
1612 /*@
1613 VecGetOptionsPrefix - Sets the prefix used for searching for all
1614 Vec options in the database.
1615
1616 Not Collective
1617
1618 Input Parameter:
1619 . v - the `Vec` context
1620
1621 Output Parameter:
1622 . prefix - pointer to the prefix string used
1623
1624 Level: advanced
1625
1626 .seealso: [](ch_vectors), `Vec`, `VecAppendOptionsPrefix()`
1627 @*/
VecGetOptionsPrefix(Vec v,const char * prefix[])1628 PetscErrorCode VecGetOptionsPrefix(Vec v, const char *prefix[])
1629 {
1630 PetscFunctionBegin;
1631 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1632 PetscCall(PetscObjectGetOptionsPrefix((PetscObject)v, prefix));
1633 PetscFunctionReturn(PETSC_SUCCESS);
1634 }
1635
1636 /*@C
1637 VecGetState - Gets the state of a `Vec`.
1638
1639 Not Collective
1640
1641 Input Parameter:
1642 . v - the `Vec` context
1643
1644 Output Parameter:
1645 . state - the object state
1646
1647 Level: advanced
1648
1649 Note:
1650 Object state is an integer which gets increased every time
1651 the object is changed. By saving and later querying the object state
1652 one can determine whether information about the object is still current.
1653
1654 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `PetscObjectStateGet()`
1655 @*/
VecGetState(Vec v,PetscObjectState * state)1656 PetscErrorCode VecGetState(Vec v, PetscObjectState *state)
1657 {
1658 PetscFunctionBegin;
1659 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1660 PetscAssertPointer(state, 2);
1661 PetscCall(PetscObjectStateGet((PetscObject)v, state));
1662 PetscFunctionReturn(PETSC_SUCCESS);
1663 }
1664
1665 /*@
1666 VecSetUp - Sets up the internal vector data structures for the later use.
1667
1668 Collective
1669
1670 Input Parameter:
1671 . v - the `Vec` context
1672
1673 Level: advanced
1674
1675 Notes:
1676 For basic use of the `Vec` classes the user need not explicitly call
1677 `VecSetUp()`, since these actions will happen automatically.
1678
1679 .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDestroy()`
1680 @*/
VecSetUp(Vec v)1681 PetscErrorCode VecSetUp(Vec v)
1682 {
1683 PetscMPIInt size;
1684
1685 PetscFunctionBegin;
1686 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1687 PetscCheck(v->map->n >= 0 || v->map->N >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Sizes not set");
1688 if (!((PetscObject)v)->type_name) {
1689 PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1690 if (size == 1) {
1691 PetscCall(VecSetType(v, VECSEQ));
1692 } else {
1693 PetscCall(VecSetType(v, VECMPI));
1694 }
1695 }
1696 PetscFunctionReturn(PETSC_SUCCESS);
1697 }
1698
1699 /*
1700 These currently expose the PetscScalar/PetscReal in updating the
1701 cached norm. If we push those down into the implementation these
1702 will become independent of PetscScalar/PetscReal
1703 */
1704
VecCopyAsync_Private(Vec x,Vec y,PetscDeviceContext dctx)1705 PetscErrorCode VecCopyAsync_Private(Vec x, Vec y, PetscDeviceContext dctx)
1706 {
1707 PetscBool flgs[4];
1708 PetscReal norms[4] = {0.0, 0.0, 0.0, 0.0};
1709
1710 PetscFunctionBegin;
1711 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1712 PetscValidHeaderSpecific(y, VEC_CLASSID, 2);
1713 PetscValidType(x, 1);
1714 PetscValidType(y, 2);
1715 if (x == y) PetscFunctionReturn(PETSC_SUCCESS);
1716 VecCheckSameLocalSize(x, 1, y, 2);
1717 VecCheckAssembled(x);
1718 PetscCall(VecSetErrorIfLocked(y, 2));
1719
1720 #if !defined(PETSC_USE_MIXED_PRECISION)
1721 for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
1722 #endif
1723
1724 PetscCall(PetscLogEventBegin(VEC_Copy, x, y, 0, 0));
1725 #if defined(PETSC_USE_MIXED_PRECISION)
1726 extern PetscErrorCode VecGetArray(Vec, double **);
1727 extern PetscErrorCode VecRestoreArray(Vec, double **);
1728 extern PetscErrorCode VecGetArray(Vec, float **);
1729 extern PetscErrorCode VecRestoreArray(Vec, float **);
1730 extern PetscErrorCode VecGetArrayRead(Vec, const double **);
1731 extern PetscErrorCode VecRestoreArrayRead(Vec, const double **);
1732 extern PetscErrorCode VecGetArrayRead(Vec, const float **);
1733 extern PetscErrorCode VecRestoreArrayRead(Vec, const float **);
1734 if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
1735 PetscInt i, n;
1736 const float *xx;
1737 double *yy;
1738 PetscCall(VecGetArrayRead(x, &xx));
1739 PetscCall(VecGetArray(y, &yy));
1740 PetscCall(VecGetLocalSize(x, &n));
1741 for (i = 0; i < n; i++) yy[i] = xx[i];
1742 PetscCall(VecRestoreArrayRead(x, &xx));
1743 PetscCall(VecRestoreArray(y, &yy));
1744 } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
1745 PetscInt i, n;
1746 float *yy;
1747 const double *xx;
1748 PetscCall(VecGetArrayRead(x, &xx));
1749 PetscCall(VecGetArray(y, &yy));
1750 PetscCall(VecGetLocalSize(x, &n));
1751 for (i = 0; i < n; i++) yy[i] = (float)xx[i];
1752 PetscCall(VecRestoreArrayRead(x, &xx));
1753 PetscCall(VecRestoreArray(y, &yy));
1754 } else PetscUseTypeMethod(x, copy, y);
1755 #else
1756 VecMethodDispatch(x, dctx, VecAsyncFnName(Copy), copy, (Vec, Vec, PetscDeviceContext), y);
1757 #endif
1758
1759 PetscCall(PetscObjectStateIncrease((PetscObject)y));
1760 #if !defined(PETSC_USE_MIXED_PRECISION)
1761 for (PetscInt i = 0; i < 4; i++) {
1762 if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], norms[i]));
1763 }
1764 #endif
1765
1766 PetscCall(PetscLogEventEnd(VEC_Copy, x, y, 0, 0));
1767 PetscFunctionReturn(PETSC_SUCCESS);
1768 }
1769
1770 /*@
1771 VecCopy - Copies a vector `y = x`
1772
1773 Logically Collective
1774
1775 Input Parameter:
1776 . x - the vector
1777
1778 Output Parameter:
1779 . y - the copy
1780
1781 Level: beginner
1782
1783 Note:
1784 For default parallel PETSc vectors, both `x` and `y` must be distributed in
1785 the same manner; local copies are done.
1786
1787 Developer Notes:
1788 `PetscCheckSameTypeAndComm`(x,1,y,2) is not used on these vectors because we allow one
1789 of the vectors to be sequential and one to be parallel so long as both have the same
1790 local sizes. This is used in some internal functions in PETSc.
1791
1792 .seealso: [](ch_vectors), `Vec`, `VecDuplicate()`
1793 @*/
VecCopy(Vec x,Vec y)1794 PetscErrorCode VecCopy(Vec x, Vec y)
1795 {
1796 PetscFunctionBegin;
1797 PetscCall(VecCopyAsync_Private(x, y, NULL));
1798 PetscFunctionReturn(PETSC_SUCCESS);
1799 }
1800
VecSwapAsync_Private(Vec x,Vec y,PetscDeviceContext dctx)1801 PetscErrorCode VecSwapAsync_Private(Vec x, Vec y, PetscDeviceContext dctx)
1802 {
1803 PetscReal normxs[4], normys[4];
1804 PetscBool flgxs[4], flgys[4];
1805
1806 PetscFunctionBegin;
1807 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
1808 PetscValidHeaderSpecific(y, VEC_CLASSID, 2);
1809 PetscValidType(x, 1);
1810 PetscValidType(y, 2);
1811 PetscCheckSameTypeAndComm(x, 1, y, 2);
1812 VecCheckSameSize(x, 1, y, 2);
1813 VecCheckAssembled(x);
1814 VecCheckAssembled(y);
1815 PetscCall(VecSetErrorIfLocked(x, 1));
1816 PetscCall(VecSetErrorIfLocked(y, 2));
1817
1818 for (PetscInt i = 0; i < 4; i++) {
1819 PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], normxs[i], flgxs[i]));
1820 PetscCall(PetscObjectComposedDataGetReal((PetscObject)y, NormIds[i], normys[i], flgys[i]));
1821 }
1822
1823 PetscCall(PetscLogEventBegin(VEC_Swap, x, y, 0, 0));
1824 VecMethodDispatch(x, dctx, VecAsyncFnName(Swap), swap, (Vec, Vec, PetscDeviceContext), y);
1825 PetscCall(PetscLogEventEnd(VEC_Swap, x, y, 0, 0));
1826
1827 PetscCall(PetscObjectStateIncrease((PetscObject)x));
1828 PetscCall(PetscObjectStateIncrease((PetscObject)y));
1829 for (PetscInt i = 0; i < 4; i++) {
1830 if (flgxs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], normxs[i]));
1831 if (flgys[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], normys[i]));
1832 }
1833 PetscFunctionReturn(PETSC_SUCCESS);
1834 }
1835 /*@
1836 VecSwap - Swaps the values between two vectors, `x` and `y`.
1837
1838 Logically Collective
1839
1840 Input Parameters:
1841 + x - the first vector
1842 - y - the second vector
1843
1844 Level: advanced
1845
1846 .seealso: [](ch_vectors), `Vec`, `VecSet()`
1847 @*/
VecSwap(Vec x,Vec y)1848 PetscErrorCode VecSwap(Vec x, Vec y)
1849 {
1850 PetscFunctionBegin;
1851 PetscCall(VecSwapAsync_Private(x, y, NULL));
1852 PetscFunctionReturn(PETSC_SUCCESS);
1853 }
1854
1855 /*@
1856 VecStashViewFromOptions - Processes command line options to determine if/how a `VecStash` object is to be viewed.
1857
1858 Collective
1859
1860 Input Parameters:
1861 + obj - the `Vec` containing a stash
1862 . bobj - optional other object that provides the prefix
1863 - optionname - option to activate viewing
1864
1865 Level: intermediate
1866
1867 Developer Notes:
1868 This cannot use `PetscObjectViewFromOptions()` because it takes a `Vec` as an argument but does not use `VecView()`
1869
1870 .seealso: [](ch_vectors), `Vec`, `VecStashSetInitialSize()`
1871 @*/
VecStashViewFromOptions(Vec obj,PetscObject bobj,const char optionname[])1872 PetscErrorCode VecStashViewFromOptions(Vec obj, PetscObject bobj, const char optionname[])
1873 {
1874 PetscViewer viewer;
1875 PetscBool flg;
1876 PetscViewerFormat format;
1877 char *prefix;
1878
1879 PetscFunctionBegin;
1880 prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
1881 PetscCall(PetscOptionsCreateViewer(PetscObjectComm((PetscObject)obj), ((PetscObject)obj)->options, prefix, optionname, &viewer, &format, &flg));
1882 if (flg) {
1883 PetscCall(PetscViewerPushFormat(viewer, format));
1884 PetscCall(VecStashView(obj, viewer));
1885 PetscCall(PetscViewerPopFormat(viewer));
1886 PetscCall(PetscViewerDestroy(&viewer));
1887 }
1888 PetscFunctionReturn(PETSC_SUCCESS);
1889 }
1890
1891 /*@
1892 VecStashView - Prints the entries in the vector stash and block stash.
1893
1894 Collective
1895
1896 Input Parameters:
1897 + v - the vector
1898 - viewer - the viewer
1899
1900 Level: advanced
1901
1902 .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`
1903 @*/
VecStashView(Vec v,PetscViewer viewer)1904 PetscErrorCode VecStashView(Vec v, PetscViewer viewer)
1905 {
1906 PetscMPIInt rank;
1907 PetscInt i, j;
1908 PetscBool match;
1909 VecStash *s;
1910 PetscScalar val;
1911
1912 PetscFunctionBegin;
1913 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
1914 PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1915 PetscCheckSameComm(v, 1, viewer, 2);
1916
1917 PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &match));
1918 PetscCheck(match, PETSC_COMM_SELF, PETSC_ERR_SUP, "Stash viewer only works with ASCII viewer not %s", ((PetscObject)v)->type_name);
1919 PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1920 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
1921 s = &v->bstash;
1922
1923 /* print block stash */
1924 PetscCall(PetscViewerASCIIPushSynchronized(viewer));
1925 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector Block stash size %" PetscInt_FMT " block size %" PetscInt_FMT "\n", rank, s->n, s->bs));
1926 for (i = 0; i < s->n; i++) {
1927 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " ", rank, s->idx[i]));
1928 for (j = 0; j < s->bs; j++) {
1929 val = s->array[i * s->bs + j];
1930 #if defined(PETSC_USE_COMPLEX)
1931 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "(%18.16e %18.16e) ", (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1932 #else
1933 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%18.16e ", (double)val));
1934 #endif
1935 }
1936 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
1937 }
1938 PetscCall(PetscViewerFlush(viewer));
1939
1940 s = &v->stash;
1941
1942 /* print basic stash */
1943 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector stash size %" PetscInt_FMT "\n", rank, s->n));
1944 for (i = 0; i < s->n; i++) {
1945 val = s->array[i];
1946 #if defined(PETSC_USE_COMPLEX)
1947 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " (%18.16e %18.16e) ", rank, s->idx[i], (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1948 #else
1949 PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " %18.16e\n", rank, s->idx[i], (double)val));
1950 #endif
1951 }
1952 PetscCall(PetscViewerFlush(viewer));
1953 PetscCall(PetscViewerASCIIPopSynchronized(viewer));
1954 PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1955 PetscFunctionReturn(PETSC_SUCCESS);
1956 }
1957
PetscOptionsGetVec(PetscOptions options,const char prefix[],const char key[],Vec v,PetscBool * set)1958 PetscErrorCode PetscOptionsGetVec(PetscOptions options, const char prefix[], const char key[], Vec v, PetscBool *set)
1959 {
1960 PetscInt i, N, rstart, rend;
1961 PetscScalar *xx;
1962 PetscReal *xreal;
1963 PetscBool iset;
1964
1965 PetscFunctionBegin;
1966 PetscCall(VecGetOwnershipRange(v, &rstart, &rend));
1967 PetscCall(VecGetSize(v, &N));
1968 PetscCall(PetscCalloc1(N, &xreal));
1969 PetscCall(PetscOptionsGetRealArray(options, prefix, key, xreal, &N, &iset));
1970 if (iset) {
1971 PetscCall(VecGetArray(v, &xx));
1972 for (i = rstart; i < rend; i++) xx[i - rstart] = xreal[i];
1973 PetscCall(VecRestoreArray(v, &xx));
1974 }
1975 PetscCall(PetscFree(xreal));
1976 if (set) *set = iset;
1977 PetscFunctionReturn(PETSC_SUCCESS);
1978 }
1979
1980 /*@
1981 VecGetLayout - get `PetscLayout` describing a vector layout
1982
1983 Not Collective
1984
1985 Input Parameter:
1986 . x - the vector
1987
1988 Output Parameter:
1989 . map - the layout
1990
1991 Level: developer
1992
1993 Note:
1994 The layout determines what vector elements are contained on each MPI process
1995
1996 .seealso: [](ch_vectors), `PetscLayout`, `Vec`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1997 @*/
VecGetLayout(Vec x,PetscLayout * map)1998 PetscErrorCode VecGetLayout(Vec x, PetscLayout *map)
1999 {
2000 PetscFunctionBegin;
2001 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
2002 PetscAssertPointer(map, 2);
2003 *map = x->map;
2004 PetscFunctionReturn(PETSC_SUCCESS);
2005 }
2006
2007 /*@
2008 VecSetLayout - set `PetscLayout` describing vector layout
2009
2010 Not Collective
2011
2012 Input Parameters:
2013 + x - the vector
2014 - map - the layout
2015
2016 Level: developer
2017
2018 Note:
2019 It is normally only valid to replace the layout with a layout known to be equivalent.
2020
2021 .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2022 @*/
VecSetLayout(Vec x,PetscLayout map)2023 PetscErrorCode VecSetLayout(Vec x, PetscLayout map)
2024 {
2025 PetscFunctionBegin;
2026 PetscValidHeaderSpecific(x, VEC_CLASSID, 1);
2027 PetscCall(PetscLayoutReference(map, &x->map));
2028 PetscFunctionReturn(PETSC_SUCCESS);
2029 }
2030
2031 /*@
2032 VecFlag - set infinity into the local part of the vector on any subset of MPI processes
2033
2034 Logically Collective
2035
2036 Input Parameters:
2037 + xin - the vector, can be `NULL` but only if on all processes
2038 - flg - indicates if this processes portion of the vector should be set to infinity
2039
2040 Level: developer
2041
2042 Note:
2043 This removes the values from the vector norm cache for all processes by calling `PetscObjectIncrease()`.
2044
2045 This is used for any subset of MPI processes to indicate an failure in a solver, after the next use of `VecNorm()` if
2046 `KSPCheckNorm()` detects an infinity and at least one of the MPI processes has a not converged reason then the `KSP`
2047 object collectively is labeled as not converged.
2048
2049 .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2050 @*/
VecFlag(Vec xin,PetscInt flg)2051 PetscErrorCode VecFlag(Vec xin, PetscInt flg)
2052 {
2053 // MSVC gives "divide by zero" error at compile time - so declare as volatile to skip this check.
2054 volatile PetscReal one = 1.0, zero = 0.0;
2055 PetscScalar inf;
2056
2057 PetscFunctionBegin;
2058 if (!xin) PetscFunctionReturn(PETSC_SUCCESS);
2059 PetscValidHeaderSpecific(xin, VEC_CLASSID, 1);
2060 PetscCall(PetscObjectStateIncrease((PetscObject)xin));
2061 if (flg) {
2062 PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2063 inf = one / zero;
2064 PetscCall(PetscFPTrapPop());
2065 if (xin->ops->set) {
2066 PetscUseTypeMethod(xin, set, inf);
2067 } else {
2068 PetscInt n;
2069 PetscScalar *xx;
2070
2071 PetscCall(VecGetLocalSize(xin, &n));
2072 PetscCall(VecGetArrayWrite(xin, &xx));
2073 for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
2074 PetscCall(VecRestoreArrayWrite(xin, &xx));
2075 }
2076 }
2077 PetscFunctionReturn(PETSC_SUCCESS);
2078 }
2079
2080 /*@
2081 VecSetInf - set infinity into the local part of the vector
2082
2083 Not Collective
2084
2085 Input Parameters:
2086 . xin - the vector
2087
2088 Level: developer
2089
2090 Note:
2091 Deprecated, see `VecFlag()`
2092 This is used for any subset of MPI processes to indicate an failure in a solver, after the next use of `VecNorm()` if
2093 `KSPCheckNorm()` detects an infinity and at least one of the MPI processes has a not converged reason then the `KSP`
2094 object collectively is labeled as not converged.
2095
2096 This cannot be called if `xin` has a cached norm available
2097
2098 .seealso: [](ch_vectors), `VecFlag()`, `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSize()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
2099 @*/
VecSetInf(Vec xin)2100 PetscErrorCode VecSetInf(Vec xin)
2101 {
2102 // MSVC gives "divide by zero" error at compile time - so declare as volatile to skip this check.
2103 volatile PetscReal one = 1.0, zero = 0.0;
2104 PetscScalar inf;
2105 PetscBool flg;
2106
2107 PetscFunctionBegin;
2108 PetscCall(VecNormAvailable(xin, NORM_2, &flg, NULL));
2109 PetscCheck(!flg, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Cannot call VecSetInf() if the vector has a cached norm");
2110 PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
2111 inf = one / zero;
2112 PetscCall(PetscFPTrapPop());
2113 if (xin->ops->set) {
2114 PetscUseTypeMethod(xin, set, inf);
2115 } else {
2116 PetscInt n;
2117 PetscScalar *xx;
2118
2119 PetscCall(VecGetLocalSize(xin, &n));
2120 PetscCall(VecGetArrayWrite(xin, &xx));
2121 for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
2122 PetscCall(VecRestoreArrayWrite(xin, &xx));
2123 }
2124 PetscFunctionReturn(PETSC_SUCCESS);
2125 }
2126
2127 /*@
2128 VecBindToCPU - marks a vector to temporarily stay on the CPU and perform computations on the CPU
2129
2130 Logically collective
2131
2132 Input Parameters:
2133 + v - the vector
2134 - flg - bind to the CPU if value of `PETSC_TRUE`
2135
2136 Level: intermediate
2137
2138 .seealso: [](ch_vectors), `Vec`, `VecBoundToCPU()`
2139 @*/
VecBindToCPU(Vec v,PetscBool flg)2140 PetscErrorCode VecBindToCPU(Vec v, PetscBool flg)
2141 {
2142 PetscFunctionBegin;
2143 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2144 PetscValidLogicalCollectiveBool(v, flg, 2);
2145 #if defined(PETSC_HAVE_DEVICE)
2146 if (v->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS);
2147 v->boundtocpu = flg;
2148 PetscTryTypeMethod(v, bindtocpu, flg);
2149 #endif
2150 PetscFunctionReturn(PETSC_SUCCESS);
2151 }
2152
2153 /*@
2154 VecBoundToCPU - query if a vector is bound to the CPU
2155
2156 Not collective
2157
2158 Input Parameter:
2159 . v - the vector
2160
2161 Output Parameter:
2162 . flg - the logical flag
2163
2164 Level: intermediate
2165
2166 .seealso: [](ch_vectors), `Vec`, `VecBindToCPU()`
2167 @*/
VecBoundToCPU(Vec v,PetscBool * flg)2168 PetscErrorCode VecBoundToCPU(Vec v, PetscBool *flg)
2169 {
2170 PetscFunctionBegin;
2171 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2172 PetscAssertPointer(flg, 2);
2173 #if defined(PETSC_HAVE_DEVICE)
2174 *flg = v->boundtocpu;
2175 #else
2176 *flg = PETSC_TRUE;
2177 #endif
2178 PetscFunctionReturn(PETSC_SUCCESS);
2179 }
2180
2181 /*@
2182 VecSetBindingPropagates - Sets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2183
2184 Input Parameters:
2185 + v - the vector
2186 - flg - flag indicating whether the boundtocpu flag should be propagated
2187
2188 Level: developer
2189
2190 Notes:
2191 If the value of flg is set to true, then `VecDuplicate()` and `VecDuplicateVecs()` will bind created vectors to GPU if the input vector is bound to the CPU.
2192 The created vectors will also have their bindingpropagates flag set to true.
2193
2194 Developer Notes:
2195 If a `DMDA` has the `-dm_bind_below option` set to true, then vectors created by `DMCreateGlobalVector()` will have `VecSetBindingPropagates()` called on them to
2196 set their bindingpropagates flag to true.
2197
2198 .seealso: [](ch_vectors), `Vec`, `MatSetBindingPropagates()`, `VecGetBindingPropagates()`
2199 @*/
VecSetBindingPropagates(Vec v,PetscBool flg)2200 PetscErrorCode VecSetBindingPropagates(Vec v, PetscBool flg)
2201 {
2202 PetscFunctionBegin;
2203 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2204 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2205 v->bindingpropagates = flg;
2206 #endif
2207 PetscFunctionReturn(PETSC_SUCCESS);
2208 }
2209
2210 /*@
2211 VecGetBindingPropagates - Gets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2212
2213 Input Parameter:
2214 . v - the vector
2215
2216 Output Parameter:
2217 . flg - flag indicating whether the boundtocpu flag will be propagated
2218
2219 Level: developer
2220
2221 .seealso: [](ch_vectors), `Vec`, `VecSetBindingPropagates()`
2222 @*/
VecGetBindingPropagates(Vec v,PetscBool * flg)2223 PetscErrorCode VecGetBindingPropagates(Vec v, PetscBool *flg)
2224 {
2225 PetscFunctionBegin;
2226 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2227 PetscAssertPointer(flg, 2);
2228 #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2229 *flg = v->bindingpropagates;
2230 #else
2231 *flg = PETSC_FALSE;
2232 #endif
2233 PetscFunctionReturn(PETSC_SUCCESS);
2234 }
2235
2236 /*@C
2237 VecSetPinnedMemoryMin - Set the minimum data size for which pinned memory will be used for host (CPU) allocations.
2238
2239 Logically Collective
2240
2241 Input Parameters:
2242 + v - the vector
2243 - mbytes - minimum data size in bytes
2244
2245 Options Database Key:
2246 . -vec_pinned_memory_min <size> - minimum size (in bytes) for an allocation to use pinned memory on host.
2247
2248 Level: developer
2249
2250 Note:
2251 Specifying -1 ensures that pinned memory will never be used.
2252
2253 .seealso: [](ch_vectors), `Vec`, `VecGetPinnedMemoryMin()`
2254 @*/
VecSetPinnedMemoryMin(Vec v,size_t mbytes)2255 PetscErrorCode VecSetPinnedMemoryMin(Vec v, size_t mbytes)
2256 {
2257 PetscFunctionBegin;
2258 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2259 #if PetscDefined(HAVE_DEVICE)
2260 v->minimum_bytes_pinned_memory = mbytes;
2261 #endif
2262 PetscFunctionReturn(PETSC_SUCCESS);
2263 }
2264
2265 /*@C
2266 VecGetPinnedMemoryMin - Get the minimum data size for which pinned memory will be used for host (CPU) allocations.
2267
2268 Logically Collective
2269
2270 Input Parameter:
2271 . v - the vector
2272
2273 Output Parameter:
2274 . mbytes - minimum data size in bytes
2275
2276 Level: developer
2277
2278 .seealso: [](ch_vectors), `Vec`, `VecSetPinnedMemoryMin()`
2279 @*/
VecGetPinnedMemoryMin(Vec v,size_t * mbytes)2280 PetscErrorCode VecGetPinnedMemoryMin(Vec v, size_t *mbytes)
2281 {
2282 PetscFunctionBegin;
2283 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2284 PetscAssertPointer(mbytes, 2);
2285 #if PetscDefined(HAVE_DEVICE)
2286 *mbytes = v->minimum_bytes_pinned_memory;
2287 #endif
2288 PetscFunctionReturn(PETSC_SUCCESS);
2289 }
2290
2291 /*@
2292 VecGetOffloadMask - Get the offload mask of a `Vec`
2293
2294 Not Collective
2295
2296 Input Parameter:
2297 . v - the vector
2298
2299 Output Parameter:
2300 . mask - corresponding `PetscOffloadMask` enum value.
2301
2302 Level: intermediate
2303
2304 .seealso: [](ch_vectors), `Vec`, `VecCreateSeqCUDA()`, `VecCreateSeqViennaCL()`, `VecGetArray()`, `VecGetType()`
2305 @*/
VecGetOffloadMask(Vec v,PetscOffloadMask * mask)2306 PetscErrorCode VecGetOffloadMask(Vec v, PetscOffloadMask *mask)
2307 {
2308 PetscFunctionBegin;
2309 PetscValidHeaderSpecific(v, VEC_CLASSID, 1);
2310 PetscAssertPointer(mask, 2);
2311 *mask = v->offloadmask;
2312 PetscFunctionReturn(PETSC_SUCCESS);
2313 }
2314
2315 #if !defined(PETSC_HAVE_VIENNACL)
VecViennaCLGetCLContext(Vec v,PETSC_UINTPTR_T * ctx)2316 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v, PETSC_UINTPTR_T *ctx)
2317 {
2318 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_context");
2319 }
2320
VecViennaCLGetCLQueue(Vec v,PETSC_UINTPTR_T * queue)2321 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLQueue(Vec v, PETSC_UINTPTR_T *queue)
2322 {
2323 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_command_queue");
2324 }
2325
VecViennaCLGetCLMem(Vec v,PETSC_UINTPTR_T * queue)2326 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMem(Vec v, PETSC_UINTPTR_T *queue)
2327 {
2328 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2329 }
2330
VecViennaCLGetCLMemRead(Vec v,PETSC_UINTPTR_T * queue)2331 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemRead(Vec v, PETSC_UINTPTR_T *queue)
2332 {
2333 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2334 }
2335
VecViennaCLGetCLMemWrite(Vec v,PETSC_UINTPTR_T * queue)2336 PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemWrite(Vec v, PETSC_UINTPTR_T *queue)
2337 {
2338 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2339 }
2340
VecViennaCLRestoreCLMemWrite(Vec v)2341 PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
2342 {
2343 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
2344 }
2345 #endif
2346
VecErrorWeightedNorms_Basic(Vec U,Vec Y,Vec E,NormType wnormtype,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol,PetscReal ignore_max,PetscReal * norm,PetscInt * norm_loc,PetscReal * norma,PetscInt * norma_loc,PetscReal * normr,PetscInt * normr_loc)2347 static PetscErrorCode VecErrorWeightedNorms_Basic(Vec U, Vec Y, Vec E, NormType wnormtype, PetscReal atol, Vec vatol, PetscReal rtol, Vec vrtol, PetscReal ignore_max, PetscReal *norm, PetscInt *norm_loc, PetscReal *norma, PetscInt *norma_loc, PetscReal *normr, PetscInt *normr_loc)
2348 {
2349 const PetscScalar *u, *y;
2350 const PetscScalar *atola = NULL, *rtola = NULL, *erra = NULL;
2351 PetscInt n, n_loc = 0, na_loc = 0, nr_loc = 0;
2352 PetscReal nrm = 0, nrma = 0, nrmr = 0, err_loc[6];
2353
2354 PetscFunctionBegin;
2355 #define SkipSmallValue(a, b, tol) \
2356 if (PetscAbsScalar(a) < tol || PetscAbsScalar(b) < tol) continue
2357
2358 PetscCall(VecGetLocalSize(U, &n));
2359 PetscCall(VecGetArrayRead(U, &u));
2360 PetscCall(VecGetArrayRead(Y, &y));
2361 if (E) PetscCall(VecGetArrayRead(E, &erra));
2362 if (vatol) PetscCall(VecGetArrayRead(vatol, &atola));
2363 if (vrtol) PetscCall(VecGetArrayRead(vrtol, &rtola));
2364 for (PetscInt i = 0; i < n; i++) {
2365 PetscReal err, tol, tola, tolr;
2366
2367 SkipSmallValue(y[i], u[i], ignore_max);
2368 atol = atola ? PetscRealPart(atola[i]) : atol;
2369 rtol = rtola ? PetscRealPart(rtola[i]) : rtol;
2370 err = erra ? PetscAbsScalar(erra[i]) : PetscAbsScalar(y[i] - u[i]);
2371 tola = atol;
2372 tolr = rtol * PetscMax(PetscAbsScalar(u[i]), PetscAbsScalar(y[i]));
2373 tol = tola + tolr;
2374 if (tola > 0.) {
2375 if (wnormtype == NORM_INFINITY) nrma = PetscMax(nrma, err / tola);
2376 else nrma += PetscSqr(err / tola);
2377 na_loc++;
2378 }
2379 if (tolr > 0.) {
2380 if (wnormtype == NORM_INFINITY) nrmr = PetscMax(nrmr, err / tolr);
2381 else nrmr += PetscSqr(err / tolr);
2382 nr_loc++;
2383 }
2384 if (tol > 0.) {
2385 if (wnormtype == NORM_INFINITY) nrm = PetscMax(nrm, err / tol);
2386 else nrm += PetscSqr(err / tol);
2387 n_loc++;
2388 }
2389 }
2390 if (E) PetscCall(VecRestoreArrayRead(E, &erra));
2391 if (vatol) PetscCall(VecRestoreArrayRead(vatol, &atola));
2392 if (vrtol) PetscCall(VecRestoreArrayRead(vrtol, &rtola));
2393 PetscCall(VecRestoreArrayRead(U, &u));
2394 PetscCall(VecRestoreArrayRead(Y, &y));
2395 #undef SkipSmallValue
2396
2397 err_loc[0] = nrm;
2398 err_loc[1] = nrma;
2399 err_loc[2] = nrmr;
2400 err_loc[3] = (PetscReal)n_loc;
2401 err_loc[4] = (PetscReal)na_loc;
2402 err_loc[5] = (PetscReal)nr_loc;
2403 if (wnormtype == NORM_2) {
2404 PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc, 6, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)U)));
2405 } else {
2406 PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc, 3, MPIU_REAL, MPIU_MAX, PetscObjectComm((PetscObject)U)));
2407 PetscCallMPI(MPIU_Allreduce(MPI_IN_PLACE, err_loc + 3, 3, MPIU_REAL, MPIU_SUM, PetscObjectComm((PetscObject)U)));
2408 }
2409 if (wnormtype == NORM_2) {
2410 *norm = PetscSqrtReal(err_loc[0]);
2411 *norma = PetscSqrtReal(err_loc[1]);
2412 *normr = PetscSqrtReal(err_loc[2]);
2413 } else {
2414 *norm = err_loc[0];
2415 *norma = err_loc[1];
2416 *normr = err_loc[2];
2417 }
2418 *norm_loc = (PetscInt)err_loc[3];
2419 *norma_loc = (PetscInt)err_loc[4];
2420 *normr_loc = (PetscInt)err_loc[5];
2421 PetscFunctionReturn(PETSC_SUCCESS);
2422 }
2423
2424 /*@
2425 VecErrorWeightedNorms - compute a weighted norm of the difference between two vectors
2426
2427 Collective
2428
2429 Input Parameters:
2430 + U - first vector to be compared
2431 . Y - second vector to be compared
2432 . E - optional third vector representing the error (if not provided, the error is ||U-Y||)
2433 . wnormtype - norm type
2434 . atol - scalar for absolute tolerance
2435 . vatol - vector representing per-entry absolute tolerances (can be ``NULL``)
2436 . rtol - scalar for relative tolerance
2437 . vrtol - vector representing per-entry relative tolerances (can be ``NULL``)
2438 - ignore_max - ignore values smaller than this value in absolute terms.
2439
2440 Output Parameters:
2441 + norm - weighted norm
2442 . norm_loc - number of vector locations used for the weighted norm
2443 . norma - weighted norm based on the absolute tolerance
2444 . norma_loc - number of vector locations used for the absolute weighted norm
2445 . normr - weighted norm based on the relative tolerance
2446 - normr_loc - number of vector locations used for the relative weighted norm
2447
2448 Level: developer
2449
2450 Notes:
2451 This is primarily used for computing weighted local truncation errors in ``TS``.
2452
2453 .seealso: [](ch_vectors), `Vec`, `NormType`, `TSErrorWeightedNorm()`, `TSErrorWeightedENorm()`
2454 @*/
VecErrorWeightedNorms(Vec U,Vec Y,Vec E,NormType wnormtype,PetscReal atol,Vec vatol,PetscReal rtol,Vec vrtol,PetscReal ignore_max,PetscReal * norm,PetscInt * norm_loc,PetscReal * norma,PetscInt * norma_loc,PetscReal * normr,PetscInt * normr_loc)2455 PetscErrorCode VecErrorWeightedNorms(Vec U, Vec Y, Vec E, NormType wnormtype, PetscReal atol, Vec vatol, PetscReal rtol, Vec vrtol, PetscReal ignore_max, PetscReal *norm, PetscInt *norm_loc, PetscReal *norma, PetscInt *norma_loc, PetscReal *normr, PetscInt *normr_loc)
2456 {
2457 PetscFunctionBegin;
2458 PetscValidHeaderSpecific(U, VEC_CLASSID, 1);
2459 PetscValidType(U, 1);
2460 PetscValidHeaderSpecific(Y, VEC_CLASSID, 2);
2461 PetscValidType(Y, 2);
2462 if (E) {
2463 PetscValidHeaderSpecific(E, VEC_CLASSID, 3);
2464 PetscValidType(E, 3);
2465 }
2466 PetscValidLogicalCollectiveEnum(U, wnormtype, 4);
2467 PetscValidLogicalCollectiveReal(U, atol, 5);
2468 if (vatol) {
2469 PetscValidHeaderSpecific(vatol, VEC_CLASSID, 6);
2470 PetscValidType(vatol, 6);
2471 }
2472 PetscValidLogicalCollectiveReal(U, rtol, 7);
2473 if (vrtol) {
2474 PetscValidHeaderSpecific(vrtol, VEC_CLASSID, 8);
2475 PetscValidType(vrtol, 8);
2476 }
2477 PetscValidLogicalCollectiveReal(U, ignore_max, 9);
2478 PetscAssertPointer(norm, 10);
2479 PetscAssertPointer(norm_loc, 11);
2480 PetscAssertPointer(norma, 12);
2481 PetscAssertPointer(norma_loc, 13);
2482 PetscAssertPointer(normr, 14);
2483 PetscAssertPointer(normr_loc, 15);
2484 PetscCheck(wnormtype == NORM_2 || wnormtype == NORM_INFINITY, PetscObjectComm((PetscObject)U), PETSC_ERR_SUP, "No support for norm type %s", NormTypes[wnormtype]);
2485
2486 /* There are potentially 5 vectors involved, some of them may happen to be of different type or bound to cpu.
2487 Here we check that they all implement the same operation and call it if so.
2488 Otherwise, we call the _Basic implementation that always works (provided VecGetArrayRead is implemented). */
2489 PetscBool sameop = (PetscBool)(U->ops->errorwnorm && U->ops->errorwnorm == Y->ops->errorwnorm);
2490 if (sameop && E) sameop = (PetscBool)(U->ops->errorwnorm == E->ops->errorwnorm);
2491 if (sameop && vatol) sameop = (PetscBool)(U->ops->errorwnorm == vatol->ops->errorwnorm);
2492 if (sameop && vrtol) sameop = (PetscBool)(U->ops->errorwnorm == vrtol->ops->errorwnorm);
2493 if (sameop) PetscUseTypeMethod(U, errorwnorm, Y, E, wnormtype, atol, vatol, rtol, vrtol, ignore_max, norm, norm_loc, norma, norma_loc, normr, normr_loc);
2494 else PetscCall(VecErrorWeightedNorms_Basic(U, Y, E, wnormtype, atol, vatol, rtol, vrtol, ignore_max, norm, norm_loc, norma, norma_loc, normr, normr_loc));
2495 PetscFunctionReturn(PETSC_SUCCESS);
2496 }
2497