Actual source code: vector.c
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>
6: #include <petsc/private/deviceimpl.h>
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_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_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;
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
24: Not collective
26: Input Parameter:
27: . vec - the vector
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()`)
35: Level: advanced
37: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `Vec`, `VecStashSetInitialSize()`, `VecStashView()`
38: @*/
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: }
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.
52: Logically Collective
54: Input Parameters:
55: + x - vector
56: - mapping - mapping created with `ISLocalToGlobalMappingCreate()` or `ISLocalToGlobalMappingCreateIS()`
58: Level: intermediate
60: Notes:
61: All vectors obtained with `VecDuplicate()` from this vector inherit the same mapping.
63: Vectors obtained with `DMCreateGlobaVector()` will often have this attribute attached to the vector so this call is not needed
65: seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesLocal()`,
66: `VecGetLocalToGlobalMapping()`, `VecSetValuesBlockedLocal()`
67: @*/
68: PetscErrorCode VecSetLocalToGlobalMapping(Vec x, ISLocalToGlobalMapping mapping)
69: {
70: PetscFunctionBegin;
73: if (x->ops->setlocaltoglobalmapping) PetscUseTypeMethod(x, setlocaltoglobalmapping, mapping);
74: else PetscCall(PetscLayoutSetISLocalToGlobalMapping(x->map, mapping));
75: PetscFunctionReturn(PETSC_SUCCESS);
76: }
78: /*@
79: VecGetLocalToGlobalMapping - Gets the local-to-global numbering set by `VecSetLocalToGlobalMapping()`
81: Not Collective
83: Input Parameter:
84: . X - the vector
86: Output Parameter:
87: . mapping - the mapping
89: Level: advanced
91: .seealso: [](chapter_vectors), `Vec`, `VecSetValuesLocal()`, `VecSetLocalToGlobalMapping()`
92: @*/
93: PetscErrorCode VecGetLocalToGlobalMapping(Vec X, ISLocalToGlobalMapping *mapping)
94: {
95: PetscFunctionBegin;
99: *mapping = X->map->mapping;
100: PetscFunctionReturn(PETSC_SUCCESS);
101: }
103: /*@
104: VecAssemblyBegin - Begins assembling the vector; that is ensuring all the vector's entries are stored on the correct MPI process. This routine should
105: be called after completing all calls to `VecSetValues()`.
107: Collective
109: Input Parameter:
110: . vec - the vector
112: Level: beginner
114: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyEnd()`, `VecSetValues()`
115: @*/
116: PetscErrorCode VecAssemblyBegin(Vec vec)
117: {
118: PetscFunctionBegin;
121: PetscCall(VecStashViewFromOptions(vec, NULL, "-vec_view_stash"));
122: PetscCall(PetscLogEventBegin(VEC_AssemblyBegin, vec, 0, 0, 0));
123: PetscTryTypeMethod(vec, assemblybegin);
124: PetscCall(PetscLogEventEnd(VEC_AssemblyBegin, vec, 0, 0, 0));
125: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
126: PetscFunctionReturn(PETSC_SUCCESS);
127: }
129: /*@
130: VecAssemblyEnd - Completes assembling the vector. This routine should be called after `VecAssemblyBegin()`.
132: Collective
134: Input Parameter:
135: . vec - the vector
137: Options Database Keys:
138: + -vec_view - Prints vector in `PETSC_VIEWER_DEFAULT` format
139: . -vec_view ::ascii_matlab - Prints vector in `PETSC_VIEWER_ASCII_MATLAB` format to stdout
140: . -vec_view matlab:filename - Prints vector in MATLAB .mat file to filename (requires PETSc configured with --with-matlab)
141: . -vec_view draw - Activates vector viewing using drawing tools
142: . -display <name> - Sets display name (default is host)
143: . -draw_pause <sec> - Sets number of seconds to pause after display
144: - -vec_view socket - Activates vector viewing using a socket
146: Level: beginner
148: .seealso: [](chapter_vectors), `Vec`, `VecAssemblyBegin()`, `VecSetValues()`
149: @*/
150: PetscErrorCode VecAssemblyEnd(Vec vec)
151: {
152: PetscFunctionBegin;
154: PetscCall(PetscLogEventBegin(VEC_AssemblyEnd, vec, 0, 0, 0));
156: PetscTryTypeMethod(vec, assemblyend);
157: PetscCall(PetscLogEventEnd(VEC_AssemblyEnd, vec, 0, 0, 0));
158: PetscCall(VecViewFromOptions(vec, NULL, "-vec_view"));
159: PetscFunctionReturn(PETSC_SUCCESS);
160: }
162: /*@
163: VecSetPreallocationCOO - set preallocation for a vector using a coordinate format of the entries with global indices
165: Collective
167: Input Parameters:
168: + x - vector being preallocated
169: . ncoo - number of entries
170: - coo_i - entry indices
172: Level: beginner
174: Notes:
175: This and `VecSetValuesCOO()` provide an alernative API to using `VecSetValues()` to provide vector values.
177: This API is particularly efficient for use on GPUs.
179: Entries can be repeated, see `VecSetValuesCOO()`. Negative indices are not allowed unless vector option `VEC_IGNORE_NEGATIVE_INDICES` is set,
180: in which case they, along with the corresponding entries in `VecSetValuesCOO()`, are ignored. If vector option `VEC_NO_OFF_PROC_ENTRIES` is set,
181: remote entries are ignored, otherwise, they will be properly added or inserted to the vector.
183: The array coo_i[] may be freed immediately after calling this function.
185: .seealso: [](chapter_vectors), `Vec`, VecSetValuesCOO(), VecSetPreallocationCOOLocal()
186: @*/
187: PetscErrorCode VecSetPreallocationCOO(Vec x, PetscCount ncoo, const PetscInt coo_i[])
188: {
189: PetscFunctionBegin;
193: PetscCall(PetscLogEventBegin(VEC_SetPreallocateCOO, x, 0, 0, 0));
194: PetscCall(PetscLayoutSetUp(x->map));
195: if (x->ops->setpreallocationcoo) {
196: PetscUseTypeMethod(x, setpreallocationcoo, ncoo, coo_i);
197: } else {
198: IS is_coo_i;
199: /* The default implementation only supports ncoo within limit of PetscInt */
200: PetscCheck(ncoo <= PETSC_MAX_INT, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo);
201: PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_i, PETSC_COPY_VALUES, &is_coo_i));
202: PetscCall(PetscObjectCompose((PetscObject)x, "__PETSc_coo_i", (PetscObject)is_coo_i));
203: PetscCall(ISDestroy(&is_coo_i));
204: }
205: PetscCall(PetscLogEventEnd(VEC_SetPreallocateCOO, x, 0, 0, 0));
206: PetscFunctionReturn(PETSC_SUCCESS);
207: }
209: /*@
210: VecSetPreallocationCOOLocal - set preallocation for vectors using a coordinate format of the entries with local indices
212: Collective
214: Input Parameters:
215: + x - vector being preallocated
216: . ncoo - number of entries
217: - coo_i - row indices (local numbering; may be modified)
219: Level: beginner
221: Notes:
222: This and `VecSetValuesCOO()` provide an alernative API to using `VecSetValuesLocal()` to provide vector values.
224: This API is particularly efficient for use on GPUs.
226: The local indices are translated using the local to global mapping, thus `VecSetLocalToGlobalMapping()` must have been
227: called prior to this function.
229: The indices coo_i may be modified within this function. They might be translated to corresponding global
230: indices, but the caller should not rely on them having any specific value after this function returns. The arrays
231: can be freed or reused immediately after this function returns.
233: Entries can be repeated. Negative indices and remote indices might be allowed. see `VecSetPreallocationCOO()`.
235: .seealso: [](chapter_vectors), `Vec`, VecSetPreallocationCOO(), VecSetValuesCOO()
236: @*/
237: PetscErrorCode VecSetPreallocationCOOLocal(Vec x, PetscCount ncoo, PetscInt coo_i[])
238: {
239: ISLocalToGlobalMapping ltog;
241: PetscFunctionBegin;
245: PetscCheck(ncoo <= PETSC_MAX_INT, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo);
246: PetscCall(PetscLayoutSetUp(x->map));
247: PetscCall(VecGetLocalToGlobalMapping(x, <og));
248: if (ltog) PetscCall(ISLocalToGlobalMappingApply(ltog, ncoo, coo_i, coo_i));
249: PetscCall(VecSetPreallocationCOO(x, ncoo, coo_i));
250: PetscFunctionReturn(PETSC_SUCCESS);
251: }
253: /*@
254: VecSetValuesCOO - set values at once in a vector preallocated using `VecSetPreallocationCOO()`
256: Collective
258: Input Parameters:
259: + x - vector being set
260: . coo_v - the value array
261: - imode - the insert mode
263: Level: beginner
265: Note:
266: This and `VecSetPreallocationCOO() or ``VecSetPreallocationCOOLocal()` provide an alernative API to using `VecSetValues()` to provide vector values.
268: This API is particularly efficient for use on GPUs.
270: The values must follow the order of the indices prescribed with `VecSetPreallocationCOO()` or `VecSetPreallocationCOOLocal()`.
271: When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of `imode`.
272: The imode flag indicates if `coo_v` must be added to the current values of the vector (`ADD_VALUES`) or overwritten (`INSERT_VALUES`).
273: `VecAssemblyBegin()` and `VecAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process.
275: .seealso: [](chapter_vectors), `Vec`, VecSetPreallocationCOO(), VecSetPreallocationCOOLocal(), VecSetValues()
276: @*/
277: PetscErrorCode VecSetValuesCOO(Vec x, const PetscScalar coo_v[], InsertMode imode)
278: {
279: PetscFunctionBegin;
283: PetscCall(PetscLogEventBegin(VEC_SetValuesCOO, x, 0, 0, 0));
284: if (x->ops->setvaluescoo) {
285: PetscUseTypeMethod(x, setvaluescoo, coo_v, imode);
286: PetscCall(PetscObjectStateIncrease((PetscObject)x));
287: } else {
288: IS is_coo_i;
289: const PetscInt *coo_i;
290: PetscInt ncoo;
291: PetscMemType mtype;
293: PetscCall(PetscGetMemType(coo_v, &mtype));
294: PetscCheck(mtype == PETSC_MEMTYPE_HOST, PetscObjectComm((PetscObject)x), PETSC_ERR_ARG_WRONG, "The basic VecSetValuesCOO() only supports v[] on host");
295: PetscCall(PetscObjectQuery((PetscObject)x, "__PETSc_coo_i", (PetscObject *)&is_coo_i));
296: PetscCheck(is_coo_i, PetscObjectComm((PetscObject)x), PETSC_ERR_COR, "Missing coo_i IS");
297: PetscCall(ISGetLocalSize(is_coo_i, &ncoo));
298: PetscCall(ISGetIndices(is_coo_i, &coo_i));
299: if (imode != ADD_VALUES) PetscCall(VecZeroEntries(x));
300: PetscCall(VecSetValues(x, ncoo, coo_i, coo_v, ADD_VALUES));
301: PetscCall(ISRestoreIndices(is_coo_i, &coo_i));
302: PetscCall(VecAssemblyBegin(x));
303: PetscCall(VecAssemblyEnd(x));
304: }
305: PetscCall(PetscLogEventEnd(VEC_SetValuesCOO, x, 0, 0, 0));
306: PetscFunctionReturn(PETSC_SUCCESS);
307: }
309: static PetscErrorCode VecPointwiseApply_Private(Vec w, Vec x, Vec y, PetscLogEvent event, PetscErrorCode (*const pointwise_op)(Vec, Vec, Vec))
310: {
311: PetscFunctionBegin;
318: PetscCheckSameTypeAndComm(x, 2, y, 3);
319: PetscCheckSameTypeAndComm(y, 3, w, 1);
320: VecCheckSameSize(w, 1, x, 2);
321: VecCheckSameSize(w, 1, y, 3);
322: VecCheckAssembled(x);
323: VecCheckAssembled(y);
324: PetscCall(VecSetErrorIfLocked(w, 1));
327: if (event) PetscCall(PetscLogEventBegin(event, x, y, w, 0));
328: PetscCall((*pointwise_op)(w, x, y));
329: if (event) PetscCall(PetscLogEventEnd(event, x, y, w, 0));
330: PetscCall(PetscObjectStateIncrease((PetscObject)w));
331: PetscFunctionReturn(PETSC_SUCCESS);
332: }
334: /*@
335: VecPointwiseMax - Computes the component-wise maximum `w[i] = max(x[i], y[i])`.
337: Logically Collective
339: Input Parameters:
340: + x - the first input vector
341: - y - the second input vector
343: Output Parameter:
344: . w - the result
346: Level: advanced
348: Notes:
349: Any subset of the `x`, `y`, and `w` may be the same vector.
351: For complex numbers compares only the real part
353: .seealso: [](chapter_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
354: @*/
355: PetscErrorCode VecPointwiseMax(Vec w, Vec x, Vec y)
356: {
357: PetscFunctionBegin;
359: // REVIEW ME: no log event?
360: PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisemax));
361: PetscFunctionReturn(PETSC_SUCCESS);
362: }
364: /*@
365: VecPointwiseMin - Computes the component-wise minimum `w[i] = min(x[i], y[i])`.
367: Logically Collective
369: Input Parameters:
370: + x - the first input vector
371: - y - the second input vector
373: Output Parameter:
374: . w - the result
376: Level: advanced
378: Notes:
379: Any subset of the `x`, `y`, and `w` may be the same vector.
381: For complex numbers compares only the real part
383: .seealso: [](chapter_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
384: @*/
385: PetscErrorCode VecPointwiseMin(Vec w, Vec x, Vec y)
386: {
387: PetscFunctionBegin;
389: VecCheckAssembled(x);
390: // REVIEW ME: no log event?
391: PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisemin));
392: PetscFunctionReturn(PETSC_SUCCESS);
393: }
395: /*@
396: VecPointwiseMaxAbs - Computes the component-wise maximum of the absolute values `w[i] = max(abs(x[i]), abs(y[i]))`.
398: Logically Collective
400: Input Parameters:
401: + x - the first input vector
402: - y - the second input vector
404: Output Parameter:
405: . w - the result
407: Level: advanced
409: Notes:
410: Any subset of the `x`, `y`, and `w` may be the same vector.
412: .seealso: [](chapter_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMin()`, `VecPointwiseMax()`, `VecMaxPointwiseDivide()`
413: @*/
414: PetscErrorCode VecPointwiseMaxAbs(Vec w, Vec x, Vec y)
415: {
416: PetscFunctionBegin;
418: // REVIEW ME: no log event?
419: PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisemaxabs));
420: PetscFunctionReturn(PETSC_SUCCESS);
421: }
423: /*@
424: VecPointwiseDivide - Computes the component-wise division `w[i] = x[i] / y[i]`.
426: Logically Collective
428: Input Parameters:
429: + x - the numerator vector
430: - y - the denominator vector
432: Output Parameter:
433: . w - the result
435: Level: advanced
437: Note:
438: Any subset of the `x`, `y`, and `w` may be the same vector.
440: .seealso: [](chapter_vectors), `Vec`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
441: @*/
442: PetscErrorCode VecPointwiseDivide(Vec w, Vec x, Vec y)
443: {
444: PetscFunctionBegin;
446: // REVIEW ME: no log event?
447: PetscCall(VecPointwiseApply_Private(w, x, y, 0, w->ops->pointwisedivide));
448: PetscFunctionReturn(PETSC_SUCCESS);
449: }
451: /*@
452: VecPointwiseMult - Computes the component-wise multiplication `w[i] = x[i] * y[i]`.
454: Logically Collective
456: Input Parameters:
457: . x, y - the vectors
459: Output Parameter:
460: . w - the result
462: Level: advanced
464: Note:
465: Any subset of the `x`, `y`, and `w` may be the same vector.
467: .seealso: [](chapter_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
468: @*/
469: PetscErrorCode VecPointwiseMult(Vec w, Vec x, Vec y)
470: {
471: PetscFunctionBegin;
473: PetscCall(VecPointwiseApply_Private(w, x, y, VEC_PointwiseMult, w->ops->pointwisemult));
474: PetscFunctionReturn(PETSC_SUCCESS);
475: }
477: /*@
478: VecDuplicate - Creates a new vector of the same type as an existing vector.
480: Collective
482: Input Parameters:
483: . v - a vector to mimic
485: Output Parameter:
486: . newv - location to put new vector
488: Level: beginner
490: Notes:
491: VecDuplicate() DOES NOT COPY the vector entries, but rather allocates storage
492: for the new vector. Use `VecCopy()` to copy a vector.
494: Use `VecDestroy()` to free the space. Use `VecDuplicateVecs()` to get several
495: vectors.
497: .seealso: [](chapter_vectors), `Vec`, `VecDestroy()`, `VecDuplicateVecs()`, `VecCreate()`, `VecCopy()`
498: @*/
499: PetscErrorCode VecDuplicate(Vec v, Vec *newv)
500: {
501: PetscFunctionBegin;
505: PetscUseTypeMethod(v, duplicate, newv);
506: #if PetscDefined(HAVE_DEVICE)
507: if (v->boundtocpu && v->bindingpropagates) {
508: PetscCall(VecSetBindingPropagates(*newv, PETSC_TRUE));
509: PetscCall(VecBindToCPU(*newv, PETSC_TRUE));
510: }
511: #endif
512: PetscCall(PetscObjectStateIncrease((PetscObject)(*newv)));
513: PetscFunctionReturn(PETSC_SUCCESS);
514: }
516: /*@C
517: VecDestroy - Destroys a vector.
519: Collective
521: Input Parameters:
522: . v - the vector
524: Level: beginner
526: .seealso: [](chapter_vectors), `Vec`, `VecCreate()`, `VecDuplicate()`, `VecDestroyVecs()`
527: @*/
528: PetscErrorCode VecDestroy(Vec *v)
529: {
530: PetscFunctionBegin;
532: if (!*v) PetscFunctionReturn(PETSC_SUCCESS);
534: if (--((PetscObject)(*v))->refct > 0) {
535: *v = NULL;
536: PetscFunctionReturn(PETSC_SUCCESS);
537: }
539: PetscCall(PetscObjectSAWsViewOff((PetscObject)*v));
540: /* destroy the internal part */
541: PetscTryTypeMethod(*v, destroy);
542: PetscCall(PetscFree((*v)->defaultrandtype));
543: /* destroy the external/common part */
544: PetscCall(PetscLayoutDestroy(&(*v)->map));
545: PetscCall(PetscHeaderDestroy(v));
546: PetscFunctionReturn(PETSC_SUCCESS);
547: }
549: /*@C
550: VecDuplicateVecs - Creates several vectors of the same type as an existing vector.
552: Collective
554: Input Parameters:
555: + m - the number of vectors to obtain
556: - v - a vector to mimic
558: Output Parameter:
559: . V - location to put pointer to array of vectors
561: Level: intermediate
563: Note:
564: Use `VecDestroyVecs()` to free the space. Use `VecDuplicate()` to form a single
565: vector.
567: Fortran Note:
568: The Fortran interface is slightly different from that given below, it
569: requires one to pass in `V` a `Vec` array of size at least `m`.
570: See the [](chapter_fortran) for details.
572: .seealso: [](chapter_vectors), `Vec`, [](chapter_fortran), `VecDestroyVecs()`, `VecDuplicate()`, `VecCreate()`, `VecDuplicateVecsF90()`
573: @*/
574: PetscErrorCode VecDuplicateVecs(Vec v, PetscInt m, Vec *V[])
575: {
576: PetscFunctionBegin;
580: PetscUseTypeMethod(v, duplicatevecs, m, V);
581: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
582: if (v->boundtocpu && v->bindingpropagates) {
583: PetscInt i;
585: for (i = 0; i < m; i++) {
586: /* Since ops->duplicatevecs might itself propagate the value of boundtocpu,
587: * avoid unnecessary overhead by only calling VecBindToCPU() if the vector isn't already bound. */
588: if (!(*V)[i]->boundtocpu) {
589: PetscCall(VecSetBindingPropagates((*V)[i], PETSC_TRUE));
590: PetscCall(VecBindToCPU((*V)[i], PETSC_TRUE));
591: }
592: }
593: }
594: #endif
595: PetscFunctionReturn(PETSC_SUCCESS);
596: }
598: /*@C
599: VecDestroyVecs - Frees a block of vectors obtained with `VecDuplicateVecs()`.
601: Collective
603: Input Parameters:
604: + m - the number of vectors previously obtained, if zero no vectors are destroyed
605: - vv - pointer to pointer to array of vector pointers, if `NULL` no vectors are destroyed
607: Level: intermediate
609: Fortran Note:
610: The Fortran interface is slightly different from that given below.
611: See the [](chapter_fortran) for details.
613: .seealso: [](chapter_vectors), `Vec`, [](chapter_fortran), `VecDuplicateVecs()`, `VecDestroyVecsf90()`
614: @*/
615: PetscErrorCode VecDestroyVecs(PetscInt m, Vec *vv[])
616: {
617: PetscFunctionBegin;
619: PetscCheck(m >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of vectors %" PetscInt_FMT, m);
620: if (!m || !*vv) {
621: *vv = NULL;
622: PetscFunctionReturn(PETSC_SUCCESS);
623: }
626: PetscCall((*(**vv)->ops->destroyvecs)(m, *vv));
627: *vv = NULL;
628: PetscFunctionReturn(PETSC_SUCCESS);
629: }
631: /*@C
632: VecViewFromOptions - View a vector based on values in the options database
634: Collective
636: Input Parameters:
637: + A - the vector
638: . obj - Optional object that provides the options prefix for this viewing
639: - name - command line option
641: Level: intermediate
643: Note:
644: See `PetscObjectViewFromOptions()` to see the `PetscViewer` and PetscViewerFormat` available
646: .seealso: [](chapter_vectors), `Vec`, `VecView`, `PetscObjectViewFromOptions()`, `VecCreate()`
647: @*/
648: PetscErrorCode VecViewFromOptions(Vec A, PetscObject obj, const char name[])
649: {
650: PetscFunctionBegin;
652: PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
653: PetscFunctionReturn(PETSC_SUCCESS);
654: }
656: /*@C
657: VecView - Views a vector object.
659: Collective
661: Input Parameters:
662: + vec - the vector
663: - viewer - an optional `PetscViewer` visualization context
665: Level: beginner
667: Notes:
668: The available visualization contexts include
669: + `PETSC_VIEWER_STDOUT_SELF` - for sequential vectors
670: . `PETSC_VIEWER_STDOUT_WORLD` - for parallel vectors created on `PETSC_COMM_WORLD`
671: - `PETSC_VIEWER_STDOUT`_(comm) - for parallel vectors created on MPI communicator comm
673: You can change the format the vector is printed using the
674: option `PetscViewerPushFormat()`.
676: The user can open alternative viewers with
677: + `PetscViewerASCIIOpen()` - Outputs vector to a specified file
678: . `PetscViewerBinaryOpen()` - Outputs vector in binary to a
679: specified file; corresponding input uses `VecLoad()`
680: . `PetscViewerDrawOpen()` - Outputs vector to an X window display
681: . `PetscViewerSocketOpen()` - Outputs vector to Socket viewer
682: - `PetscViewerHDF5Open()` - Outputs vector to HDF5 file viewer
684: The user can call `PetscViewerPushFormat()` to specify the output
685: format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`,
686: `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include
687: + `PETSC_VIEWER_DEFAULT` - default, prints vector contents
688: . `PETSC_VIEWER_ASCII_MATLAB` - prints vector contents in MATLAB format
689: . `PETSC_VIEWER_ASCII_INDEX` - prints vector contents, including indices of vector elements
690: - `PETSC_VIEWER_ASCII_COMMON` - prints vector contents, using a
691: format common among all vector types
693: You can pass any number of vector objects, or other PETSc objects to the same viewer.
695: In the debugger you can do call `VecView`(v,0) to display the vector. (The same holds for any PETSc object viewer).
697: Notes for binary viewer:
698: If you pass multiple vectors to a binary viewer you can read them back in in the same order
699: with `VecLoad()`.
701: If the blocksize of the vector is greater than one then you must provide a unique prefix to
702: the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
703: vector to be stored and then set that same unique prefix on the vector that you pass to `VecLoad()`. The blocksize
704: information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
705: filename. If you copy the binary file, make sure you copy the associated .info file with it.
707: See the manual page for `VecLoad()` on the exact format the binary viewer stores
708: the values in the file.
710: Notes for HDF5 Viewer:
711: The name of the `Vec` (given with `PetscObjectSetName()` is the name that is used
712: for the object in the HDF5 file. If you wish to store the same Vec into multiple
713: datasets in the same file (typically with different values), you must change its
714: name each time before calling the `VecView()`. To load the same vector,
715: the name of the Vec object passed to `VecLoad()` must be the same.
717: If the block size of the vector is greater than 1 then it is used as the first dimension in the HDF5 array.
718: If the function `PetscViewerHDF5SetBaseDimension2()`is called then even if the block size is one it will
719: be used as the first dimension in the HDF5 array (that is the HDF5 array will always be two dimensional)
720: See also `PetscViewerHDF5SetTimestep()` which adds an additional complication to reading and writing `Vec`
721: with the HDF5 viewer.
723: .seealso: [](chapter_vectors), `Vec`, `VecViewFromOptions()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`,
724: `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
725: `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
726: @*/
727: PetscErrorCode VecView(Vec vec, PetscViewer viewer)
728: {
729: PetscBool iascii;
730: PetscViewerFormat format;
731: PetscMPIInt size;
733: PetscFunctionBegin;
736: VecCheckAssembled(vec);
737: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
739: PetscCall(PetscViewerGetFormat(viewer, &format));
740: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
741: if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS);
743: PetscCheck(!vec->stash.n && !vec->bstash.n, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call VecAssemblyBegin/End() before viewing this vector");
745: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
746: if (iascii) {
747: PetscInt rows, bs;
749: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)vec, viewer));
750: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
751: PetscCall(PetscViewerASCIIPushTab(viewer));
752: PetscCall(VecGetSize(vec, &rows));
753: PetscCall(VecGetBlockSize(vec, &bs));
754: if (bs != 1) {
755: PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, bs));
756: } else {
757: PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT "\n", rows));
758: }
759: PetscCall(PetscViewerASCIIPopTab(viewer));
760: }
761: }
762: PetscCall(VecLockReadPush(vec));
763: PetscCall(PetscLogEventBegin(VEC_View, vec, viewer, 0, 0));
764: if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
765: PetscUseTypeMethod(vec, viewnative, viewer);
766: } else {
767: PetscUseTypeMethod(vec, view, viewer);
768: }
769: PetscCall(VecLockReadPop(vec));
770: PetscCall(PetscLogEventEnd(VEC_View, vec, viewer, 0, 0));
771: PetscFunctionReturn(PETSC_SUCCESS);
772: }
774: #if defined(PETSC_USE_DEBUG)
775: #include <../src/sys/totalview/tv_data_display.h>
776: PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
777: {
778: const PetscScalar *values;
779: char type[32];
781: TV_add_row("Local rows", "int", &v->map->n);
782: TV_add_row("Global rows", "int", &v->map->N);
783: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
784: PetscCall(VecGetArrayRead((Vec)v, &values));
785: PetscCall(PetscSNPrintf(type, 32, "double[%" PetscInt_FMT "]", v->map->n));
786: TV_add_row("values", type, values);
787: PetscCall(VecRestoreArrayRead((Vec)v, &values));
788: return TV_format_OK;
789: }
790: #endif
792: /*@C
793: VecViewNative - Views a vector object with the original type specific viewer
795: Collective
797: Input Parameters:
798: + vec - the vector
799: - viewer - an optional `PetscViewer` visualization context
801: Level: developer
803: Note:
804: This can be used with, for example, vectors obtained with `DMCreateGlobalVector()` for a `DMDA` to display the vector
805: in the PETSc storage format (each MPI process values follow the previous MPI processes) instead of the "natural" grid
806: ordering.
808: .seealso: [](chapter_vectors), `Vec`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`, `VecView()`
809: `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
810: `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
811: @*/
812: PetscErrorCode VecViewNative(Vec vec, PetscViewer viewer)
813: {
814: PetscFunctionBegin;
817: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
819: PetscUseTypeMethod(vec, viewnative, viewer);
820: PetscFunctionReturn(PETSC_SUCCESS);
821: }
823: /*@
824: VecGetSize - Returns the global number of elements of the vector.
826: Not Collective
828: Input Parameter:
829: . x - the vector
831: Output Parameters:
832: . size - the global length of the vector
834: Level: beginner
836: .seealso: [](chapter_vectors), `Vec`, `VecGetLocalSize()`
837: @*/
838: PetscErrorCode VecGetSize(Vec x, PetscInt *size)
839: {
840: PetscFunctionBegin;
844: PetscUseTypeMethod(x, getsize, size);
845: PetscFunctionReturn(PETSC_SUCCESS);
846: }
848: /*@
849: VecGetLocalSize - Returns the number of elements of the vector stored
850: in local memory (that is on this MPI process)
852: Not Collective
854: Input Parameter:
855: . x - the vector
857: Output Parameter:
858: . size - the length of the local piece of the vector
860: Level: beginner
862: .seealso: [](chapter_vectors), `Vec`, `VecGetSize()`
863: @*/
864: PetscErrorCode VecGetLocalSize(Vec x, PetscInt *size)
865: {
866: PetscFunctionBegin;
870: PetscUseTypeMethod(x, getlocalsize, size);
871: PetscFunctionReturn(PETSC_SUCCESS);
872: }
874: /*@C
875: VecGetOwnershipRange - Returns the range of indices owned by
876: this process. The vector is laid out with the
877: first n1 elements on the first processor, next n2 elements on the
878: second, etc. For certain parallel layouts this range may not be
879: well defined.
881: Not Collective
883: Input Parameter:
884: . x - the vector
886: Output Parameters:
887: + low - the first local element, pass in `NULL` if not interested
888: - high - one more than the last local element, pass in `NULL` if not interested
890: Level: beginner
892: Note:
893: The high argument is one more than the last element stored locally.
895: Fortran Note:
896: `PETSC_NULL_INTEGER` should be used instead of NULL
898: .seealso: [](chapter_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRanges()`
899: @*/
900: PetscErrorCode VecGetOwnershipRange(Vec x, PetscInt *low, PetscInt *high)
901: {
902: PetscFunctionBegin;
907: if (low) *low = x->map->rstart;
908: if (high) *high = x->map->rend;
909: PetscFunctionReturn(PETSC_SUCCESS);
910: }
912: /*@C
913: VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
914: The vector is laid out with the
915: first n1 elements on the first processor, next n2 elements on the
916: second, etc. For certain parallel layouts this range may not be
917: well defined.
919: Not Collective
921: Input Parameter:
922: . x - the vector
924: Output Parameters:
925: . range - array of length size+1 with the start and end+1 for each process
927: Level: beginner
929: Notes:
930: The high argument is one more than the last element stored locally.
932: If the ranges are used after all vectors that share the ranges has been destroyed then the program will crash accessing ranges[].
934: Fortran Note:
935: You must PASS in an array of length size+1
937: .seealso: [](chapter_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRange()`
938: @*/
939: PetscErrorCode VecGetOwnershipRanges(Vec x, const PetscInt *ranges[])
940: {
941: PetscFunctionBegin;
944: PetscCall(PetscLayoutGetRanges(x->map, ranges));
945: PetscFunctionReturn(PETSC_SUCCESS);
946: }
948: /*@
949: VecSetOption - Sets an option for controlling a vector's behavior.
951: Collective
953: Input Parameters:
954: + x - the vector
955: . op - the option
956: - flag - turn the option on or off
958: Supported Options:
959: + `VEC_IGNORE_OFF_PROC_ENTRIES`, which causes `VecSetValues()` to ignore
960: entries destined to be stored on a separate processor. This can be used
961: to eliminate the global reduction in the `VecAssemblyBegin()` if you know
962: that you have only used `VecSetValues()` to set local elements
963: . `VEC_IGNORE_NEGATIVE_INDICES`, which means you can pass negative indices
964: in ix in calls to `VecSetValues()` or `VecGetValues()`. These rows are simply
965: ignored.
966: - `VEC_SUBSET_OFF_PROC_ENTRIES`, which causes `VecAssemblyBegin()` to assume that the off-process
967: entries will always be a subset (possibly equal) of the off-process entries set on the
968: first assembly which had a true `VEC_SUBSET_OFF_PROC_ENTRIES` and the vector has not
969: changed this flag afterwards. If this assembly is not such first assembly, then this
970: assembly can reuse the communication pattern setup in that first assembly, thus avoiding
971: a global reduction. Subsequent assemblies setting off-process values should use the same
972: InsertMode as the first assembly.
974: Level: intermediate
976: Developer Note:
977: The `InsertMode` restriction could be removed by packing the stash messages out of place.
979: .seealso: [](chapter_vectors), `Vec`, `VecSetValues()`
980: @*/
981: PetscErrorCode VecSetOption(Vec x, VecOption op, PetscBool flag)
982: {
983: PetscFunctionBegin;
986: PetscTryTypeMethod(x, setoption, op, flag);
987: PetscFunctionReturn(PETSC_SUCCESS);
988: }
990: /* Default routines for obtaining and releasing; */
991: /* may be used by any implementation */
992: PetscErrorCode VecDuplicateVecs_Default(Vec w, PetscInt m, Vec *V[])
993: {
994: PetscFunctionBegin;
997: PetscCheck(m > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "m must be > 0: m = %" PetscInt_FMT, m);
998: PetscCall(PetscMalloc1(m, V));
999: for (PetscInt i = 0; i < m; i++) PetscCall(VecDuplicate(w, *V + i));
1000: PetscFunctionReturn(PETSC_SUCCESS);
1001: }
1003: PetscErrorCode VecDestroyVecs_Default(PetscInt m, Vec v[])
1004: {
1005: PetscInt i;
1007: PetscFunctionBegin;
1009: for (i = 0; i < m; i++) PetscCall(VecDestroy(&v[i]));
1010: PetscCall(PetscFree(v));
1011: PetscFunctionReturn(PETSC_SUCCESS);
1012: }
1014: /*@
1015: VecResetArray - Resets a vector to use its default memory. Call this
1016: after the use of `VecPlaceArray()`.
1018: Not Collective
1020: Input Parameters:
1021: . vec - the vector
1023: Level: developer
1025: .seealso: [](chapter_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`
1026: @*/
1027: PetscErrorCode VecResetArray(Vec vec)
1028: {
1029: PetscFunctionBegin;
1032: PetscUseTypeMethod(vec, resetarray);
1033: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1034: PetscFunctionReturn(PETSC_SUCCESS);
1035: }
1037: /*@C
1038: VecLoad - Loads a vector that has been stored in binary or HDF5 format
1039: with `VecView()`.
1041: Collective
1043: Input Parameters:
1044: + vec - the newly loaded vector, this needs to have been created with `VecCreate()` or
1045: some related function before the call to `VecLoad()`.
1046: - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or
1047: HDF5 file viewer, obtained from `PetscViewerHDF5Open()`
1049: Level: intermediate
1051: Notes:
1052: Defaults to the standard `VECSEQ` or `VECMPI`, if you want some other type of `Vec` call `VecSetFromOptions()`
1053: before calling this.
1055: The input file must contain the full global vector, as
1056: written by the routine `VecView()`.
1058: If the type or size of `vec` is not set before a call to `VecLoad()`, PETSc
1059: sets the type and the local and global sizes based on the vector it is reading in. If type and/or
1060: sizes are already set, then the same are used.
1062: If using the binary viewer and the blocksize of the vector is greater than one then you must provide a unique prefix to
1063: the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
1064: vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
1065: information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
1066: filename. If you copy the binary file, make sure you copy the associated .info file with it.
1068: If using HDF5, you must assign the `Vec` the same name as was used in the Vec
1069: that was stored in the file using `PetscObjectSetName(). Otherwise you will
1070: get the error message: "Cannot H5DOpen2() with `Vec` name NAMEOFOBJECT".
1072: If the HDF5 file contains a two dimensional array the first dimension is treated as the block size
1073: in loading the vector. Hence, for example, using MATLAB notation h5create('vector.dat','/Test_Vec',[27 1]);
1074: will load a vector of size 27 and block size 27 thus resulting in all 27 entries being on the first process of
1075: vectors communicator and the rest of the processes having zero entries
1077: Notes for advanced users when using the binary viewer:
1078: Most users should not need to know the details of the binary storage
1079: format, since `VecLoad()` and `VecView()` completely hide these details.
1080: But for anyone who's interested, the standard binary vector storage
1081: format is
1082: .vb
1083: PetscInt VEC_FILE_CLASSID
1084: PetscInt number of rows
1085: PetscScalar *values of all entries
1086: .ve
1088: In addition, PETSc automatically uses byte swapping to work on all machines; the files
1089: are written ALWAYS using big-endian ordering. On small-endian machines the numbers
1090: are converted to the small-endian format when they are read in from the file.
1091: See PetscBinaryRead() and PetscBinaryWrite() to see how this may be done.
1093: .seealso: [](chapter_vectors), `Vec`, `PetscViewerBinaryOpen()`, `VecView()`, `MatLoad()`, `VecLoad()`
1094: @*/
1095: PetscErrorCode VecLoad(Vec vec, PetscViewer viewer)
1096: {
1097: PetscBool isbinary, ishdf5, isadios, isexodusii;
1098: PetscViewerFormat format;
1100: PetscFunctionBegin;
1103: PetscCheckSameComm(vec, 1, viewer, 2);
1104: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
1105: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1106: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERADIOS, &isadios));
1107: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWEREXODUSII, &isexodusii));
1108: PetscCheck(isbinary || ishdf5 || isadios || isexodusii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1110: PetscCall(VecSetErrorIfLocked(vec, 1));
1111: if (!((PetscObject)vec)->type_name && !vec->ops->create) PetscCall(VecSetType(vec, VECSTANDARD));
1112: PetscCall(PetscLogEventBegin(VEC_Load, viewer, 0, 0, 0));
1113: PetscCall(PetscViewerGetFormat(viewer, &format));
1114: if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
1115: PetscUseTypeMethod(vec, loadnative, viewer);
1116: } else {
1117: PetscUseTypeMethod(vec, load, viewer);
1118: }
1119: PetscCall(PetscLogEventEnd(VEC_Load, viewer, 0, 0, 0));
1120: PetscFunctionReturn(PETSC_SUCCESS);
1121: }
1123: /*@
1124: VecReciprocal - Replaces each component of a vector by its reciprocal.
1126: Logically Collective
1128: Input Parameter:
1129: . vec - the vector
1131: Output Parameter:
1132: . vec - the vector reciprocal
1134: Level: intermediate
1136: Note:
1137: Vector entries with value 0.0 are not changed
1139: .seealso: [](chapter_vectors), `Vec`, `VecLog()`, `VecExp()`, `VecSqrtAbs()`
1140: @*/
1141: PetscErrorCode VecReciprocal(Vec vec)
1142: {
1143: PetscFunctionBegin;
1146: VecCheckAssembled(vec);
1147: PetscCall(VecSetErrorIfLocked(vec, 1));
1148: PetscUseTypeMethod(vec, reciprocal);
1149: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1150: PetscFunctionReturn(PETSC_SUCCESS);
1151: }
1153: /*@C
1154: VecSetOperation - Allows the user to override a particular vector operation.
1156: Logically Collective; No Fortran Support
1158: Input Parameters:
1159: + vec - The vector to modify
1160: . op - The name of the operation
1161: - f - The function that provides the operation.
1163: Notes:
1164: `f` may be `NULL` to remove the operation from `vec`. Depending on the operation this may be
1165: allowed, however some always expect a valid function. In these cases an error will be raised
1166: when calling the interface routine in question.
1168: See `VecOperation` for an up-to-date list of override-able operations. The operations listed
1169: there have the form `VECOP_<OPERATION>`, where `<OPERATION>` is the suffix (in all capital
1170: letters) of the public interface routine (e.g., `VecView()` -> `VECOP_VIEW`).
1172: Overriding a particular `Vec`'s operation has no affect on any other `Vec`s past, present,
1173: or future. The user should also note that overriding a method is "destructive"; the previous
1174: method is not retained in any way.
1176: Level: advanced
1178: Example Usage:
1179: .vb
1180: // some new VecView() implementation, must have the same signature as the function it seeks
1181: // to replace
1182: PetscErrorCode UserVecView(Vec x, PetscViewer viewer)
1183: {
1184: PetscFunctionBeginUser;
1185: // ...
1186: PetscFunctionReturn(PETSC_SUCCESS);
1187: }
1189: // Create a VECMPI which has a pre-defined VecView() implementation
1190: VecCreateMPI(comm, n, N, &x);
1191: // Calls the VECMPI implementation for VecView()
1192: VecView(x, viewer);
1194: VecSetOperation(x, VECOP_VIEW, (void (*)(void))UserVecView);
1195: // Now calls UserVecView()
1196: VecView(x, viewer);
1197: .ve
1199: .seealso: [](chapter_vectors), `Vec`, `VecCreate()`, `MatShellSetOperation()`
1200: @*/
1201: PetscErrorCode VecSetOperation(Vec vec, VecOperation op, void (*f)(void))
1202: {
1203: PetscFunctionBegin;
1205: if (op == VECOP_VIEW && !vec->ops->viewnative) {
1206: vec->ops->viewnative = vec->ops->view;
1207: } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
1208: vec->ops->loadnative = vec->ops->load;
1209: }
1210: ((void (**)(void))vec->ops)[(int)op] = f;
1211: PetscFunctionReturn(PETSC_SUCCESS);
1212: }
1214: /*@
1215: VecStashSetInitialSize - sets the sizes of the vec-stash, that is
1216: used during the assembly process to store values that belong to
1217: other processors.
1219: Not Collective, different processes can have different size stashes
1221: Input Parameters:
1222: + vec - the vector
1223: . size - the initial size of the stash.
1224: - bsize - the initial size of the block-stash(if used).
1226: Options Database Keys:
1227: + -vecstash_initial_size <size> or <size0,size1,...sizep-1>
1228: - -vecstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
1230: Level: intermediate
1232: Notes:
1233: The block-stash is used for values set with `VecSetValuesBlocked()` while
1234: the stash is used for values set with `VecSetValues()`
1236: Run with the option -info and look for output of the form
1237: VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
1238: to determine the appropriate value, MM, to use for size and
1239: VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
1240: to determine the value, BMM to use for bsize
1242: PETSc attempts to smartly manage the stash size so there is little likelyhood setting a
1243: a specific value here will affect performance
1245: .seealso: [](chapter_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecStashView()`
1246: @*/
1247: PetscErrorCode VecStashSetInitialSize(Vec vec, PetscInt size, PetscInt bsize)
1248: {
1249: PetscFunctionBegin;
1251: PetscCall(VecStashSetInitialSize_Private(&vec->stash, size));
1252: PetscCall(VecStashSetInitialSize_Private(&vec->bstash, bsize));
1253: PetscFunctionReturn(PETSC_SUCCESS);
1254: }
1256: /*@
1257: VecConjugate - Conjugates a vector. That is, replace every entry in a vector with its complex conjugate
1259: Logically Collective
1261: Input Parameters:
1262: . x - the vector
1264: Level: intermediate
1266: .seealso: [](chapter_vectors), `Vec`, `VecSet()`
1267: @*/
1268: PetscErrorCode VecConjugate(Vec x)
1269: {
1270: PetscFunctionBegin;
1273: VecCheckAssembled(x);
1274: PetscCall(VecSetErrorIfLocked(x, 1));
1275: if (PetscDefined(USE_COMPLEX)) {
1276: PetscUseTypeMethod(x, conjugate);
1277: /* we need to copy norms here */
1278: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1279: }
1280: PetscFunctionReturn(PETSC_SUCCESS);
1281: }
1283: /*@
1284: VecSetRandom - Sets all components of a vector to random numbers.
1286: Logically Collective
1288: Input Parameters:
1289: + x - the vector
1290: - rctx - the random number context, formed by `PetscRandomCreate()`, or use `NULL` and it will create one internally.
1292: Output Parameter:
1293: . x - the vector
1295: Example of Usage:
1296: .vb
1297: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
1298: VecSetRandom(x,rctx);
1299: PetscRandomDestroy(&rctx);
1300: .ve
1302: Level: intermediate
1304: .seealso: [](chapter_vectors), `Vec`, `VecSet()`, `VecSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()`
1305: @*/
1306: PetscErrorCode VecSetRandom(Vec x, PetscRandom rctx)
1307: {
1308: PetscRandom randObj = NULL;
1310: PetscFunctionBegin;
1314: VecCheckAssembled(x);
1315: PetscCall(VecSetErrorIfLocked(x, 1));
1317: if (!rctx) {
1318: PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)x), &randObj));
1319: PetscCall(PetscRandomSetType(randObj, x->defaultrandtype));
1320: PetscCall(PetscRandomSetFromOptions(randObj));
1321: rctx = randObj;
1322: }
1324: PetscCall(PetscLogEventBegin(VEC_SetRandom, x, rctx, 0, 0));
1325: PetscUseTypeMethod(x, setrandom, rctx);
1326: PetscCall(PetscLogEventEnd(VEC_SetRandom, x, rctx, 0, 0));
1328: PetscCall(PetscRandomDestroy(&randObj));
1329: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1330: PetscFunctionReturn(PETSC_SUCCESS);
1331: }
1333: /*@
1334: VecZeroEntries - puts a `0.0` in each element of a vector
1336: Logically Collective
1338: Input Parameter:
1339: . vec - The vector
1341: Level: beginner
1343: .seealso: [](chapter_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`, `VecSet()`, `VecSetValues()`
1344: @*/
1345: PetscErrorCode VecZeroEntries(Vec vec)
1346: {
1347: PetscFunctionBegin;
1348: PetscCall(VecSet(vec, 0));
1349: PetscFunctionReturn(PETSC_SUCCESS);
1350: }
1352: /*
1353: VecSetTypeFromOptions_Private - Sets the type of vector from user options. Defaults to a PETSc sequential vector on one
1354: processor and a PETSc MPI vector on more than one processor.
1356: Collective
1358: Input Parameter:
1359: . vec - The vector
1361: Level: intermediate
1363: .seealso: [](chapter_vectors), `Vec`, `VecSetFromOptions()`, `VecSetType()`
1364: */
1365: static PetscErrorCode VecSetTypeFromOptions_Private(Vec vec, PetscOptionItems *PetscOptionsObject)
1366: {
1367: PetscBool opt;
1368: VecType defaultType;
1369: char typeName[256];
1370: PetscMPIInt size;
1372: PetscFunctionBegin;
1373: if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
1374: else {
1375: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
1376: if (size > 1) defaultType = VECMPI;
1377: else defaultType = VECSEQ;
1378: }
1380: PetscCall(VecRegisterAll());
1381: PetscCall(PetscOptionsFList("-vec_type", "Vector type", "VecSetType", VecList, defaultType, typeName, 256, &opt));
1382: if (opt) {
1383: PetscCall(VecSetType(vec, typeName));
1384: } else {
1385: PetscCall(VecSetType(vec, defaultType));
1386: }
1387: PetscFunctionReturn(PETSC_SUCCESS);
1388: }
1390: /*@
1391: VecSetFromOptions - Configures the vector from the options database.
1393: Collective
1395: Input Parameter:
1396: . vec - The vector
1398: Level: beginner
1400: Notes:
1401: To see all options, run your program with the -help option.
1403: Must be called after `VecCreate()` but before the vector is used.
1405: .seealso: [](chapter_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`
1406: @*/
1407: PetscErrorCode VecSetFromOptions(Vec vec)
1408: {
1409: PetscBool flg;
1410: PetscInt bind_below = 0;
1412: PetscFunctionBegin;
1415: PetscObjectOptionsBegin((PetscObject)vec);
1416: /* Handle vector type options */
1417: PetscCall(VecSetTypeFromOptions_Private(vec, PetscOptionsObject));
1419: /* Handle specific vector options */
1420: PetscTryTypeMethod(vec, setfromoptions, PetscOptionsObject);
1422: /* Bind to CPU if below a user-specified size threshold.
1423: * This perhaps belongs in the options for the GPU Vec types, but VecBindToCPU() does nothing when called on non-GPU types,
1424: * and putting it here makes is more maintainable than duplicating this for all. */
1425: 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));
1426: if (flg && vec->map->n < bind_below) PetscCall(VecBindToCPU(vec, PETSC_TRUE));
1428: /* process any options handlers added with PetscObjectAddOptionsHandler() */
1429: PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)vec, PetscOptionsObject));
1430: PetscOptionsEnd();
1431: PetscFunctionReturn(PETSC_SUCCESS);
1432: }
1434: /*@
1435: VecSetSizes - Sets the local and global sizes, and checks to determine compatibility of the sizes
1437: Collective
1439: Input Parameters:
1440: + v - the vector
1441: . n - the local size (or `PETSC_DECIDE` to have it set)
1442: - N - the global size (or `PETSC_DETERMINE` to have it set)
1444: Level: intermediate
1446: Notes:
1447: `N` cannot be `PETSC_DETERMINE` if `n` is `PETSC_DECIDE`
1449: If one processor calls this with `N` of `PETSC_DETERMINE` then all processors must, otherwise the program will hang.
1451: .seealso: [](chapter_vectors), `Vec`, `VecGetSize()`, `PetscSplitOwnership()`
1452: @*/
1453: PetscErrorCode VecSetSizes(Vec v, PetscInt n, PetscInt N)
1454: {
1455: PetscFunctionBegin;
1457: if (N >= 0) {
1459: PetscCheck(n <= N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " cannot be larger than global size %" PetscInt_FMT, n, N);
1460: }
1461: 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,
1462: v->map->n, v->map->N);
1463: v->map->n = n;
1464: v->map->N = N;
1465: PetscTryTypeMethod(v, create);
1466: v->ops->create = NULL;
1467: PetscFunctionReturn(PETSC_SUCCESS);
1468: }
1470: /*@
1471: VecSetBlockSize - Sets the block size for future calls to `VecSetValuesBlocked()`
1472: and `VecSetValuesBlockedLocal()`.
1474: Logically Collective
1476: Input Parameters:
1477: + v - the vector
1478: - bs - the blocksize
1480: Level: advanced
1482: Note:
1483: All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1485: Vectors obtained with `DMCreateGlobalVector()` and `DMCreateLocalVector()` generally already have a blocksize set based on the state of the `DM`
1487: .seealso: [](chapter_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecGetBlockSize()`
1488: @*/
1489: PetscErrorCode VecSetBlockSize(Vec v, PetscInt bs)
1490: {
1491: PetscFunctionBegin;
1494: PetscCall(PetscLayoutSetBlockSize(v->map, bs));
1495: v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
1496: PetscFunctionReturn(PETSC_SUCCESS);
1497: }
1499: /*@
1500: VecGetBlockSize - Gets the blocksize for the vector, i.e. what is used for `VecSetValuesBlocked()`
1501: and `VecSetValuesBlockedLocal()`.
1503: Not Collective
1505: Input Parameter:
1506: . v - the vector
1508: Output Parameter:
1509: . bs - the blocksize
1511: Level: advanced
1513: Note:
1514: All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1516: .seealso: [](chapter_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecSetBlockSize()`
1517: @*/
1518: PetscErrorCode VecGetBlockSize(Vec v, PetscInt *bs)
1519: {
1520: PetscFunctionBegin;
1523: PetscCall(PetscLayoutGetBlockSize(v->map, bs));
1524: PetscFunctionReturn(PETSC_SUCCESS);
1525: }
1527: /*@C
1528: VecSetOptionsPrefix - Sets the prefix used for searching for all
1529: `Vec` options in the database.
1531: Logically Collective
1533: Input Parameters:
1534: + v - the `Vec` context
1535: - prefix - the prefix to prepend to all option names
1537: Level: advanced
1539: Note:
1540: A hyphen (-) must NOT be given at the beginning of the prefix name.
1541: The first character of all runtime options is AUTOMATICALLY the hyphen.
1543: .seealso: [](chapter_vectors), `Vec`, `VecSetFromOptions()`
1544: @*/
1545: PetscErrorCode VecSetOptionsPrefix(Vec v, const char prefix[])
1546: {
1547: PetscFunctionBegin;
1549: PetscCall(PetscObjectSetOptionsPrefix((PetscObject)v, prefix));
1550: PetscFunctionReturn(PETSC_SUCCESS);
1551: }
1553: /*@C
1554: VecAppendOptionsPrefix - Appends to the prefix used for searching for all
1555: `Vec` options in the database.
1557: Logically Collective
1559: Input Parameters:
1560: + v - the `Vec` context
1561: - prefix - the prefix to prepend to all option names
1563: Level: advanced
1565: Note:
1566: A hyphen (-) must NOT be given at the beginning of the prefix name.
1567: The first character of all runtime options is AUTOMATICALLY the hyphen.
1569: .seealso: [](chapter_vectors), `Vec`, `VecGetOptionsPrefix()`
1570: @*/
1571: PetscErrorCode VecAppendOptionsPrefix(Vec v, const char prefix[])
1572: {
1573: PetscFunctionBegin;
1575: PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)v, prefix));
1576: PetscFunctionReturn(PETSC_SUCCESS);
1577: }
1579: /*@C
1580: VecGetOptionsPrefix - Sets the prefix used for searching for all
1581: Vec options in the database.
1583: Not Collective
1585: Input Parameter:
1586: . v - the `Vec` context
1588: Output Parameter:
1589: . prefix - pointer to the prefix string used
1591: Level: advanced
1593: Fortran Note:
1594: The user must pass in a string `prefix` of
1595: sufficient length to hold the prefix.
1597: .seealso: [](chapter_vectors), `Vec`, `VecAppendOptionsPrefix()`
1598: @*/
1599: PetscErrorCode VecGetOptionsPrefix(Vec v, const char *prefix[])
1600: {
1601: PetscFunctionBegin;
1603: PetscCall(PetscObjectGetOptionsPrefix((PetscObject)v, prefix));
1604: PetscFunctionReturn(PETSC_SUCCESS);
1605: }
1607: /*@
1608: VecSetUp - Sets up the internal vector data structures for the later use.
1610: Collective
1612: Input Parameters:
1613: . v - the `Vec` context
1615: Level: advanced
1617: Notes:
1618: For basic use of the `Vec` classes the user need not explicitly call
1619: `VecSetUp()`, since these actions will happen automatically.
1621: .seealso: [](chapter_vectors), `Vec`, `VecCreate()`, `VecDestroy()`
1622: @*/
1623: PetscErrorCode VecSetUp(Vec v)
1624: {
1625: PetscMPIInt size;
1627: PetscFunctionBegin;
1629: PetscCheck(v->map->n >= 0 || v->map->N >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Sizes not set");
1630: if (!((PetscObject)v)->type_name) {
1631: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1632: if (size == 1) {
1633: PetscCall(VecSetType(v, VECSEQ));
1634: } else {
1635: PetscCall(VecSetType(v, VECMPI));
1636: }
1637: }
1638: PetscFunctionReturn(PETSC_SUCCESS);
1639: }
1641: /*
1642: These currently expose the PetscScalar/PetscReal in updating the
1643: cached norm. If we push those down into the implementation these
1644: will become independent of PetscScalar/PetscReal
1645: */
1647: /*@
1648: VecCopy - Copies a vector `y = x`
1650: Logically Collective
1652: Input Parameter:
1653: . x - the vector
1655: Output Parameter:
1656: . y - the copy
1658: Level: beginner
1660: Note:
1661: For default parallel PETSc vectors, both `x` and `y` must be distributed in
1662: the same manner; local copies are done.
1664: Developer Note:
1665: `PetscCheckSameTypeAndComm`(x,1,y,2) is not used on these vectors because we allow one
1666: of the vectors to be sequential and one to be parallel so long as both have the same
1667: local sizes. This is used in some internal functions in PETSc.
1669: .seealso: [](chapter_vectors), `Vec`, `VecDuplicate()`
1670: @*/
1671: PetscErrorCode VecCopy(Vec x, Vec y)
1672: {
1673: PetscBool flgs[4];
1674: PetscReal norms[4] = {0.0, 0.0, 0.0, 0.0};
1676: PetscFunctionBegin;
1681: if (x == y) PetscFunctionReturn(PETSC_SUCCESS);
1682: VecCheckSameLocalSize(x, 1, y, 2);
1683: VecCheckAssembled(x);
1684: PetscCall(VecSetErrorIfLocked(y, 2));
1686: #if !defined(PETSC_USE_MIXED_PRECISION)
1687: for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
1688: #endif
1690: PetscCall(PetscLogEventBegin(VEC_Copy, x, y, 0, 0));
1691: #if defined(PETSC_USE_MIXED_PRECISION)
1692: extern PetscErrorCode VecGetArray(Vec, double **);
1693: extern PetscErrorCode VecRestoreArray(Vec, double **);
1694: extern PetscErrorCode VecGetArray(Vec, float **);
1695: extern PetscErrorCode VecRestoreArray(Vec, float **);
1696: extern PetscErrorCode VecGetArrayRead(Vec, const double **);
1697: extern PetscErrorCode VecRestoreArrayRead(Vec, const double **);
1698: extern PetscErrorCode VecGetArrayRead(Vec, const float **);
1699: extern PetscErrorCode VecRestoreArrayRead(Vec, const float **);
1700: if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
1701: PetscInt i, n;
1702: const float *xx;
1703: double *yy;
1704: PetscCall(VecGetArrayRead(x, &xx));
1705: PetscCall(VecGetArray(y, &yy));
1706: PetscCall(VecGetLocalSize(x, &n));
1707: for (i = 0; i < n; i++) yy[i] = xx[i];
1708: PetscCall(VecRestoreArrayRead(x, &xx));
1709: PetscCall(VecRestoreArray(y, &yy));
1710: } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
1711: PetscInt i, n;
1712: float *yy;
1713: const double *xx;
1714: PetscCall(VecGetArrayRead(x, &xx));
1715: PetscCall(VecGetArray(y, &yy));
1716: PetscCall(VecGetLocalSize(x, &n));
1717: for (i = 0; i < n; i++) yy[i] = (float)xx[i];
1718: PetscCall(VecRestoreArrayRead(x, &xx));
1719: PetscCall(VecRestoreArray(y, &yy));
1720: } else PetscUseTypeMethod(x, copy, y);
1721: #else
1722: PetscUseTypeMethod(x, copy, y);
1723: #endif
1725: PetscCall(PetscObjectStateIncrease((PetscObject)y));
1726: #if !defined(PETSC_USE_MIXED_PRECISION)
1727: for (PetscInt i = 0; i < 4; i++) {
1728: if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], norms[i]));
1729: }
1730: #endif
1732: PetscCall(PetscLogEventEnd(VEC_Copy, x, y, 0, 0));
1733: PetscFunctionReturn(PETSC_SUCCESS);
1734: }
1736: /*@
1737: VecSwap - Swaps the values between two vectors, `x` and `y`.
1739: Logically Collective
1741: Input Parameters:
1742: . x, y - the vectors
1744: Level: advanced
1746: .seealso: [](chapter_vectors), `Vec`, `VecSet()`
1747: @*/
1748: PetscErrorCode VecSwap(Vec x, Vec y)
1749: {
1750: PetscReal normxs[4], normys[4];
1751: PetscBool flgxs[4], flgys[4];
1753: PetscFunctionBegin;
1758: PetscCheckSameTypeAndComm(x, 1, y, 2);
1759: VecCheckSameSize(x, 1, y, 2);
1760: VecCheckAssembled(x);
1761: VecCheckAssembled(y);
1762: PetscCall(VecSetErrorIfLocked(x, 1));
1763: PetscCall(VecSetErrorIfLocked(y, 2));
1765: for (PetscInt i = 0; i < 4; i++) {
1766: PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], normxs[i], flgxs[i]));
1767: PetscCall(PetscObjectComposedDataGetReal((PetscObject)y, NormIds[i], normys[i], flgys[i]));
1768: }
1770: PetscCall(PetscLogEventBegin(VEC_Swap, x, y, 0, 0));
1771: PetscUseTypeMethod(x, swap, y);
1772: PetscCall(PetscLogEventEnd(VEC_Swap, x, y, 0, 0));
1774: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1775: PetscCall(PetscObjectStateIncrease((PetscObject)y));
1776: for (PetscInt i = 0; i < 4; i++) {
1777: if (flgxs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], normxs[i]));
1778: if (flgys[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], normys[i]));
1779: }
1780: PetscFunctionReturn(PETSC_SUCCESS);
1781: }
1783: /*@C
1784: VecStashViewFromOptions - Processes command line options to determine if/how a `VecStash` object is to be viewed.
1786: Collective
1788: Input Parameters:
1789: + obj - the `Vec` containing a stash
1790: . bobj - optional other object that provides the prefix
1791: - optionname - option to activate viewing
1793: Level: intermediate
1795: Developer Note:
1796: This cannot use `PetscObjectViewFromOptions()` because it takes a `Vec` as an argument but does not use `VecView()`
1798: .seealso: [](chapter_vectors), `Vec`, `VecStashSetInitialSize()`
1799: @*/
1800: PetscErrorCode VecStashViewFromOptions(Vec obj, PetscObject bobj, const char optionname[])
1801: {
1802: PetscViewer viewer;
1803: PetscBool flg;
1804: PetscViewerFormat format;
1805: char *prefix;
1807: PetscFunctionBegin;
1808: prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
1809: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), ((PetscObject)obj)->options, prefix, optionname, &viewer, &format, &flg));
1810: if (flg) {
1811: PetscCall(PetscViewerPushFormat(viewer, format));
1812: PetscCall(VecStashView(obj, viewer));
1813: PetscCall(PetscViewerPopFormat(viewer));
1814: PetscCall(PetscViewerDestroy(&viewer));
1815: }
1816: PetscFunctionReturn(PETSC_SUCCESS);
1817: }
1819: /*@
1820: VecStashView - Prints the entries in the vector stash and block stash.
1822: Collective
1824: Input Parameters:
1825: + v - the vector
1826: - viewer - the viewer
1828: Level: advanced
1830: .seealso: [](chapter_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`
1831: @*/
1832: PetscErrorCode VecStashView(Vec v, PetscViewer viewer)
1833: {
1834: PetscMPIInt rank;
1835: PetscInt i, j;
1836: PetscBool match;
1837: VecStash *s;
1838: PetscScalar val;
1840: PetscFunctionBegin;
1843: PetscCheckSameComm(v, 1, viewer, 2);
1845: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &match));
1846: PetscCheck(match, PETSC_COMM_SELF, PETSC_ERR_SUP, "Stash viewer only works with ASCII viewer not %s", ((PetscObject)v)->type_name);
1847: PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1848: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
1849: s = &v->bstash;
1851: /* print block stash */
1852: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
1853: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector Block stash size %" PetscInt_FMT " block size %" PetscInt_FMT "\n", rank, s->n, s->bs));
1854: for (i = 0; i < s->n; i++) {
1855: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " ", rank, s->idx[i]));
1856: for (j = 0; j < s->bs; j++) {
1857: val = s->array[i * s->bs + j];
1858: #if defined(PETSC_USE_COMPLEX)
1859: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "(%18.16e %18.16e) ", (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1860: #else
1861: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%18.16e ", (double)val));
1862: #endif
1863: }
1864: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
1865: }
1866: PetscCall(PetscViewerFlush(viewer));
1868: s = &v->stash;
1870: /* print basic stash */
1871: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector stash size %" PetscInt_FMT "\n", rank, s->n));
1872: for (i = 0; i < s->n; i++) {
1873: val = s->array[i];
1874: #if defined(PETSC_USE_COMPLEX)
1875: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " (%18.16e %18.16e) ", rank, s->idx[i], (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1876: #else
1877: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " %18.16e\n", rank, s->idx[i], (double)val));
1878: #endif
1879: }
1880: PetscCall(PetscViewerFlush(viewer));
1881: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
1882: PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1883: PetscFunctionReturn(PETSC_SUCCESS);
1884: }
1886: PetscErrorCode PetscOptionsGetVec(PetscOptions options, const char prefix[], const char key[], Vec v, PetscBool *set)
1887: {
1888: PetscInt i, N, rstart, rend;
1889: PetscScalar *xx;
1890: PetscReal *xreal;
1891: PetscBool iset;
1893: PetscFunctionBegin;
1894: PetscCall(VecGetOwnershipRange(v, &rstart, &rend));
1895: PetscCall(VecGetSize(v, &N));
1896: PetscCall(PetscCalloc1(N, &xreal));
1897: PetscCall(PetscOptionsGetRealArray(options, prefix, key, xreal, &N, &iset));
1898: if (iset) {
1899: PetscCall(VecGetArray(v, &xx));
1900: for (i = rstart; i < rend; i++) xx[i - rstart] = xreal[i];
1901: PetscCall(VecRestoreArray(v, &xx));
1902: }
1903: PetscCall(PetscFree(xreal));
1904: if (set) *set = iset;
1905: PetscFunctionReturn(PETSC_SUCCESS);
1906: }
1908: /*@
1909: VecGetLayout - get `PetscLayout` describing a vector layout
1911: Not Collective
1913: Input Parameter:
1914: . x - the vector
1916: Output Parameter:
1917: . map - the layout
1919: Level: developer
1921: Note:
1922: The layout determines what vector elements are contained on each MPI process
1924: .seealso: [](chapter_vectors), `PetscLayout`, `Vec`, `VecGetSizes()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1925: @*/
1926: PetscErrorCode VecGetLayout(Vec x, PetscLayout *map)
1927: {
1928: PetscFunctionBegin;
1931: *map = x->map;
1932: PetscFunctionReturn(PETSC_SUCCESS);
1933: }
1935: /*@
1936: VecSetLayout - set `PetscLayout` describing vector layout
1938: Not Collective
1940: Input Parameters:
1941: + x - the vector
1942: - map - the layout
1944: Level: developer
1946: Note:
1947: It is normally only valid to replace the layout with a layout known to be equivalent.
1949: .seealso: [](chapter_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSizes()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1950: @*/
1951: PetscErrorCode VecSetLayout(Vec x, PetscLayout map)
1952: {
1953: PetscFunctionBegin;
1955: PetscCall(PetscLayoutReference(map, &x->map));
1956: PetscFunctionReturn(PETSC_SUCCESS);
1957: }
1959: PetscErrorCode VecSetInf(Vec xin)
1960: {
1961: // use of variables one and zero over just doing 1.0/0.0 is deliberate. MSVC complains that
1962: // we are dividing by zero in the latter case (ostensibly because dividing by 0 is UB, but
1963: // only for *integers* not floats).
1964: const PetscScalar one = 1.0, zero = 0.0, inf = one / zero;
1966: PetscFunctionBegin;
1967: if (xin->ops->set) {
1968: PetscUseTypeMethod(xin, set, inf);
1969: } else {
1970: PetscInt n;
1971: PetscScalar *xx;
1973: PetscCall(VecGetLocalSize(xin, &n));
1974: PetscCall(VecGetArrayWrite(xin, &xx));
1975: for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
1976: PetscCall(VecRestoreArrayWrite(xin, &xx));
1977: }
1978: PetscFunctionReturn(PETSC_SUCCESS);
1979: }
1981: /*@
1982: VecBindToCPU - marks a vector to temporarily stay on the CPU and perform computations on the CPU
1984: Logically collective
1986: Input Parameters:
1987: + v - the vector
1988: - flg - bind to the CPU if value of `PETSC_TRUE`
1990: Level: intermediate
1992: .seelaso: [](chapter_vectors), `Vec`, `VecBoundToCPU()`
1993: @*/
1994: PetscErrorCode VecBindToCPU(Vec v, PetscBool flg)
1995: {
1996: PetscFunctionBegin;
1999: #if defined(PETSC_HAVE_DEVICE)
2000: if (v->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS);
2001: v->boundtocpu = flg;
2002: PetscTryTypeMethod(v, bindtocpu, flg);
2003: #endif
2004: PetscFunctionReturn(PETSC_SUCCESS);
2005: }
2007: /*@
2008: VecBoundToCPU - query if a vector is bound to the CPU
2010: Not collective
2012: Input Parameter:
2013: . v - the vector
2015: Output Parameter:
2016: . flg - the logical flag
2018: Level: intermediate
2020: .seealso: [](chapter_vectors), `Vec`, `VecBindToCPU()`
2021: @*/
2022: PetscErrorCode VecBoundToCPU(Vec v, PetscBool *flg)
2023: {
2024: PetscFunctionBegin;
2027: #if defined(PETSC_HAVE_DEVICE)
2028: *flg = v->boundtocpu;
2029: #else
2030: *flg = PETSC_TRUE;
2031: #endif
2032: PetscFunctionReturn(PETSC_SUCCESS);
2033: }
2035: /*@
2036: VecSetBindingPropagates - Sets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2038: Input Parameters:
2039: + v - the vector
2040: - flg - flag indicating whether the boundtocpu flag should be propagated
2042: Level: developer
2044: Notes:
2045: 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.
2046: The created vectors will also have their bindingpropagates flag set to true.
2048: Developer Note:
2049: If a `DMDA` has the `-dm_bind_below option` set to true, then vectors created by `DMCreateGlobalVector()` will have `VecSetBindingPropagates()` called on them to
2050: set their bindingpropagates flag to true.
2052: .seealso: [](chapter_vectors), `Vec`, `MatSetBindingPropagates()`, `VecGetBindingPropagates()`
2053: @*/
2054: PetscErrorCode VecSetBindingPropagates(Vec v, PetscBool flg)
2055: {
2056: PetscFunctionBegin;
2058: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2059: v->bindingpropagates = flg;
2060: #endif
2061: PetscFunctionReturn(PETSC_SUCCESS);
2062: }
2064: /*@
2065: VecGetBindingPropagates - Gets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2067: Input Parameter:
2068: . v - the vector
2070: Output Parameter:
2071: . flg - flag indicating whether the boundtocpu flag will be propagated
2073: Level: developer
2075: .seealso: [](chapter_vectors), `Vec`, `VecSetBindingPropagates()`
2076: @*/
2077: PetscErrorCode VecGetBindingPropagates(Vec v, PetscBool *flg)
2078: {
2079: PetscFunctionBegin;
2082: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2083: *flg = v->bindingpropagates;
2084: #else
2085: *flg = PETSC_FALSE;
2086: #endif
2087: PetscFunctionReturn(PETSC_SUCCESS);
2088: }
2090: /*@C
2091: VecSetPinnedMemoryMin - Set the minimum data size for which pinned memory will be used for host (CPU) allocations.
2093: Logically Collective
2095: Input Parameters:
2096: + v - the vector
2097: - mbytes - minimum data size in bytes
2099: Options Database Key:
2100: . -vec_pinned_memory_min <size> - minimum size (in bytes) for an allocation to use pinned memory on host.
2102: Level: developer
2104: Note:
2105: Specifying -1 ensures that pinned memory will never be used.
2107: .seealso: [](chapter_vectors), `Vec`, `VecGetPinnedMemoryMin()`
2108: @*/
2109: PetscErrorCode VecSetPinnedMemoryMin(Vec v, size_t mbytes)
2110: {
2111: PetscFunctionBegin;
2113: #if PetscDefined(HAVE_DEVICE)
2114: v->minimum_bytes_pinned_memory = mbytes;
2115: #endif
2116: PetscFunctionReturn(PETSC_SUCCESS);
2117: }
2119: /*@C
2120: VecGetPinnedMemoryMin - Get the minimum data size for which pinned memory will be used for host (CPU) allocations.
2122: Logically Collective
2124: Input Parameters:
2125: . v - the vector
2127: Output Parameters:
2128: . mbytes - minimum data size in bytes
2130: Level: developer
2132: .seealso: [](chapter_vectors), `Vec`, `VecSetPinnedMemoryMin()`
2133: @*/
2134: PetscErrorCode VecGetPinnedMemoryMin(Vec v, size_t *mbytes)
2135: {
2136: PetscFunctionBegin;
2139: #if PetscDefined(HAVE_DEVICE)
2140: *mbytes = v->minimum_bytes_pinned_memory;
2141: #endif
2142: PetscFunctionReturn(PETSC_SUCCESS);
2143: }
2145: /*@
2146: VecGetOffloadMask - Get the offload mask of a `Vec`
2148: Not Collective
2150: Input Parameters:
2151: . v - the vector
2153: Output Parameters:
2154: . mask - corresponding `PetscOffloadMask` enum value.
2156: Level: intermediate
2158: .seealso: [](chapter_vectors), `Vec`, `VecCreateSeqCUDA()`, `VecCreateSeqViennaCL()`, `VecGetArray()`, `VecGetType()`
2159: @*/
2160: PetscErrorCode VecGetOffloadMask(Vec v, PetscOffloadMask *mask)
2161: {
2162: PetscFunctionBegin;
2165: *mask = v->offloadmask;
2166: PetscFunctionReturn(PETSC_SUCCESS);
2167: }
2169: #if !defined(PETSC_HAVE_VIENNACL)
2170: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v, PETSC_UINTPTR_T *ctx)
2171: {
2172: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_context");
2173: }
2175: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLQueue(Vec v, PETSC_UINTPTR_T *queue)
2176: {
2177: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_command_queue");
2178: }
2180: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMem(Vec v, PETSC_UINTPTR_T *queue)
2181: {
2182: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2183: }
2185: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemRead(Vec v, PETSC_UINTPTR_T *queue)
2186: {
2187: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2188: }
2190: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemWrite(Vec v, PETSC_UINTPTR_T *queue)
2191: {
2192: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2193: }
2195: PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
2196: {
2197: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
2198: }
2199: #endif