Actual source code: rvector.c
1: /*
2: Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
3: These are the vector functions the user calls.
4: */
5: #include "petsc/private/sfimpl.h"
6: #include "petscsystypes.h"
7: #include <petsc/private/vecimpl.h>
8: #if defined(PETSC_HAVE_CUDA)
9: #include <../src/vec/vec/impls/dvecimpl.h>
10: #include <petsc/private/cudavecimpl.h>
11: #endif
12: #if defined(PETSC_HAVE_HIP)
13: #include <../src/vec/vec/impls/dvecimpl.h>
14: #include <petsc/private/hipvecimpl.h>
15: #endif
16: PetscInt VecGetSubVectorSavedStateId = -1;
18: #if PetscDefined(USE_DEBUG)
19: // this is a no-op '0' macro in optimized builds
20: PetscErrorCode VecValidValues_Internal(Vec vec, PetscInt argnum, PetscBool begin)
21: {
22: if (vec->petscnative || vec->ops->getarray) {
23: PetscInt n;
24: const PetscScalar *x;
25: PetscOffloadMask mask;
27: VecGetOffloadMask(vec, &mask);
28: if (!PetscOffloadHost(mask)) return 0;
29: VecGetLocalSize(vec, &n);
30: VecGetArrayRead(vec, &x);
31: for (PetscInt i = 0; i < n; i++) {
32: if (begin) {
34: } else {
36: }
37: }
38: VecRestoreArrayRead(vec, &x);
39: }
40: return 0;
41: }
42: #endif
44: /*@
45: VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
47: Logically Collective on Vec
49: Input Parameters:
50: . x, y - the vectors
52: Output Parameter:
53: . max - the result
55: Level: advanced
57: Notes:
58: x and y may be the same vector
59: if a particular y_i is zero, it is treated as 1 in the above formula
61: .seealso: `VecPointwiseDivide()`, `VecPointwiseMult()`, `VecPointwiseMax()`, `VecPointwiseMin()`, `VecPointwiseMaxAbs()`
62: @*/
63: PetscErrorCode VecMaxPointwiseDivide(Vec x, Vec y, PetscReal *max)
64: {
71: VecCheckSameSize(x, 1, y, 2);
72: VecLockReadPush(x);
73: VecLockReadPush(y);
74: PetscUseTypeMethod(x, maxpointwisedivide, y, max);
75: VecLockReadPop(x);
76: VecLockReadPop(y);
77: return 0;
78: }
80: /*@
81: VecDot - Computes the vector dot product.
83: Collective on Vec
85: Input Parameters:
86: . x, y - the vectors
88: Output Parameter:
89: . val - the dot product
91: Performance Issues:
92: $ per-processor memory bandwidth
93: $ interprocessor latency
94: $ work load imbalance that causes certain processes to arrive much earlier than others
96: Notes for Users of Complex Numbers:
97: For complex vectors, VecDot() computes
98: $ val = (x,y) = y^H x,
99: where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex
100: inner product where the SECOND argument gets the complex conjugate. Since the BLASdot() complex conjugates the first
101: first argument we call the BLASdot() with the arguments reversed.
103: Use VecTDot() for the indefinite form
104: $ val = (x,y) = y^T x,
105: where y^T denotes the transpose of y.
107: Level: intermediate
109: .seealso: `VecMDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecDotRealPart()`
110: @*/
111: PetscErrorCode VecDot(Vec x, Vec y, PetscScalar *val)
112: {
119: VecCheckSameSize(x, 1, y, 2);
121: VecLockReadPush(x);
122: VecLockReadPush(y);
123: PetscLogEventBegin(VEC_Dot, x, y, 0, 0);
124: PetscUseTypeMethod(x, dot, y, val);
125: PetscLogEventEnd(VEC_Dot, x, y, 0, 0);
126: VecLockReadPop(x);
127: VecLockReadPop(y);
128: return 0;
129: }
131: /*@
132: VecDotRealPart - Computes the real part of the vector dot product.
134: Collective on Vec
136: Input Parameters:
137: . x, y - the vectors
139: Output Parameter:
140: . val - the real part of the dot product;
142: Performance Issues:
143: $ per-processor memory bandwidth
144: $ interprocessor latency
145: $ work load imbalance that causes certain processes to arrive much earlier than others
147: Notes for Users of Complex Numbers:
148: See VecDot() for more details on the definition of the dot product for complex numbers
150: For real numbers this returns the same value as VecDot()
152: For complex numbers in C^n (that is a vector of n components with a complex number for each component) this is equal to the usual real dot product on the
153: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
155: Developer Note: This is not currently optimized to compute only the real part of the dot product.
157: Level: intermediate
159: .seealso: `VecMDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecDot()`, `VecDotNorm2()`
160: @*/
161: PetscErrorCode VecDotRealPart(Vec x, Vec y, PetscReal *val)
162: {
163: PetscScalar fdot;
165: VecDot(x, y, &fdot);
166: *val = PetscRealPart(fdot);
167: return 0;
168: }
170: /*@
171: VecNorm - Computes the vector norm.
173: Collective on Vec
175: Input Parameters:
176: + x - the vector
177: - type - the type of the norm requested
179: Output Parameter:
180: . val - the norm
182: Values of NormType:
183: + NORM_1 - sum_i |x_i|
184: . NORM_2 - sqrt(sum_i |x_i|^2)
185: . NORM_INFINITY - max_i |x_i|
186: - NORM_1_AND_2 - computes efficiently both NORM_1 and NORM_2 and stores them each in an output array
188: Notes:
189: For complex numbers NORM_1 will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
190: norm of the absolute values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
191: the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
192: people expect the former.
194: This routine stashes the computed norm value, repeated calls before the vector entries are changed are then rapid since the
195: precomputed value is immediately available. Certain vector operations such as VecSet() store the norms so the value is
196: immediately available and does not need to be explicitly computed. VecScale() updates any stashed norm values, thus calls after VecScale()
197: do not need to explicitly recompute the norm.
199: Level: intermediate
201: Performance Issues:
202: + per-processor memory bandwidth - limits the speed of the computation of local portion of the norm
203: . interprocessor latency - limits the accumulation of the result across ranks, .i.e. MPI_Allreduce() time
204: . number of ranks - the time for the result will grow with the log base 2 of the number of ranks sharing the vector
205: - work load imbalance - the rank with the largest number of vector entries will limit the speed up
207: .seealso: `VecDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecNormAvailable()`,
208: `VecNormBegin()`, `VecNormEnd()`, `NormType()`
210: @*/
211: PetscErrorCode VecNorm(Vec x, NormType type, PetscReal *val)
212: {
217: /* Cached data? */
218: if (type != NORM_1_AND_2) {
219: PetscBool flg;
221: PetscObjectComposedDataGetReal((PetscObject)x, NormIds[type], *val, flg);
222: if (flg) return 0;
223: }
225: VecLockReadPush(x);
226: PetscLogEventBegin(VEC_Norm, x, 0, 0, 0);
227: PetscUseTypeMethod(x, norm, type, val);
228: PetscLogEventEnd(VEC_Norm, x, 0, 0, 0);
229: VecLockReadPop(x);
231: if (type != NORM_1_AND_2) PetscObjectComposedDataSetReal((PetscObject)x, NormIds[type], *val);
232: return 0;
233: }
235: /*@
236: VecNormAvailable - Returns the vector norm if it is already known.
238: Not Collective
240: Input Parameters:
241: + x - the vector
242: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
243: NORM_1_AND_2, which computes both norms and stores them
244: in a two element array.
246: Output Parameters:
247: + available - PETSC_TRUE if the val returned is valid
248: - val - the norm
250: Notes:
251: $ NORM_1 denotes sum_i |x_i|
252: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
253: $ NORM_INFINITY denotes max_i |x_i|
255: Level: intermediate
257: Performance Issues:
258: $ per-processor memory bandwidth
259: $ interprocessor latency
260: $ work load imbalance that causes certain processes to arrive much earlier than others
262: Compile Option:
263: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
264: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
265: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
267: .seealso: `VecDot()`, `VecTDot()`, `VecNorm()`, `VecDotBegin()`, `VecDotEnd()`, `VecNorm()`
268: `VecNormBegin()`, `VecNormEnd()`
270: @*/
271: PetscErrorCode VecNormAvailable(Vec x, NormType type, PetscBool *available, PetscReal *val)
272: {
278: if (type == NORM_1_AND_2) {
279: *available = PETSC_FALSE;
280: } else {
281: PetscObjectComposedDataGetReal((PetscObject)x, NormIds[type], *val, *available);
282: }
283: return 0;
284: }
286: /*@
287: VecNormalize - Normalizes a vector by 2-norm.
289: Collective on Vec
291: Input Parameter:
292: . x - the vector
294: Output Parameter:
295: . val - the vector norm before normalization. May be `NULL` if the value is not needed.
297: Level: intermediate
299: @*/
300: PetscErrorCode VecNormalize(Vec x, PetscReal *val)
301: {
302: PetscReal norm;
306: VecSetErrorIfLocked(x, 1);
308: PetscLogEventBegin(VEC_Normalize, x, 0, 0, 0);
309: VecNorm(x, NORM_2, &norm);
310: if (norm == 0.0) {
311: PetscInfo(x, "Vector of zero norm can not be normalized; Returning only the zero norm\n");
312: } else if (norm != 1.0) {
313: VecScale(x, 1.0 / norm);
314: }
315: PetscLogEventEnd(VEC_Normalize, x, 0, 0, 0);
316: if (val) *val = norm;
317: return 0;
318: }
320: /*@C
321: VecMax - Determines the vector component with maximum real part and its location.
323: Collective on Vec
325: Input Parameter:
326: . x - the vector
328: Output Parameters:
329: + p - the location of val (pass NULL if you don't want this)
330: - val - the maximum component
332: Notes:
333: Returns the value PETSC_MIN_REAL and negative p if the vector is of length 0.
335: Returns the smallest index with the maximum value
336: Level: intermediate
338: .seealso: `VecNorm()`, `VecMin()`
339: @*/
340: PetscErrorCode VecMax(Vec x, PetscInt *p, PetscReal *val)
341: {
346: VecLockReadPush(x);
347: PetscLogEventBegin(VEC_Max, x, 0, 0, 0);
348: PetscUseTypeMethod(x, max, p, val);
349: PetscLogEventEnd(VEC_Max, x, 0, 0, 0);
350: VecLockReadPop(x);
351: return 0;
352: }
354: /*@C
355: VecMin - Determines the vector component with minimum real part and its location.
357: Collective on Vec
359: Input Parameter:
360: . x - the vector
362: Output Parameters:
363: + p - the location of val (pass NULL if you don't want this location)
364: - val - the minimum component
366: Level: intermediate
368: Notes:
369: Returns the value PETSC_MAX_REAL and negative p if the vector is of length 0.
371: This returns the smallest index with the minumum value
373: .seealso: `VecMax()`
374: @*/
375: PetscErrorCode VecMin(Vec x, PetscInt *p, PetscReal *val)
376: {
381: VecLockReadPush(x);
382: PetscLogEventBegin(VEC_Min, x, 0, 0, 0);
383: PetscUseTypeMethod(x, min, p, val);
384: PetscLogEventEnd(VEC_Min, x, 0, 0, 0);
385: VecLockReadPop(x);
386: return 0;
387: }
389: /*@
390: VecTDot - Computes an indefinite vector dot product. That is, this
391: routine does NOT use the complex conjugate.
393: Collective on Vec
395: Input Parameters:
396: . x, y - the vectors
398: Output Parameter:
399: . val - the dot product
401: Notes for Users of Complex Numbers:
402: For complex vectors, VecTDot() computes the indefinite form
403: $ val = (x,y) = y^T x,
404: where y^T denotes the transpose of y.
406: Use VecDot() for the inner product
407: $ val = (x,y) = y^H x,
408: where y^H denotes the conjugate transpose of y.
410: Level: intermediate
412: .seealso: `VecDot()`, `VecMTDot()`
413: @*/
414: PetscErrorCode VecTDot(Vec x, Vec y, PetscScalar *val)
415: {
422: VecCheckSameSize(x, 1, y, 2);
424: VecLockReadPush(x);
425: VecLockReadPush(y);
426: PetscLogEventBegin(VEC_TDot, x, y, 0, 0);
427: PetscUseTypeMethod(x, tdot, y, val);
428: PetscLogEventEnd(VEC_TDot, x, y, 0, 0);
429: VecLockReadPop(x);
430: VecLockReadPop(y);
431: return 0;
432: }
434: /*@
435: VecScale - Scales a vector.
437: Not collective on Vec
439: Input Parameters:
440: + x - the vector
441: - alpha - the scalar
443: Note:
444: For a vector with n components, VecScale() computes
445: $ x[i] = alpha * x[i], for i=1,...,n.
447: Level: intermediate
449: @*/
450: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
451: {
452: PetscReal norms[4];
453: PetscBool flgs[4];
458: VecSetErrorIfLocked(x, 1);
459: if (alpha == (PetscScalar)1.0) return 0;
461: /* get current stashed norms */
462: for (PetscInt i = 0; i < 4; i++) PetscObjectComposedDataGetReal((PetscObject)x, NormIds[i], norms[i], flgs[i]);
464: PetscLogEventBegin(VEC_Scale, x, 0, 0, 0);
465: PetscUseTypeMethod(x, scale, alpha);
466: PetscLogEventEnd(VEC_Scale, x, 0, 0, 0);
468: PetscObjectStateIncrease((PetscObject)x);
469: /* put the scaled stashed norms back into the Vec */
470: for (PetscInt i = 0; i < 4; i++) {
471: if (flgs[i]) PetscObjectComposedDataSetReal((PetscObject)x, NormIds[i], PetscAbsScalar(alpha) * norms[i]);
472: }
473: return 0;
474: }
476: /*@
477: VecSet - Sets all components of a vector to a single scalar value.
479: Logically Collective on Vec
481: Input Parameters:
482: + x - the vector
483: - alpha - the scalar
485: Output Parameter:
486: . x - the vector
488: Note:
489: For a vector of dimension n, VecSet() computes
490: $ x[i] = alpha, for i=1,...,n,
491: so that all vector entries then equal the identical
492: scalar value, alpha. Use the more general routine
493: VecSetValues() to set different vector entries.
495: You CANNOT call this after you have called VecSetValues() but before you call
496: VecAssemblyBegin/End().
498: Level: beginner
500: .seealso `VecSetValues()`, `VecSetValuesBlocked()`, `VecSetRandom()`
502: @*/
503: PetscErrorCode VecSet(Vec x, PetscScalar alpha)
504: {
509: VecSetErrorIfLocked(x, 1);
511: PetscLogEventBegin(VEC_Set, x, 0, 0, 0);
512: PetscUseTypeMethod(x, set, alpha);
513: PetscLogEventEnd(VEC_Set, x, 0, 0, 0);
514: PetscObjectStateIncrease((PetscObject)x);
516: /* norms can be simply set (if |alpha|*N not too large) */
518: {
519: PetscReal val = PetscAbsScalar(alpha);
520: const PetscInt N = x->map->N;
522: if (N == 0) {
523: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], 0.0l);
524: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], 0.0);
525: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], 0.0);
526: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], 0.0);
527: } else if (val > PETSC_MAX_REAL / N) {
528: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val);
529: } else {
530: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_1], N * val);
531: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_INFINITY], val);
532: val = PetscSqrtReal((PetscReal)N) * val;
533: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_2], val);
534: PetscObjectComposedDataSetReal((PetscObject)x, NormIds[NORM_FROBENIUS], val);
535: }
536: }
537: return 0;
538: }
540: /*@
541: VecAXPY - Computes y = alpha x + y.
543: Logically Collective on Vec
545: Input Parameters:
546: + alpha - the scalar
547: - x, y - the vectors
549: Output Parameter:
550: . y - output vector
552: Level: intermediate
554: Notes:
555: x and y MUST be different vectors
556: This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
558: $ VecAXPY(y,alpha,x) y = alpha x + y
559: $ VecAYPX(y,beta,x) y = x + beta y
560: $ VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
561: $ VecWAXPY(w,alpha,x,y) w = alpha x + y
562: $ VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
563: $ VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
565: .seealso: `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
566: @*/
567: PetscErrorCode VecAXPY(Vec y, PetscScalar alpha, Vec x)
568: {
574: VecCheckSameSize(x, 3, y, 1);
577: if (alpha == (PetscScalar)0.0) return 0;
579: VecSetErrorIfLocked(y, 1);
580: VecLockReadPush(x);
581: PetscLogEventBegin(VEC_AXPY, x, y, 0, 0);
582: PetscUseTypeMethod(y, axpy, alpha, x);
583: PetscLogEventEnd(VEC_AXPY, x, y, 0, 0);
584: VecLockReadPop(x);
585: PetscObjectStateIncrease((PetscObject)y);
586: return 0;
587: }
589: /*@
590: VecAYPX - Computes y = x + beta y.
592: Logically Collective on Vec
594: Input Parameters:
595: + beta - the scalar
596: - x, y - the vectors
598: Output Parameter:
599: . y - output vector
601: Level: intermediate
603: Notes:
604: x and y MUST be different vectors
605: The implementation is optimized for beta of -1.0, 0.0, and 1.0
607: .seealso: `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
608: @*/
609: PetscErrorCode VecAYPX(Vec y, PetscScalar beta, Vec x)
610: {
616: VecCheckSameSize(x, 1, y, 3);
619: VecSetErrorIfLocked(y, 1);
620: VecLockReadPush(x);
621: if (beta == (PetscScalar)0.0) {
622: VecCopy(x, y);
623: } else {
624: PetscLogEventBegin(VEC_AYPX, x, y, 0, 0);
625: PetscUseTypeMethod(y, aypx, beta, x);
626: PetscLogEventEnd(VEC_AYPX, x, y, 0, 0);
627: PetscObjectStateIncrease((PetscObject)y);
628: }
629: VecLockReadPop(x);
630: return 0;
631: }
633: /*@
634: VecAXPBY - Computes y = alpha x + beta y.
636: Logically Collective on Vec
638: Input Parameters:
639: + alpha,beta - the scalars
640: - x, y - the vectors
642: Output Parameter:
643: . y - output vector
645: Level: intermediate
647: Notes:
648: x and y MUST be different vectors
649: The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
651: .seealso: `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`
652: @*/
653: PetscErrorCode VecAXPBY(Vec y, PetscScalar alpha, PetscScalar beta, Vec x)
654: {
660: VecCheckSameSize(y, 1, x, 4);
664: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) return 0;
666: VecSetErrorIfLocked(y, 1);
667: VecLockReadPush(x);
668: PetscLogEventBegin(VEC_AXPY, y, x, 0, 0);
669: PetscUseTypeMethod(y, axpby, alpha, beta, x);
670: PetscLogEventEnd(VEC_AXPY, y, x, 0, 0);
671: PetscObjectStateIncrease((PetscObject)y);
672: VecLockReadPop(x);
673: return 0;
674: }
676: /*@
677: VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
679: Logically Collective on Vec
681: Input Parameters:
682: + alpha,beta, gamma - the scalars
683: - x, y, z - the vectors
685: Output Parameter:
686: . z - output vector
688: Level: intermediate
690: Notes:
691: x, y and z must be different vectors
692: The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
694: .seealso: `VecAYPX()`, `VecMAXPY()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBY()`
695: @*/
696: PetscErrorCode VecAXPBYPCZ(Vec z, PetscScalar alpha, PetscScalar beta, PetscScalar gamma, Vec x, Vec y)
697: {
706: VecCheckSameSize(x, 1, y, 5);
707: VecCheckSameSize(x, 1, z, 6);
713: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) return 0;
715: VecSetErrorIfLocked(z, 1);
716: VecLockReadPush(x);
717: VecLockReadPush(y);
718: PetscLogEventBegin(VEC_AXPBYPCZ, x, y, z, 0);
719: PetscUseTypeMethod(z, axpbypcz, alpha, beta, gamma, x, y);
720: PetscLogEventEnd(VEC_AXPBYPCZ, x, y, z, 0);
721: PetscObjectStateIncrease((PetscObject)z);
722: VecLockReadPop(x);
723: VecLockReadPop(y);
724: return 0;
725: }
727: /*@
728: VecWAXPY - Computes w = alpha x + y.
730: Logically Collective on Vec
732: Input Parameters:
733: + alpha - the scalar
734: - x, y - the vectors
736: Output Parameter:
737: . w - the result
739: Level: intermediate
741: Notes:
742: w cannot be either x or y, but x and y can be the same
743: The implementation is optimzed for alpha of -1.0, 0.0, and 1.0
745: .seealso: `VecAXPY()`, `VecAYPX()`, `VecAXPBY()`, `VecMAXPY()`, `VecAXPBYPCZ()`
746: @*/
747: PetscErrorCode VecWAXPY(Vec w, PetscScalar alpha, Vec x, Vec y)
748: {
757: VecCheckSameSize(x, 3, y, 4);
758: VecCheckSameSize(x, 3, w, 1);
762: VecSetErrorIfLocked(w, 1);
764: VecLockReadPush(x);
765: VecLockReadPush(y);
766: if (alpha == (PetscScalar)0.0) {
767: VecCopy(y, w);
768: } else {
769: PetscLogEventBegin(VEC_WAXPY, x, y, w, 0);
770: PetscUseTypeMethod(w, waxpy, alpha, x, y);
771: PetscLogEventEnd(VEC_WAXPY, x, y, w, 0);
772: PetscObjectStateIncrease((PetscObject)w);
773: }
774: VecLockReadPop(x);
775: VecLockReadPop(y);
776: return 0;
777: }
779: /*@C
780: VecSetValues - Inserts or adds values into certain locations of a vector.
782: Not Collective
784: Input Parameters:
785: + x - vector to insert in
786: . ni - number of elements to add
787: . ix - indices where to add
788: . y - array of values
789: - iora - either INSERT_VALUES or ADD_VALUES, where
790: ADD_VALUES adds values to any existing entries, and
791: INSERT_VALUES replaces existing entries with new values
793: Notes:
794: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
796: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
797: options cannot be mixed without intervening calls to the assembly
798: routines.
800: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
801: MUST be called after all calls to VecSetValues() have been completed.
803: VecSetValues() uses 0-based indices in Fortran as well as in C.
805: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
806: negative indices may be passed in ix. These rows are
807: simply ignored. This allows easily inserting element load matrices
808: with homogeneous Dirchlet boundary conditions that you don't want represented
809: in the vector.
811: Level: beginner
813: .seealso: `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValuesLocal()`,
814: `VecSetValue()`, `VecSetValuesBlocked()`, `InsertMode`, `INSERT_VALUES`, `ADD_VALUES`, `VecGetValues()`
815: @*/
816: PetscErrorCode VecSetValues(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
817: {
820: if (!ni) return 0;
825: PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0);
826: PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
827: PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0);
828: PetscObjectStateIncrease((PetscObject)x);
829: return 0;
830: }
832: /*@C
833: VecGetValues - Gets values from certain locations of a vector. Currently
834: can only get values on the same processor
836: Not Collective
838: Input Parameters:
839: + x - vector to get values from
840: . ni - number of elements to get
841: - ix - indices where to get them from (in global 1d numbering)
843: Output Parameter:
844: . y - array of values
846: Notes:
847: The user provides the allocated array y; it is NOT allocated in this routine
849: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
851: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
853: VecGetValues() uses 0-based indices in Fortran as well as in C.
855: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
856: negative indices may be passed in ix. These rows are
857: simply ignored.
859: Level: beginner
861: .seealso: `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`
862: @*/
863: PetscErrorCode VecGetValues(Vec x, PetscInt ni, const PetscInt ix[], PetscScalar y[])
864: {
866: if (!ni) return 0;
870: PetscUseTypeMethod(x, getvalues, ni, ix, y);
871: return 0;
872: }
874: /*@C
875: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
877: Not Collective
879: Input Parameters:
880: + x - vector to insert in
881: . ni - number of blocks to add
882: . ix - indices where to add in block count, rather than element count
883: . y - array of values
884: - iora - either INSERT_VALUES or ADD_VALUES, where
885: ADD_VALUES adds values to any existing entries, and
886: INSERT_VALUES replaces existing entries with new values
888: Notes:
889: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
890: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
892: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
893: options cannot be mixed without intervening calls to the assembly
894: routines.
896: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
897: MUST be called after all calls to VecSetValuesBlocked() have been completed.
899: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
901: Negative indices may be passed in ix, these rows are
902: simply ignored. This allows easily inserting element load matrices
903: with homogeneous Dirchlet boundary conditions that you don't want represented
904: in the vector.
906: Level: intermediate
908: .seealso: `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValuesBlockedLocal()`,
909: `VecSetValues()`
910: @*/
911: PetscErrorCode VecSetValuesBlocked(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
912: {
915: if (!ni) return 0;
920: PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0);
921: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
922: PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0);
923: PetscObjectStateIncrease((PetscObject)x);
924: return 0;
925: }
927: /*@C
928: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
929: using a local ordering of the nodes.
931: Not Collective
933: Input Parameters:
934: + x - vector to insert in
935: . ni - number of elements to add
936: . ix - indices where to add
937: . y - array of values
938: - iora - either INSERT_VALUES or ADD_VALUES, where
939: ADD_VALUES adds values to any existing entries, and
940: INSERT_VALUES replaces existing entries with new values
942: Level: intermediate
944: Notes:
945: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
947: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
948: options cannot be mixed without intervening calls to the assembly
949: routines.
951: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
952: MUST be called after all calls to VecSetValuesLocal() have been completed.
954: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
956: .seealso: `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetLocalToGlobalMapping()`,
957: `VecSetValuesBlockedLocal()`
958: @*/
959: PetscErrorCode VecSetValuesLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
960: {
961: PetscInt lixp[128], *lix = lixp;
965: if (!ni) return 0;
970: PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0);
971: if (!x->ops->setvalueslocal) {
972: if (x->map->mapping) {
973: if (ni > 128) PetscMalloc1(ni, &lix);
974: ISLocalToGlobalMappingApply(x->map->mapping, ni, (PetscInt *)ix, lix);
975: PetscUseTypeMethod(x, setvalues, ni, lix, y, iora);
976: if (ni > 128) PetscFree(lix);
977: } else PetscUseTypeMethod(x, setvalues, ni, ix, y, iora);
978: } else PetscUseTypeMethod(x, setvalueslocal, ni, ix, y, iora);
979: PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0);
980: PetscObjectStateIncrease((PetscObject)x);
981: return 0;
982: }
984: /*@
985: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
986: using a local ordering of the nodes.
988: Not Collective
990: Input Parameters:
991: + x - vector to insert in
992: . ni - number of blocks to add
993: . ix - indices where to add in block count, not element count
994: . y - array of values
995: - iora - either INSERT_VALUES or ADD_VALUES, where
996: ADD_VALUES adds values to any existing entries, and
997: INSERT_VALUES replaces existing entries with new values
999: Level: intermediate
1001: Notes:
1002: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
1003: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
1005: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1006: options cannot be mixed without intervening calls to the assembly
1007: routines.
1009: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1010: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
1012: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
1014: .seealso: `VecAssemblyBegin()`, `VecAssemblyEnd()`, `VecSetValues()`, `VecSetValuesBlocked()`,
1015: `VecSetLocalToGlobalMapping()`
1016: @*/
1017: PetscErrorCode VecSetValuesBlockedLocal(Vec x, PetscInt ni, const PetscInt ix[], const PetscScalar y[], InsertMode iora)
1018: {
1019: PetscInt lixp[128], *lix = lixp;
1023: if (!ni) return 0;
1027: PetscLogEventBegin(VEC_SetValues, x, 0, 0, 0);
1028: if (x->map->mapping) {
1029: if (ni > 128) PetscMalloc1(ni, &lix);
1030: ISLocalToGlobalMappingApplyBlock(x->map->mapping, ni, (PetscInt *)ix, lix);
1031: PetscUseTypeMethod(x, setvaluesblocked, ni, lix, y, iora);
1032: if (ni > 128) PetscFree(lix);
1033: } else {
1034: PetscUseTypeMethod(x, setvaluesblocked, ni, ix, y, iora);
1035: }
1036: PetscLogEventEnd(VEC_SetValues, x, 0, 0, 0);
1037: PetscObjectStateIncrease((PetscObject)x);
1038: return 0;
1039: }
1041: /*@
1042: VecMTDot - Computes indefinite vector multiple dot products.
1043: That is, it does NOT use the complex conjugate.
1045: Collective on Vec
1047: Input Parameters:
1048: + x - one vector
1049: . nv - number of vectors
1050: - y - array of vectors. Note that vectors are pointers
1052: Output Parameter:
1053: . val - array of the dot products
1055: Notes for Users of Complex Numbers:
1056: For complex vectors, VecMTDot() computes the indefinite form
1057: $ val = (x,y) = y^T x,
1058: where y^T denotes the transpose of y.
1060: Use VecMDot() for the inner product
1061: $ val = (x,y) = y^H x,
1062: where y^H denotes the conjugate transpose of y.
1064: Level: intermediate
1066: .seealso: `VecMDot()`, `VecTDot()`
1067: @*/
1068: PetscErrorCode VecMTDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1069: {
1073: if (!nv) return 0;
1075: for (PetscInt i = 0; i < nv; ++i) {
1079: VecCheckSameSize(x, 1, y[i], 3);
1080: VecLockReadPush(y[i]);
1081: }
1084: VecLockReadPush(x);
1085: PetscLogEventBegin(VEC_MTDot, x, *y, 0, 0);
1086: PetscUseTypeMethod(x, mtdot, nv, y, val);
1087: PetscLogEventEnd(VEC_MTDot, x, *y, 0, 0);
1088: VecLockReadPop(x);
1089: for (PetscInt i = 0; i < nv; ++i) VecLockReadPop(y[i]);
1090: return 0;
1091: }
1093: /*@
1094: VecMDot - Computes vector multiple dot products.
1096: Collective on Vec
1098: Input Parameters:
1099: + x - one vector
1100: . nv - number of vectors
1101: - y - array of vectors.
1103: Output Parameter:
1104: . val - array of the dot products (does not allocate the array)
1106: Notes for Users of Complex Numbers:
1107: For complex vectors, VecMDot() computes
1108: $ val = (x,y) = y^H x,
1109: where y^H denotes the conjugate transpose of y.
1111: Use VecMTDot() for the indefinite form
1112: $ val = (x,y) = y^T x,
1113: where y^T denotes the transpose of y.
1115: Level: intermediate
1117: .seealso: `VecMTDot()`, `VecDot()`
1118: @*/
1119: PetscErrorCode VecMDot(Vec x, PetscInt nv, const Vec y[], PetscScalar val[])
1120: {
1124: if (!nv) return 0;
1126: for (PetscInt i = 0; i < nv; ++i) {
1130: VecCheckSameSize(x, 1, y[i], 3);
1131: VecLockReadPush(y[i]);
1132: }
1135: VecLockReadPush(x);
1136: PetscLogEventBegin(VEC_MDot, x, *y, 0, 0);
1137: PetscUseTypeMethod(x, mdot, nv, y, val);
1138: PetscLogEventEnd(VEC_MDot, x, *y, 0, 0);
1139: VecLockReadPop(x);
1140: for (PetscInt i = 0; i < nv; ++i) VecLockReadPop(y[i]);
1141: return 0;
1142: }
1144: /*@
1145: VecMAXPY - Computes y = y + sum alpha[i] x[i]
1147: Logically Collective on Vec
1149: Input Parameters:
1150: + nv - number of scalars and x-vectors
1151: . alpha - array of scalars
1152: . y - one vector
1153: - x - array of vectors
1155: Level: intermediate
1157: Notes:
1158: y cannot be any of the x vectors
1160: .seealso: `VecAYPX()`, `VecWAXPY()`, `VecAXPY()`, `VecAXPBYPCZ()`, `VecAXPBY()`
1161: @*/
1162: PetscErrorCode VecMAXPY(Vec y, PetscInt nv, const PetscScalar alpha[], Vec x[])
1163: {
1166: VecSetErrorIfLocked(y, 1);
1168: if (nv) {
1169: PetscInt zeros = 0;
1173: for (PetscInt i = 0; i < nv; ++i) {
1178: VecCheckSameSize(y, 1, x[i], 4);
1180: VecLockReadPush(x[i]);
1181: zeros += alpha[i] == (PetscScalar)0.0;
1182: }
1184: if (zeros < nv) {
1185: PetscLogEventBegin(VEC_MAXPY, y, *x, 0, 0);
1186: PetscUseTypeMethod(y, maxpy, nv, alpha, x);
1187: PetscLogEventEnd(VEC_MAXPY, y, *x, 0, 0);
1188: PetscObjectStateIncrease((PetscObject)y);
1189: }
1191: for (PetscInt i = 0; i < nv; ++i) VecLockReadPop(x[i]);
1192: }
1193: return 0;
1194: }
1196: /*@
1197: VecConcatenate - Creates a new vector that is a vertical concatenation of all the given array of vectors
1198: in the order they appear in the array. The concatenated vector resides on the same
1199: communicator and is the same type as the source vectors.
1201: Collective on X
1203: Input Parameters:
1204: + nx - number of vectors to be concatenated
1205: - X - array containing the vectors to be concatenated in the order of concatenation
1207: Output Parameters:
1208: + Y - concatenated vector
1209: - x_is - array of index sets corresponding to the concatenated components of Y (NULL if not needed)
1211: Notes:
1212: Concatenation is similar to the functionality of a VecNest object; they both represent combination of
1213: different vector spaces. However, concatenated vectors do not store any information about their
1214: sub-vectors and own their own data. Consequently, this function provides index sets to enable the
1215: manipulation of data in the concatenated vector that corresponds to the original components at creation.
1217: This is a useful tool for outer loop algorithms, particularly constrained optimizers, where the solver
1218: has to operate on combined vector spaces and cannot utilize VecNest objects due to incompatibility with
1219: bound projections.
1221: Level: advanced
1223: .seealso: `VECNEST`, `VECSCATTER`, `VecScatterCreate()`
1224: @*/
1225: PetscErrorCode VecConcatenate(PetscInt nx, const Vec X[], Vec *Y, IS *x_is[])
1226: {
1227: MPI_Comm comm;
1228: VecType vec_type;
1229: Vec Ytmp, Xtmp;
1230: IS *is_tmp;
1231: PetscInt i, shift = 0, Xnl, Xng, Xbegin;
1238: if ((*X)->ops->concatenate) {
1239: /* use the dedicated concatenation function if available */
1240: (*(*X)->ops->concatenate)(nx, X, Y, x_is);
1241: } else {
1242: /* loop over vectors and start creating IS */
1243: comm = PetscObjectComm((PetscObject)(*X));
1244: VecGetType(*X, &vec_type);
1245: PetscMalloc1(nx, &is_tmp);
1246: for (i = 0; i < nx; i++) {
1247: VecGetSize(X[i], &Xng);
1248: VecGetLocalSize(X[i], &Xnl);
1249: VecGetOwnershipRange(X[i], &Xbegin, NULL);
1250: ISCreateStride(comm, Xnl, shift + Xbegin, 1, &is_tmp[i]);
1251: shift += Xng;
1252: }
1253: /* create the concatenated vector */
1254: VecCreate(comm, &Ytmp);
1255: VecSetType(Ytmp, vec_type);
1256: VecSetSizes(Ytmp, PETSC_DECIDE, shift);
1257: VecSetUp(Ytmp);
1258: /* copy data from X array to Y and return */
1259: for (i = 0; i < nx; i++) {
1260: VecGetSubVector(Ytmp, is_tmp[i], &Xtmp);
1261: VecCopy(X[i], Xtmp);
1262: VecRestoreSubVector(Ytmp, is_tmp[i], &Xtmp);
1263: }
1264: *Y = Ytmp;
1265: if (x_is) {
1266: *x_is = is_tmp;
1267: } else {
1268: for (i = 0; i < nx; i++) ISDestroy(&is_tmp[i]);
1269: PetscFree(is_tmp);
1270: }
1271: }
1272: return 0;
1273: }
1275: /* A helper function for VecGetSubVector to check if we can implement it with no-copy (i.e. the subvector shares
1276: memory with the original vector), and the block size of the subvector.
1278: Input Parameters:
1279: + X - the original vector
1280: - is - the index set of the subvector
1282: Output Parameters:
1283: + contig - PETSC_TRUE if the index set refers to contiguous entries on this process, else PETSC_FALSE
1284: . start - start of contiguous block, as an offset from the start of the ownership range of the original vector
1285: - blocksize - the block size of the subvector
1287: */
1288: PetscErrorCode VecGetSubVectorContiguityAndBS_Private(Vec X, IS is, PetscBool *contig, PetscInt *start, PetscInt *blocksize)
1289: {
1290: PetscInt gstart, gend, lstart;
1291: PetscBool red[2] = {PETSC_TRUE /*contiguous*/, PETSC_TRUE /*validVBS*/};
1292: PetscInt n, N, ibs, vbs, bs = -1;
1294: ISGetLocalSize(is, &n);
1295: ISGetSize(is, &N);
1296: ISGetBlockSize(is, &ibs);
1297: VecGetBlockSize(X, &vbs);
1298: VecGetOwnershipRange(X, &gstart, &gend);
1299: ISContiguousLocal(is, gstart, gend, &lstart, &red[0]);
1300: /* block size is given by IS if ibs > 1; otherwise, check the vector */
1301: if (ibs > 1) {
1302: MPIU_Allreduce(MPI_IN_PLACE, red, 1, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is));
1303: bs = ibs;
1304: } else {
1305: if (n % vbs || vbs == 1) red[1] = PETSC_FALSE; /* this process invalidate the collectiveness of block size */
1306: MPIU_Allreduce(MPI_IN_PLACE, red, 2, MPIU_BOOL, MPI_LAND, PetscObjectComm((PetscObject)is));
1307: if (red[0] && red[1]) bs = vbs; /* all processes have a valid block size and the access will be contiguous */
1308: }
1310: *contig = red[0];
1311: *start = lstart;
1312: *blocksize = bs;
1313: return 0;
1314: }
1316: /* A helper function for VecGetSubVector, to be used when we have to build a standalone subvector through VecScatter
1318: Input Parameters:
1319: + X - the original vector
1320: . is - the index set of the subvector
1321: - bs - the block size of the subvector, gotten from VecGetSubVectorContiguityAndBS_Private()
1323: Output Parameters:
1324: . Z - the subvector, which will compose the VecScatter context on output
1325: */
1326: PetscErrorCode VecGetSubVectorThroughVecScatter_Private(Vec X, IS is, PetscInt bs, Vec *Z)
1327: {
1328: PetscInt n, N;
1329: VecScatter vscat;
1330: Vec Y;
1332: ISGetLocalSize(is, &n);
1333: ISGetSize(is, &N);
1334: VecCreate(PetscObjectComm((PetscObject)is), &Y);
1335: VecSetSizes(Y, n, N);
1336: VecSetBlockSize(Y, bs);
1337: VecSetType(Y, ((PetscObject)X)->type_name);
1338: VecScatterCreate(X, is, Y, NULL, &vscat);
1339: VecScatterBegin(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD);
1340: VecScatterEnd(vscat, X, Y, INSERT_VALUES, SCATTER_FORWARD);
1341: PetscObjectCompose((PetscObject)Y, "VecGetSubVector_Scatter", (PetscObject)vscat);
1342: VecScatterDestroy(&vscat);
1343: *Z = Y;
1344: return 0;
1345: }
1347: /*@
1348: VecGetSubVector - Gets a vector representing part of another vector
1350: Collective on X and IS
1352: Input Parameters:
1353: + X - vector from which to extract a subvector
1354: - is - index set representing portion of X to extract
1356: Output Parameter:
1357: . Y - subvector corresponding to is
1359: Level: advanced
1361: Notes:
1362: The subvector Y should be returned with VecRestoreSubVector().
1363: X and is must be defined on the same communicator
1365: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1366: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1367: The resulting subvector inherits the block size from the IS if greater than one. Otherwise, the block size is guessed from the block size of the original vec.
1369: .seealso: `MatCreateSubMatrix()`
1370: @*/
1371: PetscErrorCode VecGetSubVector(Vec X, IS is, Vec *Y)
1372: {
1373: Vec Z;
1379: if (X->ops->getsubvector) {
1380: PetscUseTypeMethod(X, getsubvector, is, &Z);
1381: } else { /* Default implementation currently does no caching */
1382: PetscBool contig;
1383: PetscInt n, N, start, bs;
1385: ISGetLocalSize(is, &n);
1386: ISGetSize(is, &N);
1387: VecGetSubVectorContiguityAndBS_Private(X, is, &contig, &start, &bs);
1388: if (contig) { /* We can do a no-copy implementation */
1389: const PetscScalar *x;
1390: PetscInt state = 0;
1391: PetscBool isstd, iscuda, iship;
1393: PetscObjectTypeCompareAny((PetscObject)X, &isstd, VECSEQ, VECMPI, VECSTANDARD, "");
1394: PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, "");
1395: PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, "");
1396: if (iscuda) {
1397: #if defined(PETSC_HAVE_CUDA)
1398: const PetscScalar *x_d;
1399: PetscMPIInt size;
1400: PetscOffloadMask flg;
1402: VecCUDAGetArrays_Private(X, &x, &x_d, &flg);
1405: if (x) x += start;
1406: if (x_d) x_d += start;
1407: MPI_Comm_size(PetscObjectComm((PetscObject)X), &size);
1408: if (size == 1) {
1409: VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z);
1410: } else {
1411: VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z);
1412: }
1413: Z->offloadmask = flg;
1414: #endif
1415: } else if (iship) {
1416: #if defined(PETSC_HAVE_HIP)
1417: const PetscScalar *x_d;
1418: PetscMPIInt size;
1419: PetscOffloadMask flg;
1421: VecHIPGetArrays_Private(X, &x, &x_d, &flg);
1424: if (x) x += start;
1425: if (x_d) x_d += start;
1426: MPI_Comm_size(PetscObjectComm((PetscObject)X), &size);
1427: if (size == 1) {
1428: VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, x, x_d, &Z);
1429: } else {
1430: VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)X), bs, n, N, x, x_d, &Z);
1431: }
1432: Z->offloadmask = flg;
1433: #endif
1434: } else if (isstd) {
1435: PetscMPIInt size;
1437: MPI_Comm_size(PetscObjectComm((PetscObject)X), &size);
1438: VecGetArrayRead(X, &x);
1439: if (x) x += start;
1440: if (size == 1) {
1441: VecCreateSeqWithArray(PetscObjectComm((PetscObject)X), bs, n, x, &Z);
1442: } else {
1443: VecCreateMPIWithArray(PetscObjectComm((PetscObject)X), bs, n, N, x, &Z);
1444: }
1445: VecRestoreArrayRead(X, &x);
1446: } else { /* default implementation: use place array */
1447: VecGetArrayRead(X, &x);
1448: VecCreate(PetscObjectComm((PetscObject)X), &Z);
1449: VecSetType(Z, ((PetscObject)X)->type_name);
1450: VecSetSizes(Z, n, N);
1451: VecSetBlockSize(Z, bs);
1452: VecPlaceArray(Z, x ? x + start : NULL);
1453: VecRestoreArrayRead(X, &x);
1454: }
1456: /* this is relevant only in debug mode */
1457: VecLockGet(X, &state);
1458: if (state) VecLockReadPush(Z);
1459: Z->ops->placearray = NULL;
1460: Z->ops->replacearray = NULL;
1461: } else { /* Have to create a scatter and do a copy */
1462: VecGetSubVectorThroughVecScatter_Private(X, is, bs, &Z);
1463: }
1464: }
1465: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1466: if (VecGetSubVectorSavedStateId < 0) PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);
1467: PetscObjectComposedDataSetInt((PetscObject)Z, VecGetSubVectorSavedStateId, 1);
1468: *Y = Z;
1469: return 0;
1470: }
1472: /*@
1473: VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1475: Collective on IS
1477: Input Parameters:
1478: + X - vector from which subvector was obtained
1479: . is - index set representing the subset of X
1480: - Y - subvector being restored
1482: Level: advanced
1484: .seealso: `VecGetSubVector()`
1485: @*/
1486: PetscErrorCode VecRestoreSubVector(Vec X, IS is, Vec *Y)
1487: {
1488: PETSC_UNUSED PetscObjectState dummystate = 0;
1489: PetscBool unchanged;
1497: if (X->ops->restoresubvector) PetscUseTypeMethod(X, restoresubvector, is, Y);
1498: else {
1499: PetscObjectComposedDataGetInt((PetscObject)*Y, VecGetSubVectorSavedStateId, dummystate, unchanged);
1500: if (!unchanged) { /* If Y's state has not changed since VecGetSubVector(), we only need to destroy Y */
1501: VecScatter scatter;
1502: PetscInt state;
1504: VecLockGet(X, &state);
1507: PetscObjectQuery((PetscObject)*Y, "VecGetSubVector_Scatter", (PetscObject *)&scatter);
1508: if (scatter) {
1509: VecScatterBegin(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE);
1510: VecScatterEnd(scatter, *Y, X, INSERT_VALUES, SCATTER_REVERSE);
1511: } else {
1512: PetscBool iscuda, iship;
1513: PetscObjectTypeCompareAny((PetscObject)X, &iscuda, VECSEQCUDA, VECMPICUDA, "");
1514: PetscObjectTypeCompareAny((PetscObject)X, &iship, VECSEQHIP, VECMPIHIP, "");
1516: if (iscuda) {
1517: #if defined(PETSC_HAVE_CUDA)
1518: PetscOffloadMask ymask = (*Y)->offloadmask;
1520: /* The offloadmask of X dictates where to move memory
1521: If X GPU data is valid, then move Y data on GPU if needed
1522: Otherwise, move back to the CPU */
1523: switch (X->offloadmask) {
1524: case PETSC_OFFLOAD_BOTH:
1525: if (ymask == PETSC_OFFLOAD_CPU) {
1526: VecCUDAResetArray(*Y);
1527: } else if (ymask == PETSC_OFFLOAD_GPU) {
1528: X->offloadmask = PETSC_OFFLOAD_GPU;
1529: }
1530: break;
1531: case PETSC_OFFLOAD_GPU:
1532: if (ymask == PETSC_OFFLOAD_CPU) VecCUDAResetArray(*Y);
1533: break;
1534: case PETSC_OFFLOAD_CPU:
1535: if (ymask == PETSC_OFFLOAD_GPU) VecResetArray(*Y);
1536: break;
1537: case PETSC_OFFLOAD_UNALLOCATED:
1538: case PETSC_OFFLOAD_KOKKOS:
1539: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1540: }
1541: #endif
1542: } else if (iship) {
1543: #if defined(PETSC_HAVE_HIP)
1544: PetscOffloadMask ymask = (*Y)->offloadmask;
1546: /* The offloadmask of X dictates where to move memory
1547: If X GPU data is valid, then move Y data on GPU if needed
1548: Otherwise, move back to the CPU */
1549: switch (X->offloadmask) {
1550: case PETSC_OFFLOAD_BOTH:
1551: if (ymask == PETSC_OFFLOAD_CPU) {
1552: VecHIPResetArray(*Y);
1553: } else if (ymask == PETSC_OFFLOAD_GPU) {
1554: X->offloadmask = PETSC_OFFLOAD_GPU;
1555: }
1556: break;
1557: case PETSC_OFFLOAD_GPU:
1558: if (ymask == PETSC_OFFLOAD_CPU) VecHIPResetArray(*Y);
1559: break;
1560: case PETSC_OFFLOAD_CPU:
1561: if (ymask == PETSC_OFFLOAD_GPU) VecResetArray(*Y);
1562: break;
1563: case PETSC_OFFLOAD_UNALLOCATED:
1564: case PETSC_OFFLOAD_KOKKOS:
1565: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_PLIB, "This should not happen");
1566: }
1567: #endif
1568: } else {
1569: /* If OpenCL vecs updated the device memory, this triggers a copy on the CPU */
1570: VecResetArray(*Y);
1571: }
1572: PetscObjectStateIncrease((PetscObject)X);
1573: }
1574: }
1575: }
1576: VecDestroy(Y);
1577: return 0;
1578: }
1580: /*@
1581: VecCreateLocalVector - Creates a vector object suitable for use with VecGetLocalVector() and friends. You must call VecDestroy() when the
1582: vector is no longer needed.
1584: Not collective.
1586: Input parameter:
1587: . v - The vector for which the local vector is desired.
1589: Output parameter:
1590: . w - Upon exit this contains the local vector.
1592: Level: beginner
1594: .seealso: `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecRestoreLocalVector()`
1595: @*/
1596: PetscErrorCode VecCreateLocalVector(Vec v, Vec *w)
1597: {
1598: PetscMPIInt size;
1602: MPI_Comm_size(PetscObjectComm((PetscObject)v), &size);
1603: if (size == 1) VecDuplicate(v, w);
1604: else if (v->ops->createlocalvector) PetscUseTypeMethod(v, createlocalvector, w);
1605: else {
1606: VecType type;
1607: PetscInt n;
1609: VecCreate(PETSC_COMM_SELF, w);
1610: VecGetLocalSize(v, &n);
1611: VecSetSizes(*w, n, n);
1612: VecGetBlockSize(v, &n);
1613: VecSetBlockSize(*w, n);
1614: VecGetType(v, &type);
1615: VecSetType(*w, type);
1616: }
1617: return 0;
1618: }
1620: /*@
1621: VecGetLocalVectorRead - Maps the local portion of a vector into a
1622: vector. You must call VecRestoreLocalVectorRead() when the local
1623: vector is no longer needed.
1625: Not collective.
1627: Input parameter:
1628: . v - The vector for which the local vector is desired.
1630: Output parameter:
1631: . w - Upon exit this contains the local vector.
1633: Level: beginner
1635: Notes:
1636: This function is similar to VecGetArrayRead() which maps the local
1637: portion into a raw pointer. VecGetLocalVectorRead() is usually
1638: almost as efficient as VecGetArrayRead() but in certain circumstances
1639: VecGetLocalVectorRead() can be much more efficient than
1640: VecGetArrayRead(). This is because the construction of a contiguous
1641: array representing the vector data required by VecGetArrayRead() can
1642: be an expensive operation for certain vector types. For example, for
1643: GPU vectors VecGetArrayRead() requires that the data between device
1644: and host is synchronized.
1646: Unlike VecGetLocalVector(), this routine is not collective and
1647: preserves cached information.
1649: .seealso: `VecCreateLocalVector()`, `VecRestoreLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1650: @*/
1651: PetscErrorCode VecGetLocalVectorRead(Vec v, Vec w)
1652: {
1655: VecCheckSameLocalSize(v, 1, w, 2);
1656: if (v->ops->getlocalvectorread) {
1657: PetscUseTypeMethod(v, getlocalvectorread, w);
1658: } else {
1659: PetscScalar *a;
1661: VecGetArrayRead(v, (const PetscScalar **)&a);
1662: VecPlaceArray(w, a);
1663: }
1664: PetscObjectStateIncrease((PetscObject)w);
1665: VecLockReadPush(v);
1666: VecLockReadPush(w);
1667: return 0;
1668: }
1670: /*@
1671: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1672: previously mapped into a vector using VecGetLocalVectorRead().
1674: Not collective.
1676: Input parameter:
1677: + v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
1678: - w - The vector into which the local portion of v was mapped.
1680: Level: beginner
1682: .seealso: `VecCreateLocalVector()`, `VecGetLocalVectorRead()`, `VecGetLocalVector()`, `VecGetArrayRead()`, `VecGetArray()`
1683: @*/
1684: PetscErrorCode VecRestoreLocalVectorRead(Vec v, Vec w)
1685: {
1688: if (v->ops->restorelocalvectorread) {
1689: PetscUseTypeMethod(v, restorelocalvectorread, w);
1690: } else {
1691: const PetscScalar *a;
1693: VecGetArrayRead(w, &a);
1694: VecRestoreArrayRead(v, &a);
1695: VecResetArray(w);
1696: }
1697: VecLockReadPop(v);
1698: VecLockReadPop(w);
1699: PetscObjectStateIncrease((PetscObject)w);
1700: return 0;
1701: }
1703: /*@
1704: VecGetLocalVector - Maps the local portion of a vector into a
1705: vector.
1707: Collective on v, not collective on w.
1709: Input parameter:
1710: . v - The vector for which the local vector is desired.
1712: Output parameter:
1713: . w - Upon exit this contains the local vector.
1715: Level: beginner
1717: Notes:
1718: This function is similar to VecGetArray() which maps the local
1719: portion into a raw pointer. VecGetLocalVector() is usually about as
1720: efficient as VecGetArray() but in certain circumstances
1721: VecGetLocalVector() can be much more efficient than VecGetArray().
1722: This is because the construction of a contiguous array representing
1723: the vector data required by VecGetArray() can be an expensive
1724: operation for certain vector types. For example, for GPU vectors
1725: VecGetArray() requires that the data between device and host is
1726: synchronized.
1728: .seealso: `VecCreateLocalVector()`, `VecRestoreLocalVector()`, `VecGetLocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1729: @*/
1730: PetscErrorCode VecGetLocalVector(Vec v, Vec w)
1731: {
1734: VecCheckSameLocalSize(v, 1, w, 2);
1735: if (v->ops->getlocalvector) {
1736: PetscUseTypeMethod(v, getlocalvector, w);
1737: } else {
1738: PetscScalar *a;
1740: VecGetArray(v, &a);
1741: VecPlaceArray(w, a);
1742: }
1743: PetscObjectStateIncrease((PetscObject)w);
1744: return 0;
1745: }
1747: /*@
1748: VecRestoreLocalVector - Unmaps the local portion of a vector
1749: previously mapped into a vector using VecGetLocalVector().
1751: Logically collective.
1753: Input parameter:
1754: + v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
1755: - w - The vector into which the local portion of v was mapped.
1757: Level: beginner
1759: .seealso: `VecCreateLocalVector()`, `VecGetLocalVector()`, `VecGetLocalVectorRead()`, `VecRestoreLocalVectorRead()`, `LocalVectorRead()`, `VecGetArrayRead()`, `VecGetArray()`
1760: @*/
1761: PetscErrorCode VecRestoreLocalVector(Vec v, Vec w)
1762: {
1765: if (v->ops->restorelocalvector) {
1766: PetscUseTypeMethod(v, restorelocalvector, w);
1767: } else {
1768: PetscScalar *a;
1769: VecGetArray(w, &a);
1770: VecRestoreArray(v, &a);
1771: VecResetArray(w);
1772: }
1773: PetscObjectStateIncrease((PetscObject)w);
1774: PetscObjectStateIncrease((PetscObject)v);
1775: return 0;
1776: }
1778: /*@C
1779: VecGetArray - Returns a pointer to a contiguous array that contains this
1780: processor's portion of the vector data. For the standard PETSc
1781: vectors, VecGetArray() returns a pointer to the local data array and
1782: does not use any copies. If the underlying vector data is not stored
1783: in a contiguous array this routine will copy the data to a contiguous
1784: array and return a pointer to that. You MUST call VecRestoreArray()
1785: when you no longer need access to the array.
1787: Logically Collective on Vec
1789: Input Parameter:
1790: . x - the vector
1792: Output Parameter:
1793: . a - location to put pointer to the array
1795: Fortran Note:
1796: This routine is used differently from Fortran 77
1797: $ Vec x
1798: $ PetscScalar x_array(1)
1799: $ PetscOffset i_x
1800: $ PetscErrorCode ierr
1801: $ call VecGetArray(x,x_array,i_x,ierr)
1802: $
1803: $ Access first local entry in vector with
1804: $ value = x_array(i_x + 1)
1805: $
1806: $ ...... other code
1807: $ call VecRestoreArray(x,x_array,i_x,ierr)
1808: For Fortran 90 see VecGetArrayF90()
1810: See the Fortran chapter of the users manual and
1811: petsc/src/snes/tutorials/ex5f.F for details.
1813: Level: beginner
1815: .seealso: `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
1816: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
1817: @*/
1818: PetscErrorCode VecGetArray(Vec x, PetscScalar **a)
1819: {
1821: VecSetErrorIfLocked(x, 1);
1822: if (x->ops->getarray) { /* The if-else order matters! VECNEST, VECCUDA etc should have ops->getarray while VECCUDA etc are petscnative */
1823: PetscUseTypeMethod(x, getarray, a);
1824: } else if (x->petscnative) { /* VECSTANDARD */
1825: *a = *((PetscScalar **)x->data);
1826: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array for vector type \"%s\"", ((PetscObject)x)->type_name);
1827: return 0;
1828: }
1830: /*@C
1831: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1833: Logically Collective on Vec
1835: Input Parameters:
1836: + x - the vector
1837: - a - location of pointer to array obtained from VecGetArray()
1839: Level: beginner
1841: .seealso: `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
1842: `VecGetArrayPair()`, `VecRestoreArrayPair()`
1843: @*/
1844: PetscErrorCode VecRestoreArray(Vec x, PetscScalar **a)
1845: {
1848: if (x->ops->restorearray) {
1849: PetscUseTypeMethod(x, restorearray, a);
1851: if (a) *a = NULL;
1852: PetscObjectStateIncrease((PetscObject)x);
1853: return 0;
1854: }
1855: /*@C
1856: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1858: Not Collective
1860: Input Parameter:
1861: . x - the vector
1863: Output Parameter:
1864: . a - the array
1866: Level: beginner
1868: Notes:
1869: The array must be returned using a matching call to VecRestoreArrayRead().
1871: Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1873: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1874: implementations may require a copy, but must such implementations should cache the contiguous representation so that
1875: only one copy is performed when this routine is called multiple times in sequence.
1877: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1878: @*/
1879: PetscErrorCode VecGetArrayRead(Vec x, const PetscScalar **a)
1880: {
1883: if (x->ops->getarrayread) {
1884: PetscUseTypeMethod(x, getarrayread, a);
1885: } else if (x->ops->getarray) {
1886: /* VECNEST, VECCUDA, VECKOKKOS etc */
1887: PetscUseTypeMethod(x, getarray, (PetscScalar **)a);
1888: } else if (x->petscnative) {
1889: /* VECSTANDARD */
1890: *a = *((PetscScalar **)x->data);
1891: } else SETERRQ(PetscObjectComm((PetscObject)x), PETSC_ERR_SUP, "Cannot get array read for vector type \"%s\"", ((PetscObject)x)->type_name);
1892: return 0;
1893: }
1895: /*@C
1896: VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
1898: Not Collective
1900: Input Parameters:
1901: + vec - the vector
1902: - array - the array
1904: Level: beginner
1906: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
1907: @*/
1908: PetscErrorCode VecRestoreArrayRead(Vec x, const PetscScalar **a)
1909: {
1912: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS etc */
1913: /* nothing */
1914: } else if (x->ops->restorearrayread) { /* VECNEST */
1915: PetscUseTypeMethod(x, restorearrayread, a);
1916: } else { /* No one? */
1917: PetscUseTypeMethod(x, restorearray, (PetscScalar **)a);
1918: }
1919: if (a) *a = NULL;
1920: return 0;
1921: }
1923: /*@C
1924: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contains this
1925: processor's portion of the vector data. The values in this array are NOT valid, the routine calling this
1926: routine is responsible for putting values into the array; any values it does not set will be invalid
1928: Logically Collective on Vec
1930: Input Parameter:
1931: . x - the vector
1933: Output Parameter:
1934: . a - location to put pointer to the array
1936: Level: intermediate
1938: This is for vectors associate with GPUs, the vector is not copied up before giving access. If you need correct
1939: values in the array use VecGetArray()
1941: .seealso: `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`, `VecPlaceArray()`, `VecGetArray2d()`,
1942: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArray()`, `VecRestoreArrayWrite()`
1943: @*/
1944: PetscErrorCode VecGetArrayWrite(Vec x, PetscScalar **a)
1945: {
1948: VecSetErrorIfLocked(x, 1);
1949: if (x->ops->getarraywrite) {
1950: PetscUseTypeMethod(x, getarraywrite, a);
1951: } else {
1952: VecGetArray(x, a);
1953: }
1954: return 0;
1955: }
1957: /*@C
1958: VecRestoreArrayWrite - Restores a vector after VecGetArrayWrite() has been called.
1960: Logically Collective on Vec
1962: Input Parameters:
1963: + x - the vector
1964: - a - location of pointer to array obtained from VecGetArray()
1966: Level: beginner
1968: .seealso: `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`, `VecPlaceArray()`, `VecRestoreArray2d()`,
1969: `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`
1970: @*/
1971: PetscErrorCode VecRestoreArrayWrite(Vec x, PetscScalar **a)
1972: {
1975: if (x->ops->restorearraywrite) {
1976: PetscUseTypeMethod(x, restorearraywrite, a);
1977: } else if (x->ops->restorearray) {
1978: PetscUseTypeMethod(x, restorearray, a);
1979: }
1980: if (a) *a = NULL;
1981: PetscObjectStateIncrease((PetscObject)x);
1982: return 0;
1983: }
1985: /*@C
1986: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1987: that were created by a call to VecDuplicateVecs(). You MUST call
1988: VecRestoreArrays() when you no longer need access to the array.
1990: Logically Collective on Vec
1992: Input Parameters:
1993: + x - the vectors
1994: - n - the number of vectors
1996: Output Parameter:
1997: . a - location to put pointer to the array
1999: Fortran Note:
2000: This routine is not supported in Fortran.
2002: Level: intermediate
2004: .seealso: `VecGetArray()`, `VecRestoreArrays()`
2005: @*/
2006: PetscErrorCode VecGetArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2007: {
2008: PetscInt i;
2009: PetscScalar **q;
2015: PetscMalloc1(n, &q);
2016: for (i = 0; i < n; ++i) VecGetArray(x[i], &q[i]);
2017: *a = q;
2018: return 0;
2019: }
2021: /*@C
2022: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
2023: has been called.
2025: Logically Collective on Vec
2027: Input Parameters:
2028: + x - the vector
2029: . n - the number of vectors
2030: - a - location of pointer to arrays obtained from VecGetArrays()
2032: Notes:
2033: For regular PETSc vectors this routine does not involve any copies. For
2034: any special vectors that do not store local vector data in a contiguous
2035: array, this routine will copy the data back into the underlying
2036: vector data structure from the arrays obtained with VecGetArrays().
2038: Fortran Note:
2039: This routine is not supported in Fortran.
2041: Level: intermediate
2043: .seealso: `VecGetArrays()`, `VecRestoreArray()`
2044: @*/
2045: PetscErrorCode VecRestoreArrays(const Vec x[], PetscInt n, PetscScalar **a[])
2046: {
2047: PetscInt i;
2048: PetscScalar **q = *a;
2054: for (i = 0; i < n; ++i) VecRestoreArray(x[i], &q[i]);
2055: PetscFree(q);
2056: return 0;
2057: }
2059: /*@C
2060: VecGetArrayAndMemType - Like VecGetArray(), but if this is a standard device vector (e.g., VECCUDA), the returned pointer will be a device
2061: pointer to the device memory that contains this processor's portion of the vector data. Device data is guaranteed to have the latest value.
2062: Otherwise, when this is a host vector (e.g., VECMPI), this routine functions the same as VecGetArray() and returns a host pointer.
2064: For VECKOKKOS, if Kokkos is configured without device (e.g., use serial or openmp), per this function, the vector works like VECSEQ/VECMPI;
2065: otherwise, it works like VECCUDA or VECHIP etc.
2067: Logically Collective on Vec
2069: Input Parameter:
2070: . x - the vector
2072: Output Parameters:
2073: + a - location to put pointer to the array
2074: - mtype - memory type of the array
2076: Level: beginner
2078: .seealso: `VecRestoreArrayAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecGetArrayReadF90()`,
2079: `VecPlaceArray()`, `VecGetArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayWrite()`, `VecRestoreArrayWrite()`
2080: @*/
2081: PetscErrorCode VecGetArrayAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2082: {
2087: VecSetErrorIfLocked(x, 1);
2088: if (x->ops->getarrayandmemtype) {
2089: /* VECCUDA, VECKOKKOS etc */
2090: PetscUseTypeMethod(x, getarrayandmemtype, a, mtype);
2091: } else {
2092: /* VECSTANDARD, VECNEST, VECVIENNACL */
2093: VecGetArray(x, a);
2094: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2095: }
2096: return 0;
2097: }
2099: /*@C
2100: VecRestoreArrayAndMemType - Restores a vector after VecGetArrayAndMemType() has been called.
2102: Logically Collective on Vec
2104: Input Parameters:
2105: + x - the vector
2106: - a - location of pointer to array obtained from VecGetArrayAndMemType()
2108: Level: beginner
2110: .seealso: `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArrayRead()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecRestoreArrayReadF90()`,
2111: `VecPlaceArray()`, `VecRestoreArray2d()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2112: @*/
2113: PetscErrorCode VecRestoreArrayAndMemType(Vec x, PetscScalar **a)
2114: {
2118: if (x->ops->restorearrayandmemtype) {
2119: /* VECCUDA, VECKOKKOS etc */
2120: PetscUseTypeMethod(x, restorearrayandmemtype, a);
2121: } else {
2122: /* VECNEST, VECVIENNACL */
2123: VecRestoreArray(x, a);
2124: } /* VECSTANDARD does nothing */
2125: if (a) *a = NULL;
2126: PetscObjectStateIncrease((PetscObject)x);
2127: return 0;
2128: }
2130: /*@C
2131: VecGetArrayReadAndMemType - Like VecGetArrayRead(), but if the input vector is a device vector, it will return a read-only device pointer. The returned pointer is guarenteed to point to up-to-date data. For host vectors, it functions as VecGetArrayRead().
2133: Not Collective
2135: Input Parameter:
2136: . x - the vector
2138: Output Parameters:
2139: + a - the array
2140: - mtype - memory type of the array
2142: Level: beginner
2144: Notes:
2145: The array must be returned using a matching call to VecRestoreArrayReadAndMemType().
2147: .seealso: `VecRestoreArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`, `VecGetArrayAndMemType()`
2148: @*/
2149: PetscErrorCode VecGetArrayReadAndMemType(Vec x, const PetscScalar **a, PetscMemType *mtype)
2150: {
2155: if (x->ops->getarrayreadandmemtype) {
2156: /* VECCUDA/VECHIP though they are also petscnative */
2157: PetscUseTypeMethod(x, getarrayreadandmemtype, a, mtype);
2158: } else if (x->ops->getarrayandmemtype) {
2159: /* VECKOKKOS */
2160: PetscUseTypeMethod(x, getarrayandmemtype, (PetscScalar **)a, mtype);
2161: } else {
2162: VecGetArrayRead(x, a);
2163: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2164: }
2165: return 0;
2166: return 0;
2167: }
2169: /*@C
2170: VecRestoreArrayReadAndMemType - Restore array obtained with VecGetArrayReadAndMemType()
2172: Not Collective
2174: Input Parameters:
2175: + vec - the vector
2176: - array - the array
2178: Level: beginner
2180: .seealso: `VecGetArrayReadAndMemType()`, `VecRestoreArrayAndMemType()`, `VecRestoreArrayWriteAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2181: @*/
2182: PetscErrorCode VecRestoreArrayReadAndMemType(Vec x, const PetscScalar **a)
2183: {
2187: if (x->ops->restorearrayreadandmemtype) {
2188: /* VECCUDA/VECHIP */
2189: PetscUseTypeMethod(x, restorearrayreadandmemtype, a);
2190: } else if (!x->petscnative) {
2191: /* VECNEST */
2192: VecRestoreArrayRead(x, a);
2193: }
2194: if (a) *a = NULL;
2195: return 0;
2196: }
2198: /*@C
2199: VecGetArrayWriteAndMemType - Like VecGetArrayWrite(), but if this is a device vector it will aways return
2200: a device pointer to the device memory that contains this processor's portion of the vector data.
2202: Not Collective
2204: Input Parameter:
2205: . x - the vector
2207: Output Parameters:
2208: + a - the array
2209: - mtype - memory type of the array
2211: Level: beginner
2213: Notes:
2214: The array must be returned using a matching call to VecRestoreArrayWriteAndMemType(), where it will label the device memory as most recent.
2216: .seealso: `VecRestoreArrayWriteAndMemType()`, `VecGetArrayReadAndMemType()`, `VecGetArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`,
2217: @*/
2218: PetscErrorCode VecGetArrayWriteAndMemType(Vec x, PetscScalar **a, PetscMemType *mtype)
2219: {
2222: VecSetErrorIfLocked(x, 1);
2225: if (x->ops->getarraywriteandmemtype) {
2226: /* VECCUDA, VECHIP, VECKOKKOS etc, though they are also petscnative */
2227: PetscUseTypeMethod(x, getarraywriteandmemtype, a, mtype);
2228: } else if (x->ops->getarrayandmemtype) {
2229: VecGetArrayAndMemType(x, a, mtype);
2230: } else {
2231: /* VECNEST, VECVIENNACL */
2232: VecGetArrayWrite(x, a);
2233: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2234: }
2235: return 0;
2236: }
2238: /*@C
2239: VecRestoreArrayWriteAndMemType - Restore array obtained with VecGetArrayWriteAndMemType()
2241: Not Collective
2243: Input Parameters:
2244: + vec - the vector
2245: - array - the array
2247: Level: beginner
2249: .seealso: `VecGetArrayWriteAndMemType()`, `VecRestoreArrayAndMemType()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayPair()`, `VecRestoreArrayPair()`
2250: @*/
2251: PetscErrorCode VecRestoreArrayWriteAndMemType(Vec x, PetscScalar **a)
2252: {
2255: VecSetErrorIfLocked(x, 1);
2257: if (x->ops->restorearraywriteandmemtype) {
2258: /* VECCUDA/VECHIP */
2259: PetscMemType PETSC_UNUSED mtype; // since this function doesn't accept a memtype?
2260: PetscUseTypeMethod(x, restorearraywriteandmemtype, a, &mtype);
2261: } else if (x->ops->restorearrayandmemtype) {
2262: VecRestoreArrayAndMemType(x, a);
2263: } else {
2264: VecRestoreArray(x, a);
2265: }
2266: if (a) *a = NULL;
2267: return 0;
2268: }
2270: /*@
2271: VecPlaceArray - Allows one to replace the array in a vector with an
2272: array provided by the user. This is useful to avoid copying an array
2273: into a vector.
2275: Not Collective
2277: Input Parameters:
2278: + vec - the vector
2279: - array - the array
2281: Notes:
2282: You can return to the original array with a call to `VecResetArray()`. `vec` does not take
2283: ownership of `array` in any way. The user must free `array` themselves but be careful not to
2284: do so before the vector has either been destroyed, had its original array restored with
2285: `VecResetArray()` or permanently replaced with `VecReplaceArray()`.
2287: Level: developer
2289: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecResetArray()`
2291: @*/
2292: PetscErrorCode VecPlaceArray(Vec vec, const PetscScalar array[])
2293: {
2297: PetscUseTypeMethod(vec, placearray, array);
2298: PetscObjectStateIncrease((PetscObject)vec);
2299: return 0;
2300: }
2302: /*@C
2303: VecReplaceArray - Allows one to replace the array in a vector with an
2304: array provided by the user. This is useful to avoid copying an array
2305: into a vector.
2307: Not Collective
2309: Input Parameters:
2310: + vec - the vector
2311: - array - the array
2313: Notes:
2314: This permanently replaces the array and frees the memory associated
2315: with the old array.
2317: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
2318: freed by the user. It will be freed when the vector is destroyed.
2320: Not supported from Fortran
2322: Level: developer
2324: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`
2326: @*/
2327: PetscErrorCode VecReplaceArray(Vec vec, const PetscScalar array[])
2328: {
2331: PetscUseTypeMethod(vec, replacearray, array);
2332: PetscObjectStateIncrease((PetscObject)vec);
2333: return 0;
2334: }
2336: /*@C
2337: VecCUDAGetArray - Provides access to the CUDA buffer inside a vector.
2339: This function has semantics similar to VecGetArray(): the pointer
2340: returned by this function points to a consistent view of the vector
2341: data. This may involve a copy operation of data from the host to the
2342: device if the data on the device is out of date. If the device
2343: memory hasn't been allocated previously it will be allocated as part
2344: of this function call. VecCUDAGetArray() assumes that
2345: the user will modify the vector data. This is similar to
2346: intent(inout) in fortran.
2348: The CUDA device pointer has to be released by calling
2349: VecCUDARestoreArray(). Upon restoring the vector data
2350: the data on the host will be marked as out of date. A subsequent
2351: access of the host data will thus incur a data transfer from the
2352: device to the host.
2354: Input Parameter:
2355: . v - the vector
2357: Output Parameter:
2358: . a - the CUDA device pointer
2360: Fortran note:
2361: This function is not currently available from Fortran.
2363: Level: intermediate
2365: .seealso: `VecCUDARestoreArray()`, `VecCUDAGetArrayRead()`, `VecCUDAGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
2366: @*/
2367: PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
2368: {
2370: #if defined(PETSC_HAVE_CUDA)
2371: {
2372: VecCUDACopyToGPU(v);
2373: *a = ((Vec_CUDA *)v->spptr)->GPUarray;
2374: }
2375: #endif
2376: return 0;
2377: }
2379: /*@C
2380: VecCUDARestoreArray - Restore a CUDA device pointer previously acquired with VecCUDAGetArray().
2382: This marks the host data as out of date. Subsequent access to the
2383: vector data on the host side with for instance VecGetArray() incurs a
2384: data transfer.
2386: Input Parameters:
2387: + v - the vector
2388: - a - the CUDA device pointer. This pointer is invalid after
2389: VecCUDARestoreArray() returns.
2391: Fortran note:
2392: This function is not currently available from Fortran.
2394: Level: intermediate
2396: .seealso: `VecCUDAGetArray()`, `VecCUDAGetArrayRead()`, `VecCUDAGetArrayWrite()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
2397: @*/
2398: PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
2399: {
2401: #if defined(PETSC_HAVE_CUDA)
2402: v->offloadmask = PETSC_OFFLOAD_GPU;
2403: #endif
2404: PetscObjectStateIncrease((PetscObject)v);
2405: return 0;
2406: }
2408: /*@C
2409: VecCUDAGetArrayRead - Provides read access to the CUDA buffer inside a vector.
2411: This function is analogous to VecGetArrayRead(): The pointer
2412: returned by this function points to a consistent view of the vector
2413: data. This may involve a copy operation of data from the host to the
2414: device if the data on the device is out of date. If the device
2415: memory hasn't been allocated previously it will be allocated as part
2416: of this function call. VecCUDAGetArrayRead() assumes that the
2417: user will not modify the vector data. This is analgogous to
2418: intent(in) in Fortran.
2420: The CUDA device pointer has to be released by calling
2421: VecCUDARestoreArrayRead(). If the data on the host side was
2422: previously up to date it will remain so, i.e. data on both the device
2423: and the host is up to date. Accessing data on the host side does not
2424: incur a device to host data transfer.
2426: Input Parameter:
2427: . v - the vector
2429: Output Parameter:
2430: . a - the CUDA pointer.
2432: Fortran note:
2433: This function is not currently available from Fortran.
2435: Level: intermediate
2437: .seealso: `VecCUDARestoreArrayRead()`, `VecCUDAGetArray()`, `VecCUDAGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
2438: @*/
2439: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v, const PetscScalar **a)
2440: {
2441: VecCUDAGetArray(v, (PetscScalar **)a);
2442: return 0;
2443: }
2445: /*@C
2446: VecCUDARestoreArrayRead - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayRead().
2448: If the data on the host side was previously up to date it will remain
2449: so, i.e. data on both the device and the host is up to date.
2450: Accessing data on the host side e.g. with VecGetArray() does not
2451: incur a device to host data transfer.
2453: Input Parameters:
2454: + v - the vector
2455: - a - the CUDA device pointer. This pointer is invalid after
2456: VecCUDARestoreArrayRead() returns.
2458: Fortran note:
2459: This function is not currently available from Fortran.
2461: Level: intermediate
2463: .seealso: `VecCUDAGetArrayRead()`, `VecCUDAGetArrayWrite()`, `VecCUDAGetArray()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
2464: @*/
2465: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
2466: {
2468: *a = NULL;
2469: return 0;
2470: }
2472: /*@C
2473: VecCUDAGetArrayWrite - Provides write access to the CUDA buffer inside a vector.
2475: The data pointed to by the device pointer is uninitialized. The user
2476: may not read from this data. Furthermore, the entire array needs to
2477: be filled by the user to obtain well-defined behaviour. The device
2478: memory will be allocated by this function if it hasn't been allocated
2479: previously. This is analogous to intent(out) in Fortran.
2481: The device pointer needs to be released with
2482: VecCUDARestoreArrayWrite(). When the pointer is released the
2483: host data of the vector is marked as out of data. Subsequent access
2484: of the host data with e.g. VecGetArray() incurs a device to host data
2485: transfer.
2487: Input Parameter:
2488: . v - the vector
2490: Output Parameter:
2491: . a - the CUDA pointer
2493: Fortran note:
2494: This function is not currently available from Fortran.
2496: Level: advanced
2498: .seealso: `VecCUDARestoreArrayWrite()`, `VecCUDAGetArray()`, `VecCUDAGetArrayRead()`, `VecCUDAGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
2499: @*/
2500: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
2501: {
2503: #if defined(PETSC_HAVE_CUDA)
2504: {
2505: VecCUDAAllocateCheck(v);
2506: *a = ((Vec_CUDA *)v->spptr)->GPUarray;
2507: }
2508: #endif
2509: return 0;
2510: }
2512: /*@C
2513: VecCUDARestoreArrayWrite - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayWrite().
2515: Data on the host will be marked as out of date. Subsequent access of
2516: the data on the host side e.g. with VecGetArray() will incur a device
2517: to host data transfer.
2519: Input Parameters:
2520: + v - the vector
2521: - a - the CUDA device pointer. This pointer is invalid after
2522: VecCUDARestoreArrayWrite() returns.
2524: Fortran note:
2525: This function is not currently available from Fortran.
2527: Level: intermediate
2529: .seealso: `VecCUDAGetArrayWrite()`, `VecCUDAGetArray()`, `VecCUDAGetArrayRead()`, `VecCUDAGetArrayWrite()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
2530: @*/
2531: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
2532: {
2534: #if defined(PETSC_HAVE_CUDA)
2535: v->offloadmask = PETSC_OFFLOAD_GPU;
2536: if (a) *a = NULL;
2537: #endif
2538: PetscObjectStateIncrease((PetscObject)v);
2539: return 0;
2540: }
2542: /*@C
2543: VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
2544: GPU array provided by the user. This is useful to avoid copying an
2545: array into a vector.
2547: Not Collective
2549: Input Parameters:
2550: + vec - the vector
2551: - array - the GPU array
2553: Notes:
2554: You can return to the original GPU array with a call to VecCUDAResetArray()
2555: It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
2556: same time on the same vector.
2558: `vec` does not take ownership of `array` in any way. The user must free `array` themselves
2559: but be careful not to do so before the vector has either been destroyed, had its original
2560: array restored with `VecCUDAResetArray()` or permanently replaced with
2561: `VecCUDAReplaceArray()`.
2563: Level: developer
2565: .seealso: `VecPlaceArray()`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecResetArray()`, `VecCUDAResetArray()`, `VecCUDAReplaceArray()`
2567: @*/
2568: PetscErrorCode VecCUDAPlaceArray(Vec vin, const PetscScalar a[])
2569: {
2571: #if defined(PETSC_HAVE_CUDA)
2572: VecCUDACopyToGPU(vin);
2574: ((Vec_Seq *)vin->data)->unplacedarray = (PetscScalar *)((Vec_CUDA *)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2575: ((Vec_CUDA *)vin->spptr)->GPUarray = (PetscScalar *)a;
2576: vin->offloadmask = PETSC_OFFLOAD_GPU;
2577: #endif
2578: PetscObjectStateIncrease((PetscObject)vin);
2579: return 0;
2580: }
2582: /*@C
2583: VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
2584: with a GPU array provided by the user. This is useful to avoid copying
2585: a GPU array into a vector.
2587: Not Collective
2589: Input Parameters:
2590: + vec - the vector
2591: - array - the GPU array
2593: Notes:
2594: This permanently replaces the GPU array and frees the memory associated
2595: with the old GPU array.
2597: The memory passed in CANNOT be freed by the user. It will be freed
2598: when the vector is destroyed.
2600: Not supported from Fortran
2602: Level: developer
2604: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`, `VecCUDAResetArray()`, `VecCUDAPlaceArray()`, `VecReplaceArray()`
2606: @*/
2607: PetscErrorCode VecCUDAReplaceArray(Vec vin, const PetscScalar a[])
2608: {
2609: #if defined(PETSC_HAVE_CUDA)
2610: #endif
2613: #if defined(PETSC_HAVE_CUDA)
2614: if (((Vec_CUDA *)vin->spptr)->GPUarray_allocated) cudaFree(((Vec_CUDA *)vin->spptr)->GPUarray_allocated);
2615: ((Vec_CUDA *)vin->spptr)->GPUarray_allocated = ((Vec_CUDA *)vin->spptr)->GPUarray = (PetscScalar *)a;
2616: vin->offloadmask = PETSC_OFFLOAD_GPU;
2617: #endif
2618: PetscObjectStateIncrease((PetscObject)vin);
2619: return 0;
2620: }
2622: /*@C
2623: VecCUDAResetArray - Resets a vector to use its default memory. Call this
2624: after the use of VecCUDAPlaceArray().
2626: Not Collective
2628: Input Parameters:
2629: . vec - the vector
2631: Level: developer
2633: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`, `VecResetArray()`, `VecCUDAPlaceArray()`, `VecCUDAReplaceArray()`
2635: @*/
2636: PetscErrorCode VecCUDAResetArray(Vec vin)
2637: {
2639: #if defined(PETSC_HAVE_CUDA)
2640: VecCUDACopyToGPU(vin);
2641: ((Vec_CUDA *)vin->spptr)->GPUarray = (PetscScalar *)((Vec_Seq *)vin->data)->unplacedarray;
2642: ((Vec_Seq *)vin->data)->unplacedarray = 0;
2643: vin->offloadmask = PETSC_OFFLOAD_GPU;
2644: #endif
2645: PetscObjectStateIncrease((PetscObject)vin);
2646: return 0;
2647: }
2649: /*@C
2650: VecHIPGetArray - Provides access to the HIP buffer inside a vector.
2652: This function has semantics similar to VecGetArray(): the pointer
2653: returned by this function points to a consistent view of the vector
2654: data. This may involve a copy operation of data from the host to the
2655: device if the data on the device is out of date. If the device
2656: memory hasn't been allocated previously it will be allocated as part
2657: of this function call. VecHIPGetArray() assumes that
2658: the user will modify the vector data. This is similar to
2659: intent(inout) in fortran.
2661: The HIP device pointer has to be released by calling
2662: VecHIPRestoreArray(). Upon restoring the vector data
2663: the data on the host will be marked as out of date. A subsequent
2664: access of the host data will thus incur a data transfer from the
2665: device to the host.
2667: Input Parameter:
2668: . v - the vector
2670: Output Parameter:
2671: . a - the HIP device pointer
2673: Fortran note:
2674: This function is not currently available from Fortran.
2676: Level: intermediate
2678: .seealso: `VecHIPRestoreArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
2679: @*/
2680: PETSC_EXTERN PetscErrorCode VecHIPGetArray(Vec v, PetscScalar **a)
2681: {
2683: #if defined(PETSC_HAVE_HIP)
2684: *a = 0;
2685: VecHIPCopyToGPU(v);
2686: *a = ((Vec_HIP *)v->spptr)->GPUarray;
2687: #endif
2688: return 0;
2689: }
2691: /*@C
2692: VecHIPRestoreArray - Restore a HIP device pointer previously acquired with VecHIPGetArray().
2694: This marks the host data as out of date. Subsequent access to the
2695: vector data on the host side with for instance VecGetArray() incurs a
2696: data transfer.
2698: Input Parameters:
2699: + v - the vector
2700: - a - the HIP device pointer. This pointer is invalid after
2701: VecHIPRestoreArray() returns.
2703: Fortran note:
2704: This function is not currently available from Fortran.
2706: Level: intermediate
2708: .seealso: `VecHIPGetArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
2709: @*/
2710: PETSC_EXTERN PetscErrorCode VecHIPRestoreArray(Vec v, PetscScalar **a)
2711: {
2713: #if defined(PETSC_HAVE_HIP)
2714: v->offloadmask = PETSC_OFFLOAD_GPU;
2715: #endif
2717: PetscObjectStateIncrease((PetscObject)v);
2718: return 0;
2719: }
2721: /*@C
2722: VecHIPGetArrayRead - Provides read access to the HIP buffer inside a vector.
2724: This function is analogous to VecGetArrayRead(): The pointer
2725: returned by this function points to a consistent view of the vector
2726: data. This may involve a copy operation of data from the host to the
2727: device if the data on the device is out of date. If the device
2728: memory hasn't been allocated previously it will be allocated as part
2729: of this function call. VecHIPGetArrayRead() assumes that the
2730: user will not modify the vector data. This is analgogous to
2731: intent(in) in Fortran.
2733: The HIP device pointer has to be released by calling
2734: VecHIPRestoreArrayRead(). If the data on the host side was
2735: previously up to date it will remain so, i.e. data on both the device
2736: and the host is up to date. Accessing data on the host side does not
2737: incur a device to host data transfer.
2739: Input Parameter:
2740: . v - the vector
2742: Output Parameter:
2743: . a - the HIP pointer.
2745: Fortran note:
2746: This function is not currently available from Fortran.
2748: Level: intermediate
2750: .seealso: `VecHIPRestoreArrayRead()`, `VecHIPGetArray()`, `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
2751: @*/
2752: PETSC_EXTERN PetscErrorCode VecHIPGetArrayRead(Vec v, const PetscScalar **a)
2753: {
2755: #if defined(PETSC_HAVE_HIP)
2756: *a = 0;
2757: VecHIPCopyToGPU(v);
2758: *a = ((Vec_HIP *)v->spptr)->GPUarray;
2759: #endif
2760: return 0;
2761: }
2763: /*@C
2764: VecHIPRestoreArrayRead - Restore a HIP device pointer previously acquired with VecHIPGetArrayRead().
2766: If the data on the host side was previously up to date it will remain
2767: so, i.e. data on both the device and the host is up to date.
2768: Accessing data on the host side e.g. with VecGetArray() does not
2769: incur a device to host data transfer.
2771: Input Parameters:
2772: + v - the vector
2773: - a - the HIP device pointer. This pointer is invalid after
2774: VecHIPRestoreArrayRead() returns.
2776: Fortran note:
2777: This function is not currently available from Fortran.
2779: Level: intermediate
2781: .seealso: `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecHIPGetArray()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
2782: @*/
2783: PETSC_EXTERN PetscErrorCode VecHIPRestoreArrayRead(Vec v, const PetscScalar **a)
2784: {
2786: *a = NULL;
2787: return 0;
2788: }
2790: /*@C
2791: VecHIPGetArrayWrite - Provides write access to the HIP buffer inside a vector.
2793: The data pointed to by the device pointer is uninitialized. The user
2794: may not read from this data. Furthermore, the entire array needs to
2795: be filled by the user to obtain well-defined behaviour. The device
2796: memory will be allocated by this function if it hasn't been allocated
2797: previously. This is analogous to intent(out) in Fortran.
2799: The device pointer needs to be released with
2800: VecHIPRestoreArrayWrite(). When the pointer is released the
2801: host data of the vector is marked as out of data. Subsequent access
2802: of the host data with e.g. VecGetArray() incurs a device to host data
2803: transfer.
2805: Input Parameter:
2806: . v - the vector
2808: Output Parameter:
2809: . a - the HIP pointer
2811: Fortran note:
2812: This function is not currently available from Fortran.
2814: Level: advanced
2816: .seealso: `VecHIPRestoreArrayWrite()`, `VecHIPGetArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecGetArrayRead()`
2817: @*/
2818: PETSC_EXTERN PetscErrorCode VecHIPGetArrayWrite(Vec v, PetscScalar **a)
2819: {
2821: #if defined(PETSC_HAVE_HIP)
2822: *a = 0;
2823: VecHIPAllocateCheck(v);
2824: *a = ((Vec_HIP *)v->spptr)->GPUarray;
2825: #endif
2826: return 0;
2827: }
2829: /*@C
2830: VecHIPRestoreArrayWrite - Restore a HIP device pointer previously acquired with VecHIPGetArrayWrite().
2832: Data on the host will be marked as out of date. Subsequent access of
2833: the data on the host side e.g. with VecGetArray() will incur a device
2834: to host data transfer.
2836: Input Parameters:
2837: + v - the vector
2838: - a - the HIP device pointer. This pointer is invalid after
2839: VecHIPRestoreArrayWrite() returns.
2841: Fortran note:
2842: This function is not currently available from Fortran.
2844: Level: intermediate
2846: .seealso: `VecHIPGetArrayWrite()`, `VecHIPGetArray()`, `VecHIPGetArrayRead()`, `VecHIPGetArrayWrite()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`
2847: @*/
2848: PETSC_EXTERN PetscErrorCode VecHIPRestoreArrayWrite(Vec v, PetscScalar **a)
2849: {
2851: #if defined(PETSC_HAVE_HIP)
2852: v->offloadmask = PETSC_OFFLOAD_GPU;
2853: #endif
2855: PetscObjectStateIncrease((PetscObject)v);
2856: return 0;
2857: }
2859: /*@C
2860: VecHIPPlaceArray - Allows one to replace the GPU array in a vector with a
2861: GPU array provided by the user. This is useful to avoid copying an
2862: array into a vector.
2864: Not Collective
2866: Input Parameters:
2867: + vec - the vector
2868: - array - the GPU array
2870: Notes:
2871: You can return to the original GPU array with a call to VecHIPResetArray()
2872: It is not possible to use VecHIPPlaceArray() and VecPlaceArray() at the
2873: same time on the same vector.
2875: `vec` does not take ownership of `array` in any way. The user must free `array` themselves
2876: but be careful not to do so before the vector has either been destroyed, had its original
2877: array restored with `VecHIPResetArray()` or permanently replaced with
2878: `VecHIPReplaceArray()`.
2880: Level: developer
2882: .seealso: `VecPlaceArray()`, `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecResetArray()`, `VecHIPResetArray()`, `VecHIPReplaceArray()`
2884: @*/
2885: PetscErrorCode VecHIPPlaceArray(Vec vin, const PetscScalar a[])
2886: {
2888: #if defined(PETSC_HAVE_HIP)
2889: VecHIPCopyToGPU(vin);
2891: ((Vec_Seq *)vin->data)->unplacedarray = (PetscScalar *)((Vec_HIP *)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2892: ((Vec_HIP *)vin->spptr)->GPUarray = (PetscScalar *)a;
2893: vin->offloadmask = PETSC_OFFLOAD_GPU;
2894: #endif
2895: PetscObjectStateIncrease((PetscObject)vin);
2896: return 0;
2897: }
2899: /*@C
2900: VecHIPReplaceArray - Allows one to replace the GPU array in a vector
2901: with a GPU array provided by the user. This is useful to avoid copying
2902: a GPU array into a vector.
2904: Not Collective
2906: Input Parameters:
2907: + vec - the vector
2908: - array - the GPU array
2910: Notes:
2911: This permanently replaces the GPU array and frees the memory associated
2912: with the old GPU array.
2914: The memory passed in CANNOT be freed by the user. It will be freed
2915: when the vector is destroyed.
2917: Not supported from Fortran
2919: Level: developer
2921: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecPlaceArray()`, `VecResetArray()`, `VecHIPResetArray()`, `VecHIPPlaceArray()`, `VecReplaceArray()`
2923: @*/
2924: PetscErrorCode VecHIPReplaceArray(Vec vin, const PetscScalar a[])
2925: {
2927: #if defined(PETSC_HAVE_HIP)
2928: hipFree(((Vec_HIP *)vin->spptr)->GPUarray);
2929: ((Vec_HIP *)vin->spptr)->GPUarray = (PetscScalar *)a;
2930: vin->offloadmask = PETSC_OFFLOAD_GPU;
2931: #endif
2932: PetscObjectStateIncrease((PetscObject)vin);
2933: return 0;
2934: }
2936: /*@C
2937: VecHIPResetArray - Resets a vector to use its default memory. Call this
2938: after the use of VecHIPPlaceArray().
2940: Not Collective
2942: Input Parameters:
2943: . vec - the vector
2945: Level: developer
2947: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecReplaceArray()`, `VecPlaceArray()`, `VecResetArray()`, `VecHIPPlaceArray()`, `VecHIPReplaceArray()`
2949: @*/
2950: PetscErrorCode VecHIPResetArray(Vec vin)
2951: {
2953: #if defined(PETSC_HAVE_HIP)
2954: VecHIPCopyToGPU(vin);
2955: ((Vec_HIP *)vin->spptr)->GPUarray = (PetscScalar *)((Vec_Seq *)vin->data)->unplacedarray;
2956: ((Vec_Seq *)vin->data)->unplacedarray = 0;
2957: vin->offloadmask = PETSC_OFFLOAD_GPU;
2958: #endif
2959: PetscObjectStateIncrease((PetscObject)vin);
2960: return 0;
2961: }
2963: /*MC
2964: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2965: and makes them accessible via a Fortran90 pointer.
2967: Synopsis:
2968: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2970: Collective on Vec
2972: Input Parameters:
2973: + x - a vector to mimic
2974: - n - the number of vectors to obtain
2976: Output Parameters:
2977: + y - Fortran90 pointer to the array of vectors
2978: - ierr - error code
2980: Example of Usage:
2981: .vb
2982: #include <petsc/finclude/petscvec.h>
2983: use petscvec
2985: Vec x
2986: Vec, pointer :: y(:)
2987: ....
2988: call VecDuplicateVecsF90(x,2,y,ierr)
2989: call VecSet(y(2),alpha,ierr)
2990: call VecSet(y(2),alpha,ierr)
2991: ....
2992: call VecDestroyVecsF90(2,y,ierr)
2993: .ve
2995: Notes:
2996: Not yet supported for all F90 compilers
2998: Use VecDestroyVecsF90() to free the space.
3000: Level: beginner
3002: .seealso: `VecDestroyVecsF90()`, `VecDuplicateVecs()`
3004: M*/
3006: /*MC
3007: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
3008: VecGetArrayF90().
3010: Synopsis:
3011: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3013: Logically Collective on Vec
3015: Input Parameters:
3016: + x - vector
3017: - xx_v - the Fortran90 pointer to the array
3019: Output Parameter:
3020: . ierr - error code
3022: Example of Usage:
3023: .vb
3024: #include <petsc/finclude/petscvec.h>
3025: use petscvec
3027: PetscScalar, pointer :: xx_v(:)
3028: ....
3029: call VecGetArrayF90(x,xx_v,ierr)
3030: xx_v(3) = a
3031: call VecRestoreArrayF90(x,xx_v,ierr)
3032: .ve
3034: Level: beginner
3036: .seealso: `VecGetArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrayReadF90()`
3038: M*/
3040: /*MC
3041: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
3043: Synopsis:
3044: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
3046: Collective on Vec
3048: Input Parameters:
3049: + n - the number of vectors previously obtained
3050: - x - pointer to array of vector pointers
3052: Output Parameter:
3053: . ierr - error code
3055: Notes:
3056: Not yet supported for all F90 compilers
3058: Level: beginner
3060: .seealso: `VecDestroyVecs()`, `VecDuplicateVecsF90()`
3062: M*/
3064: /*MC
3065: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
3066: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
3067: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
3068: when you no longer need access to the array.
3070: Synopsis:
3071: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3073: Logically Collective on Vec
3075: Input Parameter:
3076: . x - vector
3078: Output Parameters:
3079: + xx_v - the Fortran90 pointer to the array
3080: - ierr - error code
3082: Example of Usage:
3083: .vb
3084: #include <petsc/finclude/petscvec.h>
3085: use petscvec
3087: PetscScalar, pointer :: xx_v(:)
3088: ....
3089: call VecGetArrayF90(x,xx_v,ierr)
3090: xx_v(3) = a
3091: call VecRestoreArrayF90(x,xx_v,ierr)
3092: .ve
3094: If you ONLY intend to read entries from the array and not change any entries you should use VecGetArrayReadF90().
3096: Level: beginner
3098: .seealso: `VecRestoreArrayF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayReadF90()`
3100: M*/
3102: /*MC
3103: VecGetArrayReadF90 - Accesses a read only array from Fortran90. For default PETSc
3104: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
3105: this routine is implementation dependent. You MUST call VecRestoreArrayReadF90()
3106: when you no longer need access to the array.
3108: Synopsis:
3109: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3111: Logically Collective on Vec
3113: Input Parameter:
3114: . x - vector
3116: Output Parameters:
3117: + xx_v - the Fortran90 pointer to the array
3118: - ierr - error code
3120: Example of Usage:
3121: .vb
3122: #include <petsc/finclude/petscvec.h>
3123: use petscvec
3125: PetscScalar, pointer :: xx_v(:)
3126: ....
3127: call VecGetArrayReadF90(x,xx_v,ierr)
3128: a = xx_v(3)
3129: call VecRestoreArrayReadF90(x,xx_v,ierr)
3130: .ve
3132: If you intend to write entries into the array you must use VecGetArrayF90().
3134: Level: beginner
3136: .seealso: `VecRestoreArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecGetArrayF90()`
3138: M*/
3140: /*MC
3141: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
3142: VecGetArrayReadF90().
3144: Synopsis:
3145: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3147: Logically Collective on Vec
3149: Input Parameters:
3150: + x - vector
3151: - xx_v - the Fortran90 pointer to the array
3153: Output Parameter:
3154: . ierr - error code
3156: Example of Usage:
3157: .vb
3158: #include <petsc/finclude/petscvec.h>
3159: use petscvec
3161: PetscScalar, pointer :: xx_v(:)
3162: ....
3163: call VecGetArrayReadF90(x,xx_v,ierr)
3164: a = xx_v(3)
3165: call VecRestoreArrayReadF90(x,xx_v,ierr)
3166: .ve
3168: Level: beginner
3170: .seealso: `VecGetArrayReadF90()`, `VecGetArray()`, `VecRestoreArray()`, `VecGetArrayRead()`, `VecRestoreArrayRead()`, `VecRestoreArrayF90()`
3172: M*/
3174: /*@C
3175: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
3176: processor's portion of the vector data. You MUST call VecRestoreArray2d()
3177: when you no longer need access to the array.
3179: Logically Collective
3181: Input Parameters:
3182: + x - the vector
3183: . m - first dimension of two dimensional array
3184: . n - second dimension of two dimensional array
3185: . mstart - first index you will use in first coordinate direction (often 0)
3186: - nstart - first index in the second coordinate direction (often 0)
3188: Output Parameter:
3189: . a - location to put pointer to the array
3191: Level: developer
3193: Notes:
3194: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3195: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3196: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3197: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3199: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3201: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3202: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3203: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3204: @*/
3205: PetscErrorCode VecGetArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3206: {
3207: PetscInt i, N;
3208: PetscScalar *aa;
3213: VecGetLocalSize(x, &N);
3215: VecGetArray(x, &aa);
3217: PetscMalloc1(m, a);
3218: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
3219: *a -= mstart;
3220: return 0;
3221: }
3223: /*@C
3224: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
3225: processor's portion of the vector data. You MUST call VecRestoreArray2dWrite()
3226: when you no longer need access to the array.
3228: Logically Collective
3230: Input Parameters:
3231: + x - the vector
3232: . m - first dimension of two dimensional array
3233: . n - second dimension of two dimensional array
3234: . mstart - first index you will use in first coordinate direction (often 0)
3235: - nstart - first index in the second coordinate direction (often 0)
3237: Output Parameter:
3238: . a - location to put pointer to the array
3240: Level: developer
3242: Notes:
3243: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3244: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3245: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3246: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3248: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3250: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3251: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3252: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3253: @*/
3254: PetscErrorCode VecGetArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3255: {
3256: PetscInt i, N;
3257: PetscScalar *aa;
3262: VecGetLocalSize(x, &N);
3264: VecGetArrayWrite(x, &aa);
3266: PetscMalloc1(m, a);
3267: for (i = 0; i < m; i++) (*a)[i] = aa + i * n - nstart;
3268: *a -= mstart;
3269: return 0;
3270: }
3272: /*@C
3273: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
3275: Logically Collective
3277: Input Parameters:
3278: + x - the vector
3279: . m - first dimension of two dimensional array
3280: . n - second dimension of the two dimensional array
3281: . mstart - first index you will use in first coordinate direction (often 0)
3282: . nstart - first index in the second coordinate direction (often 0)
3283: - a - location of pointer to array obtained from VecGetArray2d()
3285: Level: developer
3287: Notes:
3288: For regular PETSc vectors this routine does not involve any copies. For
3289: any special vectors that do not store local vector data in a contiguous
3290: array, this routine will copy the data back into the underlying
3291: vector data structure from the array obtained with VecGetArray().
3293: This routine actually zeros out the a pointer.
3295: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3296: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3297: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3298: @*/
3299: PetscErrorCode VecRestoreArray2d(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3300: {
3301: void *dummy;
3306: dummy = (void *)(*a + mstart);
3307: PetscFree(dummy);
3308: VecRestoreArray(x, NULL);
3309: return 0;
3310: }
3312: /*@C
3313: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite() has been called.
3315: Logically Collective
3317: Input Parameters:
3318: + x - the vector
3319: . m - first dimension of two dimensional array
3320: . n - second dimension of the two dimensional array
3321: . mstart - first index you will use in first coordinate direction (often 0)
3322: . nstart - first index in the second coordinate direction (often 0)
3323: - a - location of pointer to array obtained from VecGetArray2d()
3325: Level: developer
3327: Notes:
3328: For regular PETSc vectors this routine does not involve any copies. For
3329: any special vectors that do not store local vector data in a contiguous
3330: array, this routine will copy the data back into the underlying
3331: vector data structure from the array obtained with VecGetArray().
3333: This routine actually zeros out the a pointer.
3335: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3336: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3337: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3338: @*/
3339: PetscErrorCode VecRestoreArray2dWrite(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3340: {
3341: void *dummy;
3346: dummy = (void *)(*a + mstart);
3347: PetscFree(dummy);
3348: VecRestoreArrayWrite(x, NULL);
3349: return 0;
3350: }
3352: /*@C
3353: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
3354: processor's portion of the vector data. You MUST call VecRestoreArray1d()
3355: when you no longer need access to the array.
3357: Logically Collective
3359: Input Parameters:
3360: + x - the vector
3361: . m - first dimension of two dimensional array
3362: - mstart - first index you will use in first coordinate direction (often 0)
3364: Output Parameter:
3365: . a - location to put pointer to the array
3367: Level: developer
3369: Notes:
3370: For a vector obtained from DMCreateLocalVector() mstart are likely
3371: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3372: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3374: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3376: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3377: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3378: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3379: @*/
3380: PetscErrorCode VecGetArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3381: {
3382: PetscInt N;
3387: VecGetLocalSize(x, &N);
3389: VecGetArray(x, a);
3390: *a -= mstart;
3391: return 0;
3392: }
3394: /*@C
3395: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
3396: processor's portion of the vector data. You MUST call VecRestoreArray1dWrite()
3397: when you no longer need access to the array.
3399: Logically Collective
3401: Input Parameters:
3402: + x - the vector
3403: . m - first dimension of two dimensional array
3404: - mstart - first index you will use in first coordinate direction (often 0)
3406: Output Parameter:
3407: . a - location to put pointer to the array
3409: Level: developer
3411: Notes:
3412: For a vector obtained from DMCreateLocalVector() mstart are likely
3413: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3414: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3416: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3418: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3419: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3420: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3421: @*/
3422: PetscErrorCode VecGetArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3423: {
3424: PetscInt N;
3429: VecGetLocalSize(x, &N);
3431: VecGetArrayWrite(x, a);
3432: *a -= mstart;
3433: return 0;
3434: }
3436: /*@C
3437: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
3439: Logically Collective
3441: Input Parameters:
3442: + x - the vector
3443: . m - first dimension of two dimensional array
3444: . mstart - first index you will use in first coordinate direction (often 0)
3445: - a - location of pointer to array obtained from VecGetArray21()
3447: Level: developer
3449: Notes:
3450: For regular PETSc vectors this routine does not involve any copies. For
3451: any special vectors that do not store local vector data in a contiguous
3452: array, this routine will copy the data back into the underlying
3453: vector data structure from the array obtained with VecGetArray1d().
3455: This routine actually zeros out the a pointer.
3457: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3458: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3459: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3460: @*/
3461: PetscErrorCode VecRestoreArray1d(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3462: {
3465: VecRestoreArray(x, NULL);
3466: return 0;
3467: }
3469: /*@C
3470: VecRestoreArray1dWrite - Restores a vector after VecGetArray1dWrite() has been called.
3472: Logically Collective
3474: Input Parameters:
3475: + x - the vector
3476: . m - first dimension of two dimensional array
3477: . mstart - first index you will use in first coordinate direction (often 0)
3478: - a - location of pointer to array obtained from VecGetArray21()
3480: Level: developer
3482: Notes:
3483: For regular PETSc vectors this routine does not involve any copies. For
3484: any special vectors that do not store local vector data in a contiguous
3485: array, this routine will copy the data back into the underlying
3486: vector data structure from the array obtained with VecGetArray1d().
3488: This routine actually zeros out the a pointer.
3490: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3491: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3492: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3493: @*/
3494: PetscErrorCode VecRestoreArray1dWrite(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
3495: {
3498: VecRestoreArrayWrite(x, NULL);
3499: return 0;
3500: }
3502: /*@C
3503: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
3504: processor's portion of the vector data. You MUST call VecRestoreArray3d()
3505: when you no longer need access to the array.
3507: Logically Collective
3509: Input Parameters:
3510: + x - the vector
3511: . m - first dimension of three dimensional array
3512: . n - second dimension of three dimensional array
3513: . p - third dimension of three dimensional array
3514: . mstart - first index you will use in first coordinate direction (often 0)
3515: . nstart - first index in the second coordinate direction (often 0)
3516: - pstart - first index in the third coordinate direction (often 0)
3518: Output Parameter:
3519: . a - location to put pointer to the array
3521: Level: developer
3523: Notes:
3524: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3525: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3526: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3527: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3529: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3531: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3532: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3533: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3534: @*/
3535: PetscErrorCode VecGetArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3536: {
3537: PetscInt i, N, j;
3538: PetscScalar *aa, **b;
3543: VecGetLocalSize(x, &N);
3545: VecGetArray(x, &aa);
3547: PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a);
3548: b = (PetscScalar **)((*a) + m);
3549: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3550: for (i = 0; i < m; i++)
3551: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3552: *a -= mstart;
3553: return 0;
3554: }
3556: /*@C
3557: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3558: processor's portion of the vector data. You MUST call VecRestoreArray3dWrite()
3559: when you no longer need access to the array.
3561: Logically Collective
3563: Input Parameters:
3564: + x - the vector
3565: . m - first dimension of three dimensional array
3566: . n - second dimension of three dimensional array
3567: . p - third dimension of three dimensional array
3568: . mstart - first index you will use in first coordinate direction (often 0)
3569: . nstart - first index in the second coordinate direction (often 0)
3570: - pstart - first index in the third coordinate direction (often 0)
3572: Output Parameter:
3573: . a - location to put pointer to the array
3575: Level: developer
3577: Notes:
3578: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3579: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3580: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3581: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3583: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3585: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3586: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3587: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3588: @*/
3589: PetscErrorCode VecGetArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3590: {
3591: PetscInt i, N, j;
3592: PetscScalar *aa, **b;
3597: VecGetLocalSize(x, &N);
3599: VecGetArrayWrite(x, &aa);
3601: PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a);
3602: b = (PetscScalar **)((*a) + m);
3603: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3604: for (i = 0; i < m; i++)
3605: for (j = 0; j < n; j++) b[i * n + j] = aa + i * n * p + j * p - pstart;
3607: *a -= mstart;
3608: return 0;
3609: }
3611: /*@C
3612: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
3614: Logically Collective
3616: Input Parameters:
3617: + x - the vector
3618: . m - first dimension of three dimensional array
3619: . n - second dimension of the three dimensional array
3620: . p - third dimension of the three dimensional array
3621: . mstart - first index you will use in first coordinate direction (often 0)
3622: . nstart - first index in the second coordinate direction (often 0)
3623: . pstart - first index in the third coordinate direction (often 0)
3624: - a - location of pointer to array obtained from VecGetArray3d()
3626: Level: developer
3628: Notes:
3629: For regular PETSc vectors this routine does not involve any copies. For
3630: any special vectors that do not store local vector data in a contiguous
3631: array, this routine will copy the data back into the underlying
3632: vector data structure from the array obtained with VecGetArray().
3634: This routine actually zeros out the a pointer.
3636: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3637: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3638: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3639: @*/
3640: PetscErrorCode VecRestoreArray3d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3641: {
3642: void *dummy;
3647: dummy = (void *)(*a + mstart);
3648: PetscFree(dummy);
3649: VecRestoreArray(x, NULL);
3650: return 0;
3651: }
3653: /*@C
3654: VecRestoreArray3dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3656: Logically Collective
3658: Input Parameters:
3659: + x - the vector
3660: . m - first dimension of three dimensional array
3661: . n - second dimension of the three dimensional array
3662: . p - third dimension of the three dimensional array
3663: . mstart - first index you will use in first coordinate direction (often 0)
3664: . nstart - first index in the second coordinate direction (often 0)
3665: . pstart - first index in the third coordinate direction (often 0)
3666: - a - location of pointer to array obtained from VecGetArray3d()
3668: Level: developer
3670: Notes:
3671: For regular PETSc vectors this routine does not involve any copies. For
3672: any special vectors that do not store local vector data in a contiguous
3673: array, this routine will copy the data back into the underlying
3674: vector data structure from the array obtained with VecGetArray().
3676: This routine actually zeros out the a pointer.
3678: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3679: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3680: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3681: @*/
3682: PetscErrorCode VecRestoreArray3dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
3683: {
3684: void *dummy;
3689: dummy = (void *)(*a + mstart);
3690: PetscFree(dummy);
3691: VecRestoreArrayWrite(x, NULL);
3692: return 0;
3693: }
3695: /*@C
3696: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3697: processor's portion of the vector data. You MUST call VecRestoreArray4d()
3698: when you no longer need access to the array.
3700: Logically Collective
3702: Input Parameters:
3703: + x - the vector
3704: . m - first dimension of four dimensional array
3705: . n - second dimension of four dimensional array
3706: . p - third dimension of four dimensional array
3707: . q - fourth dimension of four dimensional array
3708: . mstart - first index you will use in first coordinate direction (often 0)
3709: . nstart - first index in the second coordinate direction (often 0)
3710: . pstart - first index in the third coordinate direction (often 0)
3711: - qstart - first index in the fourth coordinate direction (often 0)
3713: Output Parameter:
3714: . a - location to put pointer to the array
3716: Level: beginner
3718: Notes:
3719: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3720: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3721: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3722: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3724: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3726: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3727: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3728: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3729: @*/
3730: PetscErrorCode VecGetArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3731: {
3732: PetscInt i, N, j, k;
3733: PetscScalar *aa, ***b, **c;
3738: VecGetLocalSize(x, &N);
3740: VecGetArray(x, &aa);
3742: PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a);
3743: b = (PetscScalar ***)((*a) + m);
3744: c = (PetscScalar **)(b + m * n);
3745: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3746: for (i = 0; i < m; i++)
3747: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3748: for (i = 0; i < m; i++)
3749: for (j = 0; j < n; j++)
3750: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3751: *a -= mstart;
3752: return 0;
3753: }
3755: /*@C
3756: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3757: processor's portion of the vector data. You MUST call VecRestoreArray4dWrite()
3758: when you no longer need access to the array.
3760: Logically Collective
3762: Input Parameters:
3763: + x - the vector
3764: . m - first dimension of four dimensional array
3765: . n - second dimension of four dimensional array
3766: . p - third dimension of four dimensional array
3767: . q - fourth dimension of four dimensional array
3768: . mstart - first index you will use in first coordinate direction (often 0)
3769: . nstart - first index in the second coordinate direction (often 0)
3770: . pstart - first index in the third coordinate direction (often 0)
3771: - qstart - first index in the fourth coordinate direction (often 0)
3773: Output Parameter:
3774: . a - location to put pointer to the array
3776: Level: beginner
3778: Notes:
3779: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3780: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3781: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3782: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3784: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3786: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3787: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3788: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3789: @*/
3790: PetscErrorCode VecGetArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3791: {
3792: PetscInt i, N, j, k;
3793: PetscScalar *aa, ***b, **c;
3798: VecGetLocalSize(x, &N);
3800: VecGetArrayWrite(x, &aa);
3802: PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a);
3803: b = (PetscScalar ***)((*a) + m);
3804: c = (PetscScalar **)(b + m * n);
3805: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
3806: for (i = 0; i < m; i++)
3807: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
3808: for (i = 0; i < m; i++)
3809: for (j = 0; j < n; j++)
3810: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = aa + i * n * p * q + j * p * q + k * q - qstart;
3811: *a -= mstart;
3812: return 0;
3813: }
3815: /*@C
3816: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
3818: Logically Collective
3820: Input Parameters:
3821: + x - the vector
3822: . m - first dimension of four dimensional array
3823: . n - second dimension of the four dimensional array
3824: . p - third dimension of the four dimensional array
3825: . q - fourth dimension of the four dimensional array
3826: . mstart - first index you will use in first coordinate direction (often 0)
3827: . nstart - first index in the second coordinate direction (often 0)
3828: . pstart - first index in the third coordinate direction (often 0)
3829: . qstart - first index in the fourth coordinate direction (often 0)
3830: - a - location of pointer to array obtained from VecGetArray4d()
3832: Level: beginner
3834: Notes:
3835: For regular PETSc vectors this routine does not involve any copies. For
3836: any special vectors that do not store local vector data in a contiguous
3837: array, this routine will copy the data back into the underlying
3838: vector data structure from the array obtained with VecGetArray().
3840: This routine actually zeros out the a pointer.
3842: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3843: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3844: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3845: @*/
3846: PetscErrorCode VecRestoreArray4d(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3847: {
3848: void *dummy;
3853: dummy = (void *)(*a + mstart);
3854: PetscFree(dummy);
3855: VecRestoreArray(x, NULL);
3856: return 0;
3857: }
3859: /*@C
3860: VecRestoreArray4dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3862: Logically Collective
3864: Input Parameters:
3865: + x - the vector
3866: . m - first dimension of four dimensional array
3867: . n - second dimension of the four dimensional array
3868: . p - third dimension of the four dimensional array
3869: . q - fourth dimension of the four dimensional array
3870: . mstart - first index you will use in first coordinate direction (often 0)
3871: . nstart - first index in the second coordinate direction (often 0)
3872: . pstart - first index in the third coordinate direction (often 0)
3873: . qstart - first index in the fourth coordinate direction (often 0)
3874: - a - location of pointer to array obtained from VecGetArray4d()
3876: Level: beginner
3878: Notes:
3879: For regular PETSc vectors this routine does not involve any copies. For
3880: any special vectors that do not store local vector data in a contiguous
3881: array, this routine will copy the data back into the underlying
3882: vector data structure from the array obtained with VecGetArray().
3884: This routine actually zeros out the a pointer.
3886: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3887: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3888: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
3889: @*/
3890: PetscErrorCode VecRestoreArray4dWrite(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
3891: {
3892: void *dummy;
3897: dummy = (void *)(*a + mstart);
3898: PetscFree(dummy);
3899: VecRestoreArrayWrite(x, NULL);
3900: return 0;
3901: }
3903: /*@C
3904: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3905: processor's portion of the vector data. You MUST call VecRestoreArray2dRead()
3906: when you no longer need access to the array.
3908: Logically Collective
3910: Input Parameters:
3911: + x - the vector
3912: . m - first dimension of two dimensional array
3913: . n - second dimension of two dimensional array
3914: . mstart - first index you will use in first coordinate direction (often 0)
3915: - nstart - first index in the second coordinate direction (often 0)
3917: Output Parameter:
3918: . a - location to put pointer to the array
3920: Level: developer
3922: Notes:
3923: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3924: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3925: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3926: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3928: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3930: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
3931: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
3932: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3933: @*/
3934: PetscErrorCode VecGetArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3935: {
3936: PetscInt i, N;
3937: const PetscScalar *aa;
3942: VecGetLocalSize(x, &N);
3944: VecGetArrayRead(x, &aa);
3946: PetscMalloc1(m, a);
3947: for (i = 0; i < m; i++) (*a)[i] = (PetscScalar *)aa + i * n - nstart;
3948: *a -= mstart;
3949: return 0;
3950: }
3952: /*@C
3953: VecRestoreArray2dRead - Restores a vector after VecGetArray2dRead() has been called.
3955: Logically Collective
3957: Input Parameters:
3958: + x - the vector
3959: . m - first dimension of two dimensional array
3960: . n - second dimension of the two dimensional array
3961: . mstart - first index you will use in first coordinate direction (often 0)
3962: . nstart - first index in the second coordinate direction (often 0)
3963: - a - location of pointer to array obtained from VecGetArray2d()
3965: Level: developer
3967: Notes:
3968: For regular PETSc vectors this routine does not involve any copies. For
3969: any special vectors that do not store local vector data in a contiguous
3970: array, this routine will copy the data back into the underlying
3971: vector data structure from the array obtained with VecGetArray().
3973: This routine actually zeros out the a pointer.
3975: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
3976: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
3977: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
3978: @*/
3979: PetscErrorCode VecRestoreArray2dRead(Vec x, PetscInt m, PetscInt n, PetscInt mstart, PetscInt nstart, PetscScalar **a[])
3980: {
3981: void *dummy;
3986: dummy = (void *)(*a + mstart);
3987: PetscFree(dummy);
3988: VecRestoreArrayRead(x, NULL);
3989: return 0;
3990: }
3992: /*@C
3993: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3994: processor's portion of the vector data. You MUST call VecRestoreArray1dRead()
3995: when you no longer need access to the array.
3997: Logically Collective
3999: Input Parameters:
4000: + x - the vector
4001: . m - first dimension of two dimensional array
4002: - mstart - first index you will use in first coordinate direction (often 0)
4004: Output Parameter:
4005: . a - location to put pointer to the array
4007: Level: developer
4009: Notes:
4010: For a vector obtained from DMCreateLocalVector() mstart are likely
4011: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
4012: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
4014: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4016: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
4017: `VecRestoreArray2d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
4018: `VecGetArray2d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
4019: @*/
4020: PetscErrorCode VecGetArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
4021: {
4022: PetscInt N;
4027: VecGetLocalSize(x, &N);
4029: VecGetArrayRead(x, (const PetscScalar **)a);
4030: *a -= mstart;
4031: return 0;
4032: }
4034: /*@C
4035: VecRestoreArray1dRead - Restores a vector after VecGetArray1dRead() has been called.
4037: Logically Collective
4039: Input Parameters:
4040: + x - the vector
4041: . m - first dimension of two dimensional array
4042: . mstart - first index you will use in first coordinate direction (often 0)
4043: - a - location of pointer to array obtained from VecGetArray21()
4045: Level: developer
4047: Notes:
4048: For regular PETSc vectors this routine does not involve any copies. For
4049: any special vectors that do not store local vector data in a contiguous
4050: array, this routine will copy the data back into the underlying
4051: vector data structure from the array obtained with VecGetArray1dRead().
4053: This routine actually zeros out the a pointer.
4055: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
4056: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
4057: `VecGetArray1d()`, `VecRestoreArray2d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
4058: @*/
4059: PetscErrorCode VecRestoreArray1dRead(Vec x, PetscInt m, PetscInt mstart, PetscScalar *a[])
4060: {
4063: VecRestoreArrayRead(x, NULL);
4064: return 0;
4065: }
4067: /*@C
4068: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
4069: processor's portion of the vector data. You MUST call VecRestoreArray3dRead()
4070: when you no longer need access to the array.
4072: Logically Collective
4074: Input Parameters:
4075: + x - the vector
4076: . m - first dimension of three dimensional array
4077: . n - second dimension of three dimensional array
4078: . p - third dimension of three dimensional array
4079: . mstart - first index you will use in first coordinate direction (often 0)
4080: . nstart - first index in the second coordinate direction (often 0)
4081: - pstart - first index in the third coordinate direction (often 0)
4083: Output Parameter:
4084: . a - location to put pointer to the array
4086: Level: developer
4088: Notes:
4089: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
4090: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
4091: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
4092: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3dRead().
4094: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4096: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
4097: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
4098: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
4099: @*/
4100: PetscErrorCode VecGetArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
4101: {
4102: PetscInt i, N, j;
4103: const PetscScalar *aa;
4104: PetscScalar **b;
4109: VecGetLocalSize(x, &N);
4111: VecGetArrayRead(x, &aa);
4113: PetscMalloc(m * sizeof(PetscScalar **) + m * n * sizeof(PetscScalar *), a);
4114: b = (PetscScalar **)((*a) + m);
4115: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
4116: for (i = 0; i < m; i++)
4117: for (j = 0; j < n; j++) b[i * n + j] = (PetscScalar *)aa + i * n * p + j * p - pstart;
4118: *a -= mstart;
4119: return 0;
4120: }
4122: /*@C
4123: VecRestoreArray3dRead - Restores a vector after VecGetArray3dRead() has been called.
4125: Logically Collective
4127: Input Parameters:
4128: + x - the vector
4129: . m - first dimension of three dimensional array
4130: . n - second dimension of the three dimensional array
4131: . p - third dimension of the three dimensional array
4132: . mstart - first index you will use in first coordinate direction (often 0)
4133: . nstart - first index in the second coordinate direction (often 0)
4134: . pstart - first index in the third coordinate direction (often 0)
4135: - a - location of pointer to array obtained from VecGetArray3dRead()
4137: Level: developer
4139: Notes:
4140: For regular PETSc vectors this routine does not involve any copies. For
4141: any special vectors that do not store local vector data in a contiguous
4142: array, this routine will copy the data back into the underlying
4143: vector data structure from the array obtained with VecGetArray().
4145: This routine actually zeros out the a pointer.
4147: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
4148: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
4149: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
4150: @*/
4151: PetscErrorCode VecRestoreArray3dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscScalar ***a[])
4152: {
4153: void *dummy;
4158: dummy = (void *)(*a + mstart);
4159: PetscFree(dummy);
4160: VecRestoreArrayRead(x, NULL);
4161: return 0;
4162: }
4164: /*@C
4165: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
4166: processor's portion of the vector data. You MUST call VecRestoreArray4dRead()
4167: when you no longer need access to the array.
4169: Logically Collective
4171: Input Parameters:
4172: + x - the vector
4173: . m - first dimension of four dimensional array
4174: . n - second dimension of four dimensional array
4175: . p - third dimension of four dimensional array
4176: . q - fourth dimension of four dimensional array
4177: . mstart - first index you will use in first coordinate direction (often 0)
4178: . nstart - first index in the second coordinate direction (often 0)
4179: . pstart - first index in the third coordinate direction (often 0)
4180: - qstart - first index in the fourth coordinate direction (often 0)
4182: Output Parameter:
4183: . a - location to put pointer to the array
4185: Level: beginner
4187: Notes:
4188: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
4189: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
4190: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
4191: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
4193: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4195: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecGetArrays()`, `VecGetArrayF90()`, `VecPlaceArray()`,
4196: `VecRestoreArray2d()`, `DMDAVecGetarray()`, `DMDAVecRestoreArray()`, `VecGetArray3d()`, `VecRestoreArray3d()`,
4197: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`
4198: @*/
4199: PetscErrorCode VecGetArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
4200: {
4201: PetscInt i, N, j, k;
4202: const PetscScalar *aa;
4203: PetscScalar ***b, **c;
4208: VecGetLocalSize(x, &N);
4210: VecGetArrayRead(x, &aa);
4212: PetscMalloc(m * sizeof(PetscScalar ***) + m * n * sizeof(PetscScalar **) + m * n * p * sizeof(PetscScalar *), a);
4213: b = (PetscScalar ***)((*a) + m);
4214: c = (PetscScalar **)(b + m * n);
4215: for (i = 0; i < m; i++) (*a)[i] = b + i * n - nstart;
4216: for (i = 0; i < m; i++)
4217: for (j = 0; j < n; j++) b[i * n + j] = c + i * n * p + j * p - pstart;
4218: for (i = 0; i < m; i++)
4219: for (j = 0; j < n; j++)
4220: for (k = 0; k < p; k++) c[i * n * p + j * p + k] = (PetscScalar *)aa + i * n * p * q + j * p * q + k * q - qstart;
4221: *a -= mstart;
4222: return 0;
4223: }
4225: /*@C
4226: VecRestoreArray4dRead - Restores a vector after VecGetArray3d() has been called.
4228: Logically Collective
4230: Input Parameters:
4231: + x - the vector
4232: . m - first dimension of four dimensional array
4233: . n - second dimension of the four dimensional array
4234: . p - third dimension of the four dimensional array
4235: . q - fourth dimension of the four dimensional array
4236: . mstart - first index you will use in first coordinate direction (often 0)
4237: . nstart - first index in the second coordinate direction (often 0)
4238: . pstart - first index in the third coordinate direction (often 0)
4239: . qstart - first index in the fourth coordinate direction (often 0)
4240: - a - location of pointer to array obtained from VecGetArray4dRead()
4242: Level: beginner
4244: Notes:
4245: For regular PETSc vectors this routine does not involve any copies. For
4246: any special vectors that do not store local vector data in a contiguous
4247: array, this routine will copy the data back into the underlying
4248: vector data structure from the array obtained with VecGetArray().
4250: This routine actually zeros out the a pointer.
4252: .seealso: `VecGetArray()`, `VecRestoreArray()`, `VecRestoreArrays()`, `VecRestoreArrayF90()`, `VecPlaceArray()`,
4253: `VecGetArray2d()`, `VecGetArray3d()`, `VecRestoreArray3d()`, `DMDAVecGetArray()`, `DMDAVecRestoreArray()`
4254: `VecGetArray1d()`, `VecRestoreArray1d()`, `VecGetArray4d()`, `VecRestoreArray4d()`, `VecGet`
4255: @*/
4256: PetscErrorCode VecRestoreArray4dRead(Vec x, PetscInt m, PetscInt n, PetscInt p, PetscInt q, PetscInt mstart, PetscInt nstart, PetscInt pstart, PetscInt qstart, PetscScalar ****a[])
4257: {
4258: void *dummy;
4263: dummy = (void *)(*a + mstart);
4264: PetscFree(dummy);
4265: VecRestoreArrayRead(x, NULL);
4266: return 0;
4267: }
4269: #if defined(PETSC_USE_DEBUG)
4271: /*@
4272: VecLockGet - Gets the current lock status of a vector
4274: Logically Collective on Vec
4276: Input Parameter:
4277: . x - the vector
4279: Output Parameter:
4280: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
4281: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
4283: Level: beginner
4285: .seealso: `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`
4286: @*/
4287: PetscErrorCode VecLockGet(Vec x, PetscInt *state)
4288: {
4290: *state = x->lock;
4291: return 0;
4292: }
4294: PetscErrorCode VecLockGetLocation(Vec x, const char *file[], const char *func[], int *line)
4295: {
4300: {
4301: const int index = x->lockstack.currentsize - 1;
4304: *file = x->lockstack.file[index];
4305: *func = x->lockstack.function[index];
4306: *line = x->lockstack.line[index];
4307: }
4308: return 0;
4309: }
4311: /*@
4312: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from writing
4314: Logically Collective on Vec
4316: Input Parameter:
4317: . x - the vector
4319: Notes:
4320: If this is set then calls to VecGetArray() or VecSetValues() or any other routines that change the vectors values will fail.
4322: The call can be nested, i.e., called multiple times on the same vector, but each VecLockReadPush(x) has to have one matching
4323: VecLockReadPop(x), which removes the latest read-only lock.
4325: Level: beginner
4327: .seealso: `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPop()`, `VecLockGet()`
4328: @*/
4329: PetscErrorCode VecLockReadPush(Vec x)
4330: {
4331: const char *file, *func;
4332: int index, line;
4336: if ((index = petscstack.currentsize - 2) == -1) {
4337: // vec was locked "outside" of petsc, either in user-land or main. the error message will
4338: // now show this function as the culprit, but it will include the stacktrace
4339: file = "unknown user-file";
4340: func = "unknown_user_function";
4341: line = 0;
4342: } else {
4344: file = petscstack.file[index];
4345: func = petscstack.function[index];
4346: line = petscstack.line[index];
4347: }
4348: PetscStackPush_Private(x->lockstack, file, func, line, petscstack.petscroutine[index], PETSC_FALSE);
4349: return 0;
4350: }
4352: /*@
4353: VecLockReadPop - Pops a read-only lock from a vector
4355: Logically Collective on Vec
4357: Input Parameter:
4358: . x - the vector
4360: Level: beginner
4362: .seealso: `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockGet()`
4363: @*/
4364: PetscErrorCode VecLockReadPop(Vec x)
4365: {
4368: {
4369: const char *previous = x->lockstack.function[x->lockstack.currentsize - 1];
4371: PetscStackPop_Private(x->lockstack, previous);
4372: }
4373: return 0;
4374: }
4376: /*@C
4377: VecLockWriteSet - Lock or unlock a vector for exclusive read/write access
4379: Logically Collective on Vec
4381: Input Parameters:
4382: + x - the vector
4383: - flg - PETSC_TRUE to lock the vector for exclusive read/write access; PETSC_FALSE to unlock it.
4385: Notes:
4386: The function is usefull in split-phase computations, which usually have a begin phase and an end phase.
4387: One can call VecLockWriteSet(x,PETSC_TRUE) in the begin phase to lock a vector for exclusive
4388: access, and call VecLockWriteSet(x,PETSC_FALSE) in the end phase to unlock the vector from exclusive
4389: access. In this way, one is ensured no other operations can access the vector in between. The code may like
4391: VecGetArray(x,&xdata); // begin phase
4392: VecLockWriteSet(v,PETSC_TRUE);
4394: Other operations, which can not acceess x anymore (they can access xdata, of course)
4396: VecRestoreArray(x,&vdata); // end phase
4397: VecLockWriteSet(v,PETSC_FALSE);
4399: The call can not be nested on the same vector, in other words, one can not call VecLockWriteSet(x,PETSC_TRUE)
4400: again before calling VecLockWriteSet(v,PETSC_FALSE).
4402: Level: beginner
4404: .seealso: `VecRestoreArray()`, `VecGetArrayRead()`, `VecLockReadPush()`, `VecLockReadPop()`, `VecLockGet()`
4405: @*/
4406: PetscErrorCode VecLockWriteSet(Vec x, PetscBool flg)
4407: {
4409: if (flg) {
4412: x->lock = -1;
4413: } else {
4415: x->lock = 0;
4416: }
4417: return 0;
4418: }
4420: /*@
4421: VecLockPush - Pushes a read-only lock on a vector to prevent it from writing
4423: Level: deprecated
4425: .seealso: `VecLockReadPush()`
4426: @*/
4427: PetscErrorCode VecLockPush(Vec x)
4428: {
4429: VecLockReadPush(x);
4430: return 0;
4431: }
4433: /*@
4434: VecLockPop - Pops a read-only lock from a vector
4436: Level: deprecated
4438: .seealso: `VecLockReadPop()`
4439: @*/
4440: PetscErrorCode VecLockPop(Vec x)
4441: {
4442: VecLockReadPop(x);
4443: return 0;
4444: }
4446: #endif