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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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: [](ch_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 - the first vector
458: - y - the second vector
460: Output Parameter:
461: . w - the result
463: Level: advanced
465: Note:
466: Any subset of the `x`, `y`, and `w` may be the same vector.
468: .seealso: [](ch_vectors), `Vec`, `VecPointwiseDivide()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`, `VecMaxPointwiseDivide()`
469: @*/
470: PetscErrorCode VecPointwiseMult(Vec w, Vec x, Vec y)
471: {
472: PetscFunctionBegin;
474: PetscCall(VecPointwiseApply_Private(w, x, y, VEC_PointwiseMult, w->ops->pointwisemult));
475: PetscFunctionReturn(PETSC_SUCCESS);
476: }
478: /*@
479: VecDuplicate - Creates a new vector of the same type as an existing vector.
481: Collective
483: Input Parameter:
484: . v - a vector to mimic
486: Output Parameter:
487: . newv - location to put new vector
489: Level: beginner
491: Notes:
492: `VecDuplicate()` DOES NOT COPY the vector entries, but rather allocates storage
493: for the new vector. Use `VecCopy()` to copy a vector.
495: Use `VecDestroy()` to free the space. Use `VecDuplicateVecs()` to get several
496: vectors.
498: .seealso: [](ch_vectors), `Vec`, `VecDestroy()`, `VecDuplicateVecs()`, `VecCreate()`, `VecCopy()`
499: @*/
500: PetscErrorCode VecDuplicate(Vec v, Vec *newv)
501: {
502: PetscFunctionBegin;
506: PetscUseTypeMethod(v, duplicate, newv);
507: #if PetscDefined(HAVE_DEVICE)
508: if (v->boundtocpu && v->bindingpropagates) {
509: PetscCall(VecSetBindingPropagates(*newv, PETSC_TRUE));
510: PetscCall(VecBindToCPU(*newv, PETSC_TRUE));
511: }
512: #endif
513: PetscCall(PetscObjectStateIncrease((PetscObject)(*newv)));
514: PetscFunctionReturn(PETSC_SUCCESS);
515: }
517: /*@C
518: VecDestroy - Destroys a vector.
520: Collective
522: Input Parameter:
523: . v - the vector
525: Level: beginner
527: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDuplicate()`, `VecDestroyVecs()`
528: @*/
529: PetscErrorCode VecDestroy(Vec *v)
530: {
531: PetscFunctionBegin;
533: if (!*v) PetscFunctionReturn(PETSC_SUCCESS);
535: if (--((PetscObject)(*v))->refct > 0) {
536: *v = NULL;
537: PetscFunctionReturn(PETSC_SUCCESS);
538: }
540: PetscCall(PetscObjectSAWsViewOff((PetscObject)*v));
541: /* destroy the internal part */
542: PetscTryTypeMethod(*v, destroy);
543: PetscCall(PetscFree((*v)->defaultrandtype));
544: /* destroy the external/common part */
545: PetscCall(PetscLayoutDestroy(&(*v)->map));
546: PetscCall(PetscHeaderDestroy(v));
547: PetscFunctionReturn(PETSC_SUCCESS);
548: }
550: /*@C
551: VecDuplicateVecs - Creates several vectors of the same type as an existing vector.
553: Collective
555: Input Parameters:
556: + m - the number of vectors to obtain
557: - v - a vector to mimic
559: Output Parameter:
560: . V - location to put pointer to array of vectors
562: Level: intermediate
564: Note:
565: Use `VecDestroyVecs()` to free the space. Use `VecDuplicate()` to form a single
566: vector.
568: Fortran Note:
569: The Fortran interface is slightly different from that given below, it
570: requires one to pass in `V` a `Vec` array of size at least `m`.
571: See the [](ch_fortran) for details.
573: .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDestroyVecs()`, `VecDuplicate()`, `VecCreate()`, `VecDuplicateVecsF90()`
574: @*/
575: PetscErrorCode VecDuplicateVecs(Vec v, PetscInt m, Vec *V[])
576: {
577: PetscFunctionBegin;
581: PetscUseTypeMethod(v, duplicatevecs, m, V);
582: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
583: if (v->boundtocpu && v->bindingpropagates) {
584: PetscInt i;
586: for (i = 0; i < m; i++) {
587: /* Since ops->duplicatevecs might itself propagate the value of boundtocpu,
588: * avoid unnecessary overhead by only calling VecBindToCPU() if the vector isn't already bound. */
589: if (!(*V)[i]->boundtocpu) {
590: PetscCall(VecSetBindingPropagates((*V)[i], PETSC_TRUE));
591: PetscCall(VecBindToCPU((*V)[i], PETSC_TRUE));
592: }
593: }
594: }
595: #endif
596: PetscFunctionReturn(PETSC_SUCCESS);
597: }
599: /*@C
600: VecDestroyVecs - Frees a block of vectors obtained with `VecDuplicateVecs()`.
602: Collective
604: Input Parameters:
605: + m - the number of vectors previously obtained, if zero no vectors are destroyed
606: - vv - pointer to pointer to array of vector pointers, if `NULL` no vectors are destroyed
608: Level: intermediate
610: Fortran Note:
611: The Fortran interface is slightly different from that given below.
612: See the [](ch_fortran) for details.
614: .seealso: [](ch_vectors), `Vec`, [](ch_fortran), `VecDuplicateVecs()`, `VecDestroyVecsf90()`
615: @*/
616: PetscErrorCode VecDestroyVecs(PetscInt m, Vec *vv[])
617: {
618: PetscFunctionBegin;
620: PetscCheck(m >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Trying to destroy negative number of vectors %" PetscInt_FMT, m);
621: if (!m || !*vv) {
622: *vv = NULL;
623: PetscFunctionReturn(PETSC_SUCCESS);
624: }
627: PetscCall((*(**vv)->ops->destroyvecs)(m, *vv));
628: *vv = NULL;
629: PetscFunctionReturn(PETSC_SUCCESS);
630: }
632: /*@C
633: VecViewFromOptions - View a vector based on values in the options database
635: Collective
637: Input Parameters:
638: + A - the vector
639: . obj - Optional object that provides the options prefix for this viewing
640: - name - command line option
642: Level: intermediate
644: Note:
645: See `PetscObjectViewFromOptions()` to see the `PetscViewer` and PetscViewerFormat` available
647: .seealso: [](ch_vectors), `Vec`, `VecView`, `PetscObjectViewFromOptions()`, `VecCreate()`
648: @*/
649: PetscErrorCode VecViewFromOptions(Vec A, PetscObject obj, const char name[])
650: {
651: PetscFunctionBegin;
653: PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
654: PetscFunctionReturn(PETSC_SUCCESS);
655: }
657: /*@C
658: VecView - Views a vector object.
660: Collective
662: Input Parameters:
663: + vec - the vector
664: - viewer - an optional `PetscViewer` visualization context
666: Level: beginner
668: Notes:
669: The available visualization contexts include
670: + `PETSC_VIEWER_STDOUT_SELF` - for sequential vectors
671: . `PETSC_VIEWER_STDOUT_WORLD` - for parallel vectors created on `PETSC_COMM_WORLD`
672: - `PETSC_VIEWER_STDOUT`_(comm) - for parallel vectors created on MPI communicator comm
674: You can change the format the vector is printed using the
675: option `PetscViewerPushFormat()`.
677: The user can open alternative viewers with
678: + `PetscViewerASCIIOpen()` - Outputs vector to a specified file
679: . `PetscViewerBinaryOpen()` - Outputs vector in binary to a
680: specified file; corresponding input uses `VecLoad()`
681: . `PetscViewerDrawOpen()` - Outputs vector to an X window display
682: . `PetscViewerSocketOpen()` - Outputs vector to Socket viewer
683: - `PetscViewerHDF5Open()` - Outputs vector to HDF5 file viewer
685: The user can call `PetscViewerPushFormat()` to specify the output
686: format of ASCII printed objects (when using `PETSC_VIEWER_STDOUT_SELF`,
687: `PETSC_VIEWER_STDOUT_WORLD` and `PetscViewerASCIIOpen()`). Available formats include
688: + `PETSC_VIEWER_DEFAULT` - default, prints vector contents
689: . `PETSC_VIEWER_ASCII_MATLAB` - prints vector contents in MATLAB format
690: . `PETSC_VIEWER_ASCII_INDEX` - prints vector contents, including indices of vector elements
691: - `PETSC_VIEWER_ASCII_COMMON` - prints vector contents, using a
692: format common among all vector types
694: You can pass any number of vector objects, or other PETSc objects to the same viewer.
696: In the debugger you can do call `VecView`(v,0) to display the vector. (The same holds for any PETSc object viewer).
698: Notes for binary viewer:
699: If you pass multiple vectors to a binary viewer you can read them back in in the same order
700: with `VecLoad()`.
702: If the blocksize of the vector is greater than one then you must provide a unique prefix to
703: the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
704: vector to be stored and then set that same unique prefix on the vector that you pass to `VecLoad()`. The blocksize
705: information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
706: filename. If you copy the binary file, make sure you copy the associated .info file with it.
708: See the manual page for `VecLoad()` on the exact format the binary viewer stores
709: the values in the file.
711: Notes for HDF5 Viewer:
712: The name of the `Vec` (given with `PetscObjectSetName()` is the name that is used
713: for the object in the HDF5 file. If you wish to store the same Vec into multiple
714: datasets in the same file (typically with different values), you must change its
715: name each time before calling the `VecView()`. To load the same vector,
716: the name of the Vec object passed to `VecLoad()` must be the same.
718: If the block size of the vector is greater than 1 then it is used as the first dimension in the HDF5 array.
719: If the function `PetscViewerHDF5SetBaseDimension2()`is called then even if the block size is one it will
720: be used as the first dimension in the HDF5 array (that is the HDF5 array will always be two dimensional)
721: See also `PetscViewerHDF5SetTimestep()` which adds an additional complication to reading and writing `Vec`
722: with the HDF5 viewer.
724: .seealso: [](ch_vectors), `Vec`, `VecViewFromOptions()`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`,
725: `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
726: `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
727: @*/
728: PetscErrorCode VecView(Vec vec, PetscViewer viewer)
729: {
730: PetscBool iascii;
731: PetscViewerFormat format;
732: PetscMPIInt size;
734: PetscFunctionBegin;
737: VecCheckAssembled(vec);
738: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
740: PetscCall(PetscViewerGetFormat(viewer, &format));
741: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
742: if (size == 1 && format == PETSC_VIEWER_LOAD_BALANCE) PetscFunctionReturn(PETSC_SUCCESS);
744: PetscCheck(!vec->stash.n && !vec->bstash.n, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call VecAssemblyBegin/End() before viewing this vector");
746: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
747: if (iascii) {
748: PetscInt rows, bs;
750: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)vec, viewer));
751: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
752: PetscCall(PetscViewerASCIIPushTab(viewer));
753: PetscCall(VecGetSize(vec, &rows));
754: PetscCall(VecGetBlockSize(vec, &bs));
755: if (bs != 1) {
756: PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT ", bs=%" PetscInt_FMT "\n", rows, bs));
757: } else {
758: PetscCall(PetscViewerASCIIPrintf(viewer, "length=%" PetscInt_FMT "\n", rows));
759: }
760: PetscCall(PetscViewerASCIIPopTab(viewer));
761: }
762: }
763: PetscCall(VecLockReadPush(vec));
764: PetscCall(PetscLogEventBegin(VEC_View, vec, viewer, 0, 0));
765: if ((format == PETSC_VIEWER_NATIVE || format == PETSC_VIEWER_LOAD_BALANCE) && vec->ops->viewnative) {
766: PetscUseTypeMethod(vec, viewnative, viewer);
767: } else {
768: PetscUseTypeMethod(vec, view, viewer);
769: }
770: PetscCall(VecLockReadPop(vec));
771: PetscCall(PetscLogEventEnd(VEC_View, vec, viewer, 0, 0));
772: PetscFunctionReturn(PETSC_SUCCESS);
773: }
775: #if defined(PETSC_USE_DEBUG)
776: #include <../src/sys/totalview/tv_data_display.h>
777: PETSC_UNUSED static int TV_display_type(const struct _p_Vec *v)
778: {
779: const PetscScalar *values;
780: char type[32];
782: TV_add_row("Local rows", "int", &v->map->n);
783: TV_add_row("Global rows", "int", &v->map->N);
784: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)v)->type_name);
785: PetscCall(VecGetArrayRead((Vec)v, &values));
786: PetscCall(PetscSNPrintf(type, 32, "double[%" PetscInt_FMT "]", v->map->n));
787: TV_add_row("values", type, values);
788: PetscCall(VecRestoreArrayRead((Vec)v, &values));
789: return TV_format_OK;
790: }
791: #endif
793: /*@C
794: VecViewNative - Views a vector object with the original type specific viewer
796: Collective
798: Input Parameters:
799: + vec - the vector
800: - viewer - an optional `PetscViewer` visualization context
802: Level: developer
804: Note:
805: This can be used with, for example, vectors obtained with `DMCreateGlobalVector()` for a `DMDA` to display the vector
806: in the PETSc storage format (each MPI process values follow the previous MPI processes) instead of the "natural" grid
807: ordering.
809: .seealso: [](ch_vectors), `Vec`, `PetscViewerASCIIOpen()`, `PetscViewerDrawOpen()`, `PetscDrawLGCreate()`, `VecView()`
810: `PetscViewerSocketOpen()`, `PetscViewerBinaryOpen()`, `VecLoad()`, `PetscViewerCreate()`,
811: `PetscRealView()`, `PetscScalarView()`, `PetscIntView()`, `PetscViewerHDF5SetTimestep()`
812: @*/
813: PetscErrorCode VecViewNative(Vec vec, PetscViewer viewer)
814: {
815: PetscFunctionBegin;
818: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)vec), &viewer));
820: PetscUseTypeMethod(vec, viewnative, viewer);
821: PetscFunctionReturn(PETSC_SUCCESS);
822: }
824: /*@
825: VecGetSize - Returns the global number of elements of the vector.
827: Not Collective
829: Input Parameter:
830: . x - the vector
832: Output Parameter:
833: . size - the global length of the vector
835: Level: beginner
837: .seealso: [](ch_vectors), `Vec`, `VecGetLocalSize()`
838: @*/
839: PetscErrorCode VecGetSize(Vec x, PetscInt *size)
840: {
841: PetscFunctionBegin;
845: PetscUseTypeMethod(x, getsize, size);
846: PetscFunctionReturn(PETSC_SUCCESS);
847: }
849: /*@
850: VecGetLocalSize - Returns the number of elements of the vector stored
851: in local memory (that is on this MPI process)
853: Not Collective
855: Input Parameter:
856: . x - the vector
858: Output Parameter:
859: . size - the length of the local piece of the vector
861: Level: beginner
863: .seealso: [](ch_vectors), `Vec`, `VecGetSize()`
864: @*/
865: PetscErrorCode VecGetLocalSize(Vec x, PetscInt *size)
866: {
867: PetscFunctionBegin;
871: PetscUseTypeMethod(x, getlocalsize, size);
872: PetscFunctionReturn(PETSC_SUCCESS);
873: }
875: /*@C
876: VecGetOwnershipRange - Returns the range of indices owned by
877: this process. The vector is laid out with the
878: first n1 elements on the first processor, next n2 elements on the
879: second, etc. For certain parallel layouts this range may not be
880: well defined.
882: Not Collective
884: Input Parameter:
885: . x - the vector
887: Output Parameters:
888: + low - the first local element, pass in `NULL` if not interested
889: - high - one more than the last local element, pass in `NULL` if not interested
891: Level: beginner
893: Note:
894: The high argument is one more than the last element stored locally.
896: Fortran Note:
897: `PETSC_NULL_INTEGER` should be used instead of NULL
899: .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRanges()`
900: @*/
901: PetscErrorCode VecGetOwnershipRange(Vec x, PetscInt *low, PetscInt *high)
902: {
903: PetscFunctionBegin;
908: if (low) *low = x->map->rstart;
909: if (high) *high = x->map->rend;
910: PetscFunctionReturn(PETSC_SUCCESS);
911: }
913: /*@C
914: VecGetOwnershipRanges - Returns the range of indices owned by EACH processor,
915: The vector is laid out with the
916: first n1 elements on the first processor, next n2 elements on the
917: second, etc. For certain parallel layouts this range may not be
918: well defined.
920: Not Collective
922: Input Parameter:
923: . x - the vector
925: Output Parameter:
926: . range - array of length size+1 with the start and end+1 for each process
928: Level: beginner
930: Notes:
931: The high argument is one more than the last element stored locally.
933: If the ranges are used after all vectors that share the ranges has been destroyed then the program will crash accessing ranges[].
935: Fortran Note:
936: You must PASS in an array of length size+1
938: .seealso: [](ch_vectors), `Vec`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `VecGetOwnershipRange()`
939: @*/
940: PetscErrorCode VecGetOwnershipRanges(Vec x, const PetscInt *ranges[])
941: {
942: PetscFunctionBegin;
945: PetscCall(PetscLayoutGetRanges(x->map, ranges));
946: PetscFunctionReturn(PETSC_SUCCESS);
947: }
949: /*@
950: VecSetOption - Sets an option for controlling a vector's behavior.
952: Collective
954: Input Parameters:
955: + x - the vector
956: . op - the option
957: - flag - turn the option on or off
959: Supported Options:
960: + `VEC_IGNORE_OFF_PROC_ENTRIES`, which causes `VecSetValues()` to ignore
961: entries destined to be stored on a separate processor. This can be used
962: to eliminate the global reduction in the `VecAssemblyBegin()` if you know
963: that you have only used `VecSetValues()` to set local elements
964: . `VEC_IGNORE_NEGATIVE_INDICES`, which means you can pass negative indices
965: in ix in calls to `VecSetValues()` or `VecGetValues()`. These rows are simply
966: ignored.
967: - `VEC_SUBSET_OFF_PROC_ENTRIES`, which causes `VecAssemblyBegin()` to assume that the off-process
968: entries will always be a subset (possibly equal) of the off-process entries set on the
969: first assembly which had a true `VEC_SUBSET_OFF_PROC_ENTRIES` and the vector has not
970: changed this flag afterwards. If this assembly is not such first assembly, then this
971: assembly can reuse the communication pattern setup in that first assembly, thus avoiding
972: a global reduction. Subsequent assemblies setting off-process values should use the same
973: InsertMode as the first assembly.
975: Level: intermediate
977: Developer Note:
978: The `InsertMode` restriction could be removed by packing the stash messages out of place.
980: .seealso: [](ch_vectors), `Vec`, `VecSetValues()`
981: @*/
982: PetscErrorCode VecSetOption(Vec x, VecOption op, PetscBool flag)
983: {
984: PetscFunctionBegin;
987: PetscTryTypeMethod(x, setoption, op, flag);
988: PetscFunctionReturn(PETSC_SUCCESS);
989: }
991: /* Default routines for obtaining and releasing; */
992: /* may be used by any implementation */
993: PetscErrorCode VecDuplicateVecs_Default(Vec w, PetscInt m, Vec *V[])
994: {
995: PetscFunctionBegin;
998: PetscCheck(m > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "m must be > 0: m = %" PetscInt_FMT, m);
999: PetscCall(PetscMalloc1(m, V));
1000: for (PetscInt i = 0; i < m; i++) PetscCall(VecDuplicate(w, *V + i));
1001: PetscFunctionReturn(PETSC_SUCCESS);
1002: }
1004: PetscErrorCode VecDestroyVecs_Default(PetscInt m, Vec v[])
1005: {
1006: PetscInt i;
1008: PetscFunctionBegin;
1010: for (i = 0; i < m; i++) PetscCall(VecDestroy(&v[i]));
1011: PetscCall(PetscFree(v));
1012: PetscFunctionReturn(PETSC_SUCCESS);
1013: }
1015: /*@
1016: VecResetArray - Resets a vector to use its default memory. Call this
1017: after the use of `VecPlaceArray()`.
1019: Not Collective
1021: Input Parameter:
1022: . vec - the vector
1024: Level: developer
1026: .seealso: [](ch_vectors), `Vec`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`
1027: @*/
1028: PetscErrorCode VecResetArray(Vec vec)
1029: {
1030: PetscFunctionBegin;
1033: PetscUseTypeMethod(vec, resetarray);
1034: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1035: PetscFunctionReturn(PETSC_SUCCESS);
1036: }
1038: /*@C
1039: VecLoad - Loads a vector that has been stored in binary or HDF5 format
1040: with `VecView()`.
1042: Collective
1044: Input Parameters:
1045: + vec - the newly loaded vector, this needs to have been created with `VecCreate()` or
1046: some related function before the call to `VecLoad()`.
1047: - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` or
1048: HDF5 file viewer, obtained from `PetscViewerHDF5Open()`
1050: Level: intermediate
1052: Notes:
1053: Defaults to the standard `VECSEQ` or `VECMPI`, if you want some other type of `Vec` call `VecSetFromOptions()`
1054: before calling this.
1056: The input file must contain the full global vector, as
1057: written by the routine `VecView()`.
1059: If the type or size of `vec` is not set before a call to `VecLoad()`, PETSc
1060: sets the type and the local and global sizes based on the vector it is reading in. If type and/or
1061: sizes are already set, then the same are used.
1063: If using the binary viewer and the blocksize of the vector is greater than one then you must provide a unique prefix to
1064: the vector with `PetscObjectSetOptionsPrefix`((`PetscObject`)vec,"uniqueprefix"); BEFORE calling `VecView()` on the
1065: vector to be stored and then set that same unique prefix on the vector that you pass to VecLoad(). The blocksize
1066: information is stored in an ASCII file with the same name as the binary file plus a ".info" appended to the
1067: filename. If you copy the binary file, make sure you copy the associated .info file with it.
1069: If using HDF5, you must assign the `Vec` the same name as was used in the Vec
1070: that was stored in the file using `PetscObjectSetName(). Otherwise you will
1071: get the error message: "Cannot H5DOpen2() with `Vec` name NAMEOFOBJECT".
1073: If the HDF5 file contains a two dimensional array the first dimension is treated as the block size
1074: in loading the vector. Hence, for example, using MATLAB notation h5create('vector.dat','/Test_Vec',[27 1]);
1075: will load a vector of size 27 and block size 27 thus resulting in all 27 entries being on the first process of
1076: vectors communicator and the rest of the processes having zero entries
1078: Notes for advanced users when using the binary viewer:
1079: Most users should not need to know the details of the binary storage
1080: format, since `VecLoad()` and `VecView()` completely hide these details.
1081: But for anyone who's interested, the standard binary vector storage
1082: format is
1083: .vb
1084: PetscInt VEC_FILE_CLASSID
1085: PetscInt number of rows
1086: PetscScalar *values of all entries
1087: .ve
1089: In addition, PETSc automatically uses byte swapping to work on all machines; the files
1090: are written ALWAYS using big-endian ordering. On small-endian machines the numbers
1091: are converted to the small-endian format when they are read in from the file.
1092: See PetscBinaryRead() and PetscBinaryWrite() to see how this may be done.
1094: .seealso: [](ch_vectors), `Vec`, `PetscViewerBinaryOpen()`, `VecView()`, `MatLoad()`, `VecLoad()`
1095: @*/
1096: PetscErrorCode VecLoad(Vec vec, PetscViewer viewer)
1097: {
1098: PetscBool isbinary, ishdf5, isadios, isexodusii;
1099: PetscViewerFormat format;
1101: PetscFunctionBegin;
1104: PetscCheckSameComm(vec, 1, viewer, 2);
1105: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
1106: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1107: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERADIOS, &isadios));
1108: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWEREXODUSII, &isexodusii));
1109: PetscCheck(isbinary || ishdf5 || isadios || isexodusii, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1111: PetscCall(VecSetErrorIfLocked(vec, 1));
1112: if (!((PetscObject)vec)->type_name && !vec->ops->create) PetscCall(VecSetType(vec, VECSTANDARD));
1113: PetscCall(PetscLogEventBegin(VEC_Load, viewer, 0, 0, 0));
1114: PetscCall(PetscViewerGetFormat(viewer, &format));
1115: if (format == PETSC_VIEWER_NATIVE && vec->ops->loadnative) {
1116: PetscUseTypeMethod(vec, loadnative, viewer);
1117: } else {
1118: PetscUseTypeMethod(vec, load, viewer);
1119: }
1120: PetscCall(PetscLogEventEnd(VEC_Load, viewer, 0, 0, 0));
1121: PetscFunctionReturn(PETSC_SUCCESS);
1122: }
1124: /*@
1125: VecReciprocal - Replaces each component of a vector by its reciprocal.
1127: Logically Collective
1129: Input Parameter:
1130: . vec - the vector
1132: Output Parameter:
1133: . vec - the vector reciprocal
1135: Level: intermediate
1137: Note:
1138: Vector entries with value 0.0 are not changed
1140: .seealso: [](ch_vectors), `Vec`, `VecLog()`, `VecExp()`, `VecSqrtAbs()`
1141: @*/
1142: PetscErrorCode VecReciprocal(Vec vec)
1143: {
1144: PetscFunctionBegin;
1147: VecCheckAssembled(vec);
1148: PetscCall(VecSetErrorIfLocked(vec, 1));
1149: PetscUseTypeMethod(vec, reciprocal);
1150: PetscCall(PetscObjectStateIncrease((PetscObject)vec));
1151: PetscFunctionReturn(PETSC_SUCCESS);
1152: }
1154: /*@C
1155: VecSetOperation - Allows the user to override a particular vector operation.
1157: Logically Collective; No Fortran Support
1159: Input Parameters:
1160: + vec - The vector to modify
1161: . op - The name of the operation
1162: - f - The function that provides the operation.
1164: Notes:
1165: `f` may be `NULL` to remove the operation from `vec`. Depending on the operation this may be
1166: allowed, however some always expect a valid function. In these cases an error will be raised
1167: when calling the interface routine in question.
1169: See `VecOperation` for an up-to-date list of override-able operations. The operations listed
1170: there have the form `VECOP_<OPERATION>`, where `<OPERATION>` is the suffix (in all capital
1171: letters) of the public interface routine (e.g., `VecView()` -> `VECOP_VIEW`).
1173: Overriding a particular `Vec`'s operation has no affect on any other `Vec`s past, present,
1174: or future. The user should also note that overriding a method is "destructive"; the previous
1175: method is not retained in any way.
1177: Level: advanced
1179: Example Usage:
1180: .vb
1181: // some new VecView() implementation, must have the same signature as the function it seeks
1182: // to replace
1183: PetscErrorCode UserVecView(Vec x, PetscViewer viewer)
1184: {
1185: PetscFunctionBeginUser;
1186: // ...
1187: PetscFunctionReturn(PETSC_SUCCESS);
1188: }
1190: // Create a VECMPI which has a pre-defined VecView() implementation
1191: VecCreateMPI(comm, n, N, &x);
1192: // Calls the VECMPI implementation for VecView()
1193: VecView(x, viewer);
1195: VecSetOperation(x, VECOP_VIEW, (void (*)(void))UserVecView);
1196: // Now calls UserVecView()
1197: VecView(x, viewer);
1198: .ve
1200: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `MatShellSetOperation()`
1201: @*/
1202: PetscErrorCode VecSetOperation(Vec vec, VecOperation op, void (*f)(void))
1203: {
1204: PetscFunctionBegin;
1206: if (op == VECOP_VIEW && !vec->ops->viewnative) {
1207: vec->ops->viewnative = vec->ops->view;
1208: } else if (op == VECOP_LOAD && !vec->ops->loadnative) {
1209: vec->ops->loadnative = vec->ops->load;
1210: }
1211: ((void (**)(void))vec->ops)[(int)op] = f;
1212: PetscFunctionReturn(PETSC_SUCCESS);
1213: }
1215: /*@
1216: VecStashSetInitialSize - sets the sizes of the vec-stash, that is
1217: used during the assembly process to store values that belong to
1218: other processors.
1220: Not Collective, different processes can have different size stashes
1222: Input Parameters:
1223: + vec - the vector
1224: . size - the initial size of the stash.
1225: - bsize - the initial size of the block-stash(if used).
1227: Options Database Keys:
1228: + -vecstash_initial_size <size> or <size0,size1,...sizep-1>
1229: - -vecstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
1231: Level: intermediate
1233: Notes:
1234: The block-stash is used for values set with `VecSetValuesBlocked()` while
1235: the stash is used for values set with `VecSetValues()`
1237: Run with the option -info and look for output of the form
1238: VecAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
1239: to determine the appropriate value, MM, to use for size and
1240: VecAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
1241: to determine the value, BMM to use for bsize
1243: PETSc attempts to smartly manage the stash size so there is little likelihood setting a
1244: a specific value here will affect performance
1246: .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`, `VecStashView()`
1247: @*/
1248: PetscErrorCode VecStashSetInitialSize(Vec vec, PetscInt size, PetscInt bsize)
1249: {
1250: PetscFunctionBegin;
1252: PetscCall(VecStashSetInitialSize_Private(&vec->stash, size));
1253: PetscCall(VecStashSetInitialSize_Private(&vec->bstash, bsize));
1254: PetscFunctionReturn(PETSC_SUCCESS);
1255: }
1257: /*@
1258: VecConjugate - Conjugates a vector. That is, replace every entry in a vector with its complex conjugate
1260: Logically Collective
1262: Input Parameter:
1263: . x - the vector
1265: Level: intermediate
1267: .seealso: [](ch_vectors), `Vec`, `VecSet()`
1268: @*/
1269: PetscErrorCode VecConjugate(Vec x)
1270: {
1271: PetscFunctionBegin;
1274: VecCheckAssembled(x);
1275: PetscCall(VecSetErrorIfLocked(x, 1));
1276: if (PetscDefined(USE_COMPLEX)) {
1277: PetscUseTypeMethod(x, conjugate);
1278: /* we need to copy norms here */
1279: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1280: }
1281: PetscFunctionReturn(PETSC_SUCCESS);
1282: }
1284: /*@
1285: VecSetRandom - Sets all components of a vector to random numbers.
1287: Logically Collective
1289: Input Parameters:
1290: + x - the vector
1291: - rctx - the random number context, formed by `PetscRandomCreate()`, or use `NULL` and it will create one internally.
1293: Output Parameter:
1294: . x - the vector
1296: Example of Usage:
1297: .vb
1298: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
1299: VecSetRandom(x,rctx);
1300: PetscRandomDestroy(&rctx);
1301: .ve
1303: Level: intermediate
1305: .seealso: [](ch_vectors), `Vec`, `VecSet()`, `VecSetValues()`, `PetscRandomCreate()`, `PetscRandomDestroy()`
1306: @*/
1307: PetscErrorCode VecSetRandom(Vec x, PetscRandom rctx)
1308: {
1309: PetscRandom randObj = NULL;
1311: PetscFunctionBegin;
1315: VecCheckAssembled(x);
1316: PetscCall(VecSetErrorIfLocked(x, 1));
1318: if (!rctx) {
1319: PetscCall(PetscRandomCreate(PetscObjectComm((PetscObject)x), &randObj));
1320: PetscCall(PetscRandomSetType(randObj, x->defaultrandtype));
1321: PetscCall(PetscRandomSetFromOptions(randObj));
1322: rctx = randObj;
1323: }
1325: PetscCall(PetscLogEventBegin(VEC_SetRandom, x, rctx, 0, 0));
1326: PetscUseTypeMethod(x, setrandom, rctx);
1327: PetscCall(PetscLogEventEnd(VEC_SetRandom, x, rctx, 0, 0));
1329: PetscCall(PetscRandomDestroy(&randObj));
1330: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1331: PetscFunctionReturn(PETSC_SUCCESS);
1332: }
1334: /*@
1335: VecZeroEntries - puts a `0.0` in each element of a vector
1337: Logically Collective
1339: Input Parameter:
1340: . vec - The vector
1342: Level: beginner
1344: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`, `VecSet()`, `VecSetValues()`
1345: @*/
1346: PetscErrorCode VecZeroEntries(Vec vec)
1347: {
1348: PetscFunctionBegin;
1349: PetscCall(VecSet(vec, 0));
1350: PetscFunctionReturn(PETSC_SUCCESS);
1351: }
1353: /*
1354: VecSetTypeFromOptions_Private - Sets the type of vector from user options. Defaults to a PETSc sequential vector on one
1355: processor and a PETSc MPI vector on more than one processor.
1357: Collective
1359: Input Parameter:
1360: . vec - The vector
1362: Level: intermediate
1364: .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`, `VecSetType()`
1365: */
1366: static PetscErrorCode VecSetTypeFromOptions_Private(Vec vec, PetscOptionItems *PetscOptionsObject)
1367: {
1368: PetscBool opt;
1369: VecType defaultType;
1370: char typeName[256];
1371: PetscMPIInt size;
1373: PetscFunctionBegin;
1374: if (((PetscObject)vec)->type_name) defaultType = ((PetscObject)vec)->type_name;
1375: else {
1376: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)vec), &size));
1377: if (size > 1) defaultType = VECMPI;
1378: else defaultType = VECSEQ;
1379: }
1381: PetscCall(VecRegisterAll());
1382: PetscCall(PetscOptionsFList("-vec_type", "Vector type", "VecSetType", VecList, defaultType, typeName, 256, &opt));
1383: if (opt) {
1384: PetscCall(VecSetType(vec, typeName));
1385: } else {
1386: PetscCall(VecSetType(vec, defaultType));
1387: }
1388: PetscFunctionReturn(PETSC_SUCCESS);
1389: }
1391: /*@
1392: VecSetFromOptions - Configures the vector from the options database.
1394: Collective
1396: Input Parameter:
1397: . vec - The vector
1399: Level: beginner
1401: Notes:
1402: To see all options, run your program with the -help option.
1404: Must be called after `VecCreate()` but before the vector is used.
1406: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecSetOptionsPrefix()`
1407: @*/
1408: PetscErrorCode VecSetFromOptions(Vec vec)
1409: {
1410: PetscBool flg;
1411: PetscInt bind_below = 0;
1413: PetscFunctionBegin;
1416: PetscObjectOptionsBegin((PetscObject)vec);
1417: /* Handle vector type options */
1418: PetscCall(VecSetTypeFromOptions_Private(vec, PetscOptionsObject));
1420: /* Handle specific vector options */
1421: PetscTryTypeMethod(vec, setfromoptions, PetscOptionsObject);
1423: /* Bind to CPU if below a user-specified size threshold.
1424: * This perhaps belongs in the options for the GPU Vec types, but VecBindToCPU() does nothing when called on non-GPU types,
1425: * and putting it here makes is more maintainable than duplicating this for all. */
1426: 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));
1427: if (flg && vec->map->n < bind_below) PetscCall(VecBindToCPU(vec, PETSC_TRUE));
1429: /* process any options handlers added with PetscObjectAddOptionsHandler() */
1430: PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)vec, PetscOptionsObject));
1431: PetscOptionsEnd();
1432: PetscFunctionReturn(PETSC_SUCCESS);
1433: }
1435: /*@
1436: VecSetSizes - Sets the local and global sizes, and checks to determine compatibility of the sizes
1438: Collective
1440: Input Parameters:
1441: + v - the vector
1442: . n - the local size (or `PETSC_DECIDE` to have it set)
1443: - N - the global size (or `PETSC_DETERMINE` to have it set)
1445: Level: intermediate
1447: Notes:
1448: `N` cannot be `PETSC_DETERMINE` if `n` is `PETSC_DECIDE`
1450: If one processor calls this with `N` of `PETSC_DETERMINE` then all processors must, otherwise the program will hang.
1452: .seealso: [](ch_vectors), `Vec`, `VecGetSize()`, `PetscSplitOwnership()`
1453: @*/
1454: PetscErrorCode VecSetSizes(Vec v, PetscInt n, PetscInt N)
1455: {
1456: PetscFunctionBegin;
1458: if (N >= 0) {
1460: PetscCheck(n <= N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local size %" PetscInt_FMT " cannot be larger than global size %" PetscInt_FMT, n, N);
1461: }
1462: 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,
1463: v->map->n, v->map->N);
1464: v->map->n = n;
1465: v->map->N = N;
1466: PetscTryTypeMethod(v, create);
1467: v->ops->create = NULL;
1468: PetscFunctionReturn(PETSC_SUCCESS);
1469: }
1471: /*@
1472: VecSetBlockSize - Sets the block size for future calls to `VecSetValuesBlocked()`
1473: and `VecSetValuesBlockedLocal()`.
1475: Logically Collective
1477: Input Parameters:
1478: + v - the vector
1479: - bs - the blocksize
1481: Level: advanced
1483: Note:
1484: All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1486: Vectors obtained with `DMCreateGlobalVector()` and `DMCreateLocalVector()` generally already have a blocksize set based on the state of the `DM`
1488: .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecGetBlockSize()`
1489: @*/
1490: PetscErrorCode VecSetBlockSize(Vec v, PetscInt bs)
1491: {
1492: PetscFunctionBegin;
1495: PetscCall(PetscLayoutSetBlockSize(v->map, bs));
1496: v->bstash.bs = bs; /* use the same blocksize for the vec's block-stash */
1497: PetscFunctionReturn(PETSC_SUCCESS);
1498: }
1500: /*@
1501: VecGetBlockSize - Gets the blocksize for the vector, i.e. what is used for `VecSetValuesBlocked()`
1502: and `VecSetValuesBlockedLocal()`.
1504: Not Collective
1506: Input Parameter:
1507: . v - the vector
1509: Output Parameter:
1510: . bs - the blocksize
1512: Level: advanced
1514: Note:
1515: All vectors obtained by `VecDuplicate()` inherit the same blocksize.
1517: .seealso: [](ch_vectors), `Vec`, `VecSetValuesBlocked()`, `VecSetLocalToGlobalMapping()`, `VecSetBlockSize()`
1518: @*/
1519: PetscErrorCode VecGetBlockSize(Vec v, PetscInt *bs)
1520: {
1521: PetscFunctionBegin;
1524: PetscCall(PetscLayoutGetBlockSize(v->map, bs));
1525: PetscFunctionReturn(PETSC_SUCCESS);
1526: }
1528: /*@C
1529: VecSetOptionsPrefix - Sets the prefix used for searching for all
1530: `Vec` options in the database.
1532: Logically Collective
1534: Input Parameters:
1535: + v - the `Vec` context
1536: - prefix - the prefix to prepend to all option names
1538: Level: advanced
1540: Note:
1541: A hyphen (-) must NOT be given at the beginning of the prefix name.
1542: The first character of all runtime options is AUTOMATICALLY the hyphen.
1544: .seealso: [](ch_vectors), `Vec`, `VecSetFromOptions()`
1545: @*/
1546: PetscErrorCode VecSetOptionsPrefix(Vec v, const char prefix[])
1547: {
1548: PetscFunctionBegin;
1550: PetscCall(PetscObjectSetOptionsPrefix((PetscObject)v, prefix));
1551: PetscFunctionReturn(PETSC_SUCCESS);
1552: }
1554: /*@C
1555: VecAppendOptionsPrefix - Appends to the prefix used for searching for all
1556: `Vec` options in the database.
1558: Logically Collective
1560: Input Parameters:
1561: + v - the `Vec` context
1562: - prefix - the prefix to prepend to all option names
1564: Level: advanced
1566: Note:
1567: A hyphen (-) must NOT be given at the beginning of the prefix name.
1568: The first character of all runtime options is AUTOMATICALLY the hyphen.
1570: .seealso: [](ch_vectors), `Vec`, `VecGetOptionsPrefix()`
1571: @*/
1572: PetscErrorCode VecAppendOptionsPrefix(Vec v, const char prefix[])
1573: {
1574: PetscFunctionBegin;
1576: PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)v, prefix));
1577: PetscFunctionReturn(PETSC_SUCCESS);
1578: }
1580: /*@C
1581: VecGetOptionsPrefix - Sets the prefix used for searching for all
1582: Vec options in the database.
1584: Not Collective
1586: Input Parameter:
1587: . v - the `Vec` context
1589: Output Parameter:
1590: . prefix - pointer to the prefix string used
1592: Level: advanced
1594: Fortran Note:
1595: The user must pass in a string `prefix` of
1596: sufficient length to hold the prefix.
1598: .seealso: [](ch_vectors), `Vec`, `VecAppendOptionsPrefix()`
1599: @*/
1600: PetscErrorCode VecGetOptionsPrefix(Vec v, const char *prefix[])
1601: {
1602: PetscFunctionBegin;
1604: PetscCall(PetscObjectGetOptionsPrefix((PetscObject)v, prefix));
1605: PetscFunctionReturn(PETSC_SUCCESS);
1606: }
1608: /*@
1609: VecSetUp - Sets up the internal vector data structures for the later use.
1611: Collective
1613: Input Parameter:
1614: . v - the `Vec` context
1616: Level: advanced
1618: Notes:
1619: For basic use of the `Vec` classes the user need not explicitly call
1620: `VecSetUp()`, since these actions will happen automatically.
1622: .seealso: [](ch_vectors), `Vec`, `VecCreate()`, `VecDestroy()`
1623: @*/
1624: PetscErrorCode VecSetUp(Vec v)
1625: {
1626: PetscMPIInt size;
1628: PetscFunctionBegin;
1630: PetscCheck(v->map->n >= 0 || v->map->N >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Sizes not set");
1631: if (!((PetscObject)v)->type_name) {
1632: PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)v), &size));
1633: if (size == 1) {
1634: PetscCall(VecSetType(v, VECSEQ));
1635: } else {
1636: PetscCall(VecSetType(v, VECMPI));
1637: }
1638: }
1639: PetscFunctionReturn(PETSC_SUCCESS);
1640: }
1642: /*
1643: These currently expose the PetscScalar/PetscReal in updating the
1644: cached norm. If we push those down into the implementation these
1645: will become independent of PetscScalar/PetscReal
1646: */
1648: /*@
1649: VecCopy - Copies a vector `y = x`
1651: Logically Collective
1653: Input Parameter:
1654: . x - the vector
1656: Output Parameter:
1657: . y - the copy
1659: Level: beginner
1661: Note:
1662: For default parallel PETSc vectors, both `x` and `y` must be distributed in
1663: the same manner; local copies are done.
1665: Developer Note:
1666: `PetscCheckSameTypeAndComm`(x,1,y,2) is not used on these vectors because we allow one
1667: of the vectors to be sequential and one to be parallel so long as both have the same
1668: local sizes. This is used in some internal functions in PETSc.
1670: .seealso: [](ch_vectors), `Vec`, `VecDuplicate()`
1671: @*/
1672: PetscErrorCode VecCopy(Vec x, Vec y)
1673: {
1674: PetscBool flgs[4];
1675: PetscReal norms[4] = {0.0, 0.0, 0.0, 0.0};
1677: PetscFunctionBegin;
1682: if (x == y) PetscFunctionReturn(PETSC_SUCCESS);
1683: VecCheckSameLocalSize(x, 1, y, 2);
1684: VecCheckAssembled(x);
1685: PetscCall(VecSetErrorIfLocked(y, 2));
1687: #if !defined(PETSC_USE_MIXED_PRECISION)
1688: for (PetscInt i = 0; i < 4; i++) PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]));
1689: #endif
1691: PetscCall(PetscLogEventBegin(VEC_Copy, x, y, 0, 0));
1692: #if defined(PETSC_USE_MIXED_PRECISION)
1693: extern PetscErrorCode VecGetArray(Vec, double **);
1694: extern PetscErrorCode VecRestoreArray(Vec, double **);
1695: extern PetscErrorCode VecGetArray(Vec, float **);
1696: extern PetscErrorCode VecRestoreArray(Vec, float **);
1697: extern PetscErrorCode VecGetArrayRead(Vec, const double **);
1698: extern PetscErrorCode VecRestoreArrayRead(Vec, const double **);
1699: extern PetscErrorCode VecGetArrayRead(Vec, const float **);
1700: extern PetscErrorCode VecRestoreArrayRead(Vec, const float **);
1701: if ((((PetscObject)x)->precision == PETSC_PRECISION_SINGLE) && (((PetscObject)y)->precision == PETSC_PRECISION_DOUBLE)) {
1702: PetscInt i, n;
1703: const float *xx;
1704: double *yy;
1705: PetscCall(VecGetArrayRead(x, &xx));
1706: PetscCall(VecGetArray(y, &yy));
1707: PetscCall(VecGetLocalSize(x, &n));
1708: for (i = 0; i < n; i++) yy[i] = xx[i];
1709: PetscCall(VecRestoreArrayRead(x, &xx));
1710: PetscCall(VecRestoreArray(y, &yy));
1711: } else if ((((PetscObject)x)->precision == PETSC_PRECISION_DOUBLE) && (((PetscObject)y)->precision == PETSC_PRECISION_SINGLE)) {
1712: PetscInt i, n;
1713: float *yy;
1714: const double *xx;
1715: PetscCall(VecGetArrayRead(x, &xx));
1716: PetscCall(VecGetArray(y, &yy));
1717: PetscCall(VecGetLocalSize(x, &n));
1718: for (i = 0; i < n; i++) yy[i] = (float)xx[i];
1719: PetscCall(VecRestoreArrayRead(x, &xx));
1720: PetscCall(VecRestoreArray(y, &yy));
1721: } else PetscUseTypeMethod(x, copy, y);
1722: #else
1723: PetscUseTypeMethod(x, copy, y);
1724: #endif
1726: PetscCall(PetscObjectStateIncrease((PetscObject)y));
1727: #if !defined(PETSC_USE_MIXED_PRECISION)
1728: for (PetscInt i = 0; i < 4; i++) {
1729: if (flgs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], norms[i]));
1730: }
1731: #endif
1733: PetscCall(PetscLogEventEnd(VEC_Copy, x, y, 0, 0));
1734: PetscFunctionReturn(PETSC_SUCCESS);
1735: }
1737: /*@
1738: VecSwap - Swaps the values between two vectors, `x` and `y`.
1740: Logically Collective
1742: Input Parameters:
1743: + x - the first vector
1744: - y - the second vector
1746: Level: advanced
1748: .seealso: [](ch_vectors), `Vec`, `VecSet()`
1749: @*/
1750: PetscErrorCode VecSwap(Vec x, Vec y)
1751: {
1752: PetscReal normxs[4], normys[4];
1753: PetscBool flgxs[4], flgys[4];
1755: PetscFunctionBegin;
1760: PetscCheckSameTypeAndComm(x, 1, y, 2);
1761: VecCheckSameSize(x, 1, y, 2);
1762: VecCheckAssembled(x);
1763: VecCheckAssembled(y);
1764: PetscCall(VecSetErrorIfLocked(x, 1));
1765: PetscCall(VecSetErrorIfLocked(y, 2));
1767: for (PetscInt i = 0; i < 4; i++) {
1768: PetscCall(PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], normxs[i], flgxs[i]));
1769: PetscCall(PetscObjectComposedDataGetReal((PetscObject)y, NormIds[i], normys[i], flgys[i]));
1770: }
1772: PetscCall(PetscLogEventBegin(VEC_Swap, x, y, 0, 0));
1773: PetscUseTypeMethod(x, swap, y);
1774: PetscCall(PetscLogEventEnd(VEC_Swap, x, y, 0, 0));
1776: PetscCall(PetscObjectStateIncrease((PetscObject)x));
1777: PetscCall(PetscObjectStateIncrease((PetscObject)y));
1778: for (PetscInt i = 0; i < 4; i++) {
1779: if (flgxs[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)y, NormIds[i], normxs[i]));
1780: if (flgys[i]) PetscCall(PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], normys[i]));
1781: }
1782: PetscFunctionReturn(PETSC_SUCCESS);
1783: }
1785: /*@C
1786: VecStashViewFromOptions - Processes command line options to determine if/how a `VecStash` object is to be viewed.
1788: Collective
1790: Input Parameters:
1791: + obj - the `Vec` containing a stash
1792: . bobj - optional other object that provides the prefix
1793: - optionname - option to activate viewing
1795: Level: intermediate
1797: Developer Note:
1798: This cannot use `PetscObjectViewFromOptions()` because it takes a `Vec` as an argument but does not use `VecView()`
1800: .seealso: [](ch_vectors), `Vec`, `VecStashSetInitialSize()`
1801: @*/
1802: PetscErrorCode VecStashViewFromOptions(Vec obj, PetscObject bobj, const char optionname[])
1803: {
1804: PetscViewer viewer;
1805: PetscBool flg;
1806: PetscViewerFormat format;
1807: char *prefix;
1809: PetscFunctionBegin;
1810: prefix = bobj ? bobj->prefix : ((PetscObject)obj)->prefix;
1811: PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)obj), ((PetscObject)obj)->options, prefix, optionname, &viewer, &format, &flg));
1812: if (flg) {
1813: PetscCall(PetscViewerPushFormat(viewer, format));
1814: PetscCall(VecStashView(obj, viewer));
1815: PetscCall(PetscViewerPopFormat(viewer));
1816: PetscCall(PetscViewerDestroy(&viewer));
1817: }
1818: PetscFunctionReturn(PETSC_SUCCESS);
1819: }
1821: /*@
1822: VecStashView - Prints the entries in the vector stash and block stash.
1824: Collective
1826: Input Parameters:
1827: + v - the vector
1828: - viewer - the viewer
1830: Level: advanced
1832: .seealso: [](ch_vectors), `Vec`, `VecSetBlockSize()`, `VecSetValues()`, `VecSetValuesBlocked()`
1833: @*/
1834: PetscErrorCode VecStashView(Vec v, PetscViewer viewer)
1835: {
1836: PetscMPIInt rank;
1837: PetscInt i, j;
1838: PetscBool match;
1839: VecStash *s;
1840: PetscScalar val;
1842: PetscFunctionBegin;
1845: PetscCheckSameComm(v, 1, viewer, 2);
1847: PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &match));
1848: PetscCheck(match, PETSC_COMM_SELF, PETSC_ERR_SUP, "Stash viewer only works with ASCII viewer not %s", ((PetscObject)v)->type_name);
1849: PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1850: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)v), &rank));
1851: s = &v->bstash;
1853: /* print block stash */
1854: PetscCall(PetscViewerASCIIPushSynchronized(viewer));
1855: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector Block stash size %" PetscInt_FMT " block size %" PetscInt_FMT "\n", rank, s->n, s->bs));
1856: for (i = 0; i < s->n; i++) {
1857: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " ", rank, s->idx[i]));
1858: for (j = 0; j < s->bs; j++) {
1859: val = s->array[i * s->bs + j];
1860: #if defined(PETSC_USE_COMPLEX)
1861: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "(%18.16e %18.16e) ", (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1862: #else
1863: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%18.16e ", (double)val));
1864: #endif
1865: }
1866: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "\n"));
1867: }
1868: PetscCall(PetscViewerFlush(viewer));
1870: s = &v->stash;
1872: /* print basic stash */
1873: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Vector stash size %" PetscInt_FMT "\n", rank, s->n));
1874: for (i = 0; i < s->n; i++) {
1875: val = s->array[i];
1876: #if defined(PETSC_USE_COMPLEX)
1877: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " (%18.16e %18.16e) ", rank, s->idx[i], (double)PetscRealPart(val), (double)PetscImaginaryPart(val)));
1878: #else
1879: PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d] Element %" PetscInt_FMT " %18.16e\n", rank, s->idx[i], (double)val));
1880: #endif
1881: }
1882: PetscCall(PetscViewerFlush(viewer));
1883: PetscCall(PetscViewerASCIIPopSynchronized(viewer));
1884: PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1885: PetscFunctionReturn(PETSC_SUCCESS);
1886: }
1888: PetscErrorCode PetscOptionsGetVec(PetscOptions options, const char prefix[], const char key[], Vec v, PetscBool *set)
1889: {
1890: PetscInt i, N, rstart, rend;
1891: PetscScalar *xx;
1892: PetscReal *xreal;
1893: PetscBool iset;
1895: PetscFunctionBegin;
1896: PetscCall(VecGetOwnershipRange(v, &rstart, &rend));
1897: PetscCall(VecGetSize(v, &N));
1898: PetscCall(PetscCalloc1(N, &xreal));
1899: PetscCall(PetscOptionsGetRealArray(options, prefix, key, xreal, &N, &iset));
1900: if (iset) {
1901: PetscCall(VecGetArray(v, &xx));
1902: for (i = rstart; i < rend; i++) xx[i - rstart] = xreal[i];
1903: PetscCall(VecRestoreArray(v, &xx));
1904: }
1905: PetscCall(PetscFree(xreal));
1906: if (set) *set = iset;
1907: PetscFunctionReturn(PETSC_SUCCESS);
1908: }
1910: /*@
1911: VecGetLayout - get `PetscLayout` describing a vector layout
1913: Not Collective
1915: Input Parameter:
1916: . x - the vector
1918: Output Parameter:
1919: . map - the layout
1921: Level: developer
1923: Note:
1924: The layout determines what vector elements are contained on each MPI process
1926: .seealso: [](ch_vectors), `PetscLayout`, `Vec`, `VecGetSizes()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1927: @*/
1928: PetscErrorCode VecGetLayout(Vec x, PetscLayout *map)
1929: {
1930: PetscFunctionBegin;
1933: *map = x->map;
1934: PetscFunctionReturn(PETSC_SUCCESS);
1935: }
1937: /*@
1938: VecSetLayout - set `PetscLayout` describing vector layout
1940: Not Collective
1942: Input Parameters:
1943: + x - the vector
1944: - map - the layout
1946: Level: developer
1948: Note:
1949: It is normally only valid to replace the layout with a layout known to be equivalent.
1951: .seealso: [](ch_vectors), `Vec`, `PetscLayout`, `VecGetLayout()`, `VecGetSizes()`, `VecGetOwnershipRange()`, `VecGetOwnershipRanges()`
1952: @*/
1953: PetscErrorCode VecSetLayout(Vec x, PetscLayout map)
1954: {
1955: PetscFunctionBegin;
1957: PetscCall(PetscLayoutReference(map, &x->map));
1958: PetscFunctionReturn(PETSC_SUCCESS);
1959: }
1961: PetscErrorCode VecSetInf(Vec xin)
1962: {
1963: // use of variables one and zero over just doing 1.0/0.0 is deliberate. MSVC complains that
1964: // we are dividing by zero in the latter case (ostensibly because dividing by 0 is UB, but
1965: // only for *integers* not floats).
1966: const PetscScalar one = 1.0, zero = 0.0;
1967: PetscScalar inf;
1969: PetscFunctionBegin;
1970: PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
1971: inf = one / zero;
1972: PetscCall(PetscFPTrapPop());
1973: if (xin->ops->set) {
1974: PetscUseTypeMethod(xin, set, inf);
1975: } else {
1976: PetscInt n;
1977: PetscScalar *xx;
1979: PetscCall(VecGetLocalSize(xin, &n));
1980: PetscCall(VecGetArrayWrite(xin, &xx));
1981: for (PetscInt i = 0; i < n; ++i) xx[i] = inf;
1982: PetscCall(VecRestoreArrayWrite(xin, &xx));
1983: }
1984: PetscFunctionReturn(PETSC_SUCCESS);
1985: }
1987: /*@
1988: VecBindToCPU - marks a vector to temporarily stay on the CPU and perform computations on the CPU
1990: Logically collective
1992: Input Parameters:
1993: + v - the vector
1994: - flg - bind to the CPU if value of `PETSC_TRUE`
1996: Level: intermediate
1998: .seelaso: [](ch_vectors), `Vec`, `VecBoundToCPU()`
1999: @*/
2000: PetscErrorCode VecBindToCPU(Vec v, PetscBool flg)
2001: {
2002: PetscFunctionBegin;
2005: #if defined(PETSC_HAVE_DEVICE)
2006: if (v->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS);
2007: v->boundtocpu = flg;
2008: PetscTryTypeMethod(v, bindtocpu, flg);
2009: #endif
2010: PetscFunctionReturn(PETSC_SUCCESS);
2011: }
2013: /*@
2014: VecBoundToCPU - query if a vector is bound to the CPU
2016: Not collective
2018: Input Parameter:
2019: . v - the vector
2021: Output Parameter:
2022: . flg - the logical flag
2024: Level: intermediate
2026: .seealso: [](ch_vectors), `Vec`, `VecBindToCPU()`
2027: @*/
2028: PetscErrorCode VecBoundToCPU(Vec v, PetscBool *flg)
2029: {
2030: PetscFunctionBegin;
2033: #if defined(PETSC_HAVE_DEVICE)
2034: *flg = v->boundtocpu;
2035: #else
2036: *flg = PETSC_TRUE;
2037: #endif
2038: PetscFunctionReturn(PETSC_SUCCESS);
2039: }
2041: /*@
2042: VecSetBindingPropagates - Sets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2044: Input Parameters:
2045: + v - the vector
2046: - flg - flag indicating whether the boundtocpu flag should be propagated
2048: Level: developer
2050: Notes:
2051: 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.
2052: The created vectors will also have their bindingpropagates flag set to true.
2054: Developer Note:
2055: If a `DMDA` has the `-dm_bind_below option` set to true, then vectors created by `DMCreateGlobalVector()` will have `VecSetBindingPropagates()` called on them to
2056: set their bindingpropagates flag to true.
2058: .seealso: [](ch_vectors), `Vec`, `MatSetBindingPropagates()`, `VecGetBindingPropagates()`
2059: @*/
2060: PetscErrorCode VecSetBindingPropagates(Vec v, PetscBool flg)
2061: {
2062: PetscFunctionBegin;
2064: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2065: v->bindingpropagates = flg;
2066: #endif
2067: PetscFunctionReturn(PETSC_SUCCESS);
2068: }
2070: /*@
2071: VecGetBindingPropagates - Gets whether the state of being bound to the CPU for a GPU vector type propagates to child and some other associated objects
2073: Input Parameter:
2074: . v - the vector
2076: Output Parameter:
2077: . flg - flag indicating whether the boundtocpu flag will be propagated
2079: Level: developer
2081: .seealso: [](ch_vectors), `Vec`, `VecSetBindingPropagates()`
2082: @*/
2083: PetscErrorCode VecGetBindingPropagates(Vec v, PetscBool *flg)
2084: {
2085: PetscFunctionBegin;
2088: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2089: *flg = v->bindingpropagates;
2090: #else
2091: *flg = PETSC_FALSE;
2092: #endif
2093: PetscFunctionReturn(PETSC_SUCCESS);
2094: }
2096: /*@C
2097: VecSetPinnedMemoryMin - Set the minimum data size for which pinned memory will be used for host (CPU) allocations.
2099: Logically Collective
2101: Input Parameters:
2102: + v - the vector
2103: - mbytes - minimum data size in bytes
2105: Options Database Key:
2106: . -vec_pinned_memory_min <size> - minimum size (in bytes) for an allocation to use pinned memory on host.
2108: Level: developer
2110: Note:
2111: Specifying -1 ensures that pinned memory will never be used.
2113: .seealso: [](ch_vectors), `Vec`, `VecGetPinnedMemoryMin()`
2114: @*/
2115: PetscErrorCode VecSetPinnedMemoryMin(Vec v, size_t mbytes)
2116: {
2117: PetscFunctionBegin;
2119: #if PetscDefined(HAVE_DEVICE)
2120: v->minimum_bytes_pinned_memory = mbytes;
2121: #endif
2122: PetscFunctionReturn(PETSC_SUCCESS);
2123: }
2125: /*@C
2126: VecGetPinnedMemoryMin - Get the minimum data size for which pinned memory will be used for host (CPU) allocations.
2128: Logically Collective
2130: Input Parameter:
2131: . v - the vector
2133: Output Parameter:
2134: . mbytes - minimum data size in bytes
2136: Level: developer
2138: .seealso: [](ch_vectors), `Vec`, `VecSetPinnedMemoryMin()`
2139: @*/
2140: PetscErrorCode VecGetPinnedMemoryMin(Vec v, size_t *mbytes)
2141: {
2142: PetscFunctionBegin;
2145: #if PetscDefined(HAVE_DEVICE)
2146: *mbytes = v->minimum_bytes_pinned_memory;
2147: #endif
2148: PetscFunctionReturn(PETSC_SUCCESS);
2149: }
2151: /*@
2152: VecGetOffloadMask - Get the offload mask of a `Vec`
2154: Not Collective
2156: Input Parameter:
2157: . v - the vector
2159: Output Parameter:
2160: . mask - corresponding `PetscOffloadMask` enum value.
2162: Level: intermediate
2164: .seealso: [](ch_vectors), `Vec`, `VecCreateSeqCUDA()`, `VecCreateSeqViennaCL()`, `VecGetArray()`, `VecGetType()`
2165: @*/
2166: PetscErrorCode VecGetOffloadMask(Vec v, PetscOffloadMask *mask)
2167: {
2168: PetscFunctionBegin;
2171: *mask = v->offloadmask;
2172: PetscFunctionReturn(PETSC_SUCCESS);
2173: }
2175: #if !defined(PETSC_HAVE_VIENNACL)
2176: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLContext(Vec v, PETSC_UINTPTR_T *ctx)
2177: {
2178: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_context");
2179: }
2181: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLQueue(Vec v, PETSC_UINTPTR_T *queue)
2182: {
2183: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_command_queue");
2184: }
2186: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMem(Vec v, PETSC_UINTPTR_T *queue)
2187: {
2188: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2189: }
2191: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemRead(Vec v, PETSC_UINTPTR_T *queue)
2192: {
2193: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2194: }
2196: PETSC_EXTERN PetscErrorCode VecViennaCLGetCLMemWrite(Vec v, PETSC_UINTPTR_T *queue)
2197: {
2198: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to get a Vec's cl_mem");
2199: }
2201: PETSC_EXTERN PetscErrorCode VecViennaCLRestoreCLMemWrite(Vec v)
2202: {
2203: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "PETSc must be configured with --with-opencl to restore a Vec's cl_mem");
2204: }
2205: #endif