Actual source code: rvector.c
petsc-3.15.0 2021-03-30
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: static PetscInt VecGetSubVectorSavedStateId = -1;
18: PETSC_EXTERN PetscErrorCode VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)
19: {
20: #if defined(PETSC_USE_DEBUG)
21: PetscErrorCode ierr;
22: PetscInt n,i;
23: const PetscScalar *x;
26: #if defined(PETSC_HAVE_DEVICE)
27: if ((vec->petscnative || vec->ops->getarray) && (vec->offloadmask & PETSC_OFFLOAD_CPU)) {
28: #else
29: if (vec->petscnative || vec->ops->getarray) {
30: #endif
31: VecGetLocalSize(vec,&n);
32: VecGetArrayRead(vec,&x);
33: for (i=0; i<n; i++) {
34: if (begin) {
35: if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at beginning of function: Parameter number %D",i,argnum);
36: } else {
37: if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at end of function: Parameter number %D",i,argnum);
38: }
39: }
40: VecRestoreArrayRead(vec,&x);
41: }
42: #else
44: #endif
45: return(0);
46: }
48: /*@
49: VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
51: Logically Collective on Vec
53: Input Parameters:
54: . x, y - the vectors
56: Output Parameter:
57: . max - the result
59: Level: advanced
61: Notes:
62: x and y may be the same vector
63: if a particular y_i is zero, it is treated as 1 in the above formula
65: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
66: @*/
67: PetscErrorCode VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
68: {
78: VecCheckSameSize(x,1,y,2);
79: (*x->ops->maxpointwisedivide)(x,y,max);
80: return(0);
81: }
83: /*@
84: VecDot - Computes the vector dot product.
86: Collective on Vec
88: Input Parameters:
89: . x, y - the vectors
91: Output Parameter:
92: . val - the dot product
94: Performance Issues:
95: $ per-processor memory bandwidth
96: $ interprocessor latency
97: $ work load inbalance that causes certain processes to arrive much earlier than others
99: Notes for Users of Complex Numbers:
100: For complex vectors, VecDot() computes
101: $ val = (x,y) = y^H x,
102: where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex
103: inner product where the SECOND argument gets the complex conjugate. Since the BLASdot() complex conjugates the first
104: first argument we call the BLASdot() with the arguments reversed.
106: Use VecTDot() for the indefinite form
107: $ val = (x,y) = y^T x,
108: where y^T denotes the transpose of y.
110: Level: intermediate
113: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDotRealPart()
114: @*/
115: PetscErrorCode VecDot(Vec x,Vec y,PetscScalar *val)
116: {
126: VecCheckSameSize(x,1,y,2);
128: PetscLogEventBegin(VEC_Dot,x,y,0,0);
129: (*x->ops->dot)(x,y,val);
130: PetscLogEventEnd(VEC_Dot,x,y,0,0);
131: return(0);
132: }
134: /*@
135: VecDotRealPart - Computes the real part of the vector dot product.
137: Collective on Vec
139: Input Parameters:
140: . x, y - the vectors
142: Output Parameter:
143: . val - the real part of the dot product;
145: Performance Issues:
146: $ per-processor memory bandwidth
147: $ interprocessor latency
148: $ work load inbalance that causes certain processes to arrive much earlier than others
150: Notes for Users of Complex Numbers:
151: See VecDot() for more details on the definition of the dot product for complex numbers
153: For real numbers this returns the same value as VecDot()
155: 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
156: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
158: Developer Note: This is not currently optimized to compute only the real part of the dot product.
160: Level: intermediate
163: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDot(), VecDotNorm2()
164: @*/
165: PetscErrorCode VecDotRealPart(Vec x,Vec y,PetscReal *val)
166: {
168: PetscScalar fdot;
171: VecDot(x,y,&fdot);
172: *val = PetscRealPart(fdot);
173: return(0);
174: }
176: /*@
177: VecNorm - Computes the vector norm.
179: Collective on Vec
181: Input Parameters:
182: + x - the vector
183: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
184: NORM_1_AND_2, which computes both norms and stores them
185: in a two element array.
187: Output Parameter:
188: . val - the norm
190: Notes:
191: $ NORM_1 denotes sum_i |x_i|
192: $ NORM_2 denotes sqrt(sum_i |x_i|^2)
193: $ NORM_INFINITY denotes max_i |x_i|
195: For complex numbers NORM_1 will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
196: norm of the absolute values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
197: the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
198: people expect the former.
200: Level: intermediate
202: Performance Issues:
203: $ per-processor memory bandwidth
204: $ interprocessor latency
205: $ work load inbalance that causes certain processes to arrive much earlier than others
208: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
209: VecNormBegin(), VecNormEnd()
211: @*/
213: PetscErrorCode VecNorm(Vec x,NormType type,PetscReal *val)
214: {
215: PetscBool flg;
223: /*
224: * Cached data?
225: */
226: if (type!=NORM_1_AND_2) {
227: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
228: if (flg) return(0);
229: }
230: PetscLogEventBegin(VEC_Norm,x,0,0,0);
231: (*x->ops->norm)(x,type,val);
232: PetscLogEventEnd(VEC_Norm,x,0,0,0);
233: if (type!=NORM_1_AND_2) {
234: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
235: }
236: return(0);
237: }
239: /*@
240: VecNormAvailable - Returns the vector norm if it is already known.
242: Not Collective
244: Input Parameters:
245: + x - the vector
246: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
247: NORM_1_AND_2, which computes both norms and stores them
248: in a two element array.
250: Output Parameter:
251: + available - PETSC_TRUE if the val returned is valid
252: - val - the norm
254: Notes:
255: $ NORM_1 denotes sum_i |x_i|
256: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
257: $ NORM_INFINITY denotes max_i |x_i|
259: Level: intermediate
261: Performance Issues:
262: $ per-processor memory bandwidth
263: $ interprocessor latency
264: $ work load inbalance that causes certain processes to arrive much earlier than others
266: Compile Option:
267: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
268: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
269: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
272: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
273: VecNormBegin(), VecNormEnd()
275: @*/
276: PetscErrorCode VecNormAvailable(Vec x,NormType type,PetscBool *available,PetscReal *val)
277: {
285: *available = PETSC_FALSE;
286: if (type!=NORM_1_AND_2) {
287: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
288: }
289: return(0);
290: }
292: /*@
293: VecNormalize - Normalizes a vector by 2-norm.
295: Collective on Vec
297: Input Parameters:
298: + x - the vector
300: Output Parameter:
301: . x - the normalized vector
302: - val - the vector norm before normalization
304: Level: intermediate
307: @*/
308: PetscErrorCode VecNormalize(Vec x,PetscReal *val)
309: {
311: PetscReal norm;
316: PetscLogEventBegin(VEC_Normalize,x,0,0,0);
317: VecNorm(x,NORM_2,&norm);
318: if (norm == 0.0) {
319: PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
320: } else if (norm != 1.0) {
321: PetscScalar tmp = 1.0/norm;
322: VecScale(x,tmp);
323: }
324: if (val) *val = norm;
325: PetscLogEventEnd(VEC_Normalize,x,0,0,0);
326: return(0);
327: }
329: /*@C
330: VecMax - Determines the vector component with maximum real part and its location.
332: Collective on Vec
334: Input Parameter:
335: . x - the vector
337: Output Parameters:
338: + p - the location of val (pass NULL if you don't want this)
339: - val - the maximum component
341: Notes:
342: Returns the value PETSC_MIN_REAL and p = -1 if the vector is of length 0.
344: Returns the smallest index with the maximum value
345: Level: intermediate
348: .seealso: VecNorm(), VecMin()
349: @*/
350: PetscErrorCode VecMax(Vec x,PetscInt *p,PetscReal *val)
351: {
358: PetscLogEventBegin(VEC_Max,x,0,0,0);
359: (*x->ops->max)(x,p,val);
360: PetscLogEventEnd(VEC_Max,x,0,0,0);
361: return(0);
362: }
364: /*@C
365: VecMin - Determines the vector component with minimum real part and its location.
367: Collective on Vec
369: Input Parameters:
370: . x - the vector
372: Output Parameter:
373: + p - the location of val (pass NULL if you don't want this location)
374: - val - the minimum component
376: Level: intermediate
378: Notes:
379: Returns the value PETSC_MAX_REAL and p = -1 if the vector is of length 0.
381: This returns the smallest index with the minumum value
384: .seealso: VecMax()
385: @*/
386: PetscErrorCode VecMin(Vec x,PetscInt *p,PetscReal *val)
387: {
394: PetscLogEventBegin(VEC_Min,x,0,0,0);
395: (*x->ops->min)(x,p,val);
396: PetscLogEventEnd(VEC_Min,x,0,0,0);
397: return(0);
398: }
400: /*@
401: VecTDot - Computes an indefinite vector dot product. That is, this
402: routine does NOT use the complex conjugate.
404: Collective on Vec
406: Input Parameters:
407: . x, y - the vectors
409: Output Parameter:
410: . val - the dot product
412: Notes for Users of Complex Numbers:
413: For complex vectors, VecTDot() computes the indefinite form
414: $ val = (x,y) = y^T x,
415: where y^T denotes the transpose of y.
417: Use VecDot() for the inner product
418: $ val = (x,y) = y^H x,
419: where y^H denotes the conjugate transpose of y.
421: Level: intermediate
423: .seealso: VecDot(), VecMTDot()
424: @*/
425: PetscErrorCode VecTDot(Vec x,Vec y,PetscScalar *val)
426: {
436: VecCheckSameSize(x,1,y,2);
438: PetscLogEventBegin(VEC_TDot,x,y,0,0);
439: (*x->ops->tdot)(x,y,val);
440: PetscLogEventEnd(VEC_TDot,x,y,0,0);
441: return(0);
442: }
444: /*@
445: VecScale - Scales a vector.
447: Not collective on Vec
449: Input Parameters:
450: + x - the vector
451: - alpha - the scalar
453: Output Parameter:
454: . x - the scaled vector
456: Note:
457: For a vector with n components, VecScale() computes
458: $ x[i] = alpha * x[i], for i=1,...,n.
460: Level: intermediate
463: @*/
464: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
465: {
466: PetscReal norms[4] = {0.0,0.0,0.0, 0.0};
467: PetscBool flgs[4];
469: PetscInt i;
474: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
475: PetscLogEventBegin(VEC_Scale,x,0,0,0);
476: if (alpha != (PetscScalar)1.0) {
477: VecSetErrorIfLocked(x,1);
478: /* get current stashed norms */
479: for (i=0; i<4; i++) {
480: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
481: }
482: (*x->ops->scale)(x,alpha);
483: PetscObjectStateIncrease((PetscObject)x);
484: /* put the scaled stashed norms back into the Vec */
485: for (i=0; i<4; i++) {
486: if (flgs[i]) {
487: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
488: }
489: }
490: }
491: PetscLogEventEnd(VEC_Scale,x,0,0,0);
492: return(0);
493: }
495: /*@
496: VecSet - Sets all components of a vector to a single scalar value.
498: Logically Collective on Vec
500: Input Parameters:
501: + x - the vector
502: - alpha - the scalar
504: Output Parameter:
505: . x - the vector
507: Note:
508: For a vector of dimension n, VecSet() computes
509: $ x[i] = alpha, for i=1,...,n,
510: so that all vector entries then equal the identical
511: scalar value, alpha. Use the more general routine
512: VecSetValues() to set different vector entries.
514: You CANNOT call this after you have called VecSetValues() but before you call
515: VecAssemblyBegin/End().
517: Level: beginner
519: .seealso VecSetValues(), VecSetValuesBlocked(), VecSetRandom()
521: @*/
522: PetscErrorCode VecSet(Vec x,PetscScalar alpha)
523: {
524: PetscReal val;
530: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"You cannot call this after you have called VecSetValues() but\n before you have called VecAssemblyBegin/End()");
532: VecSetErrorIfLocked(x,1);
534: PetscLogEventBegin(VEC_Set,x,0,0,0);
535: (*x->ops->set)(x,alpha);
536: PetscLogEventEnd(VEC_Set,x,0,0,0);
537: PetscObjectStateIncrease((PetscObject)x);
539: /* norms can be simply set (if |alpha|*N not too large) */
540: val = PetscAbsScalar(alpha);
541: if (x->map->N == 0) {
542: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],0.0l);
543: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],0.0);
544: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],0.0);
545: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],0.0);
546: } else if (val > PETSC_MAX_REAL/x->map->N) {
547: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
548: } else {
549: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
550: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
551: val = PetscSqrtReal((PetscReal)x->map->N) * val;
552: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
553: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
554: }
555: return(0);
556: }
559: /*@
560: VecAXPY - Computes y = alpha x + y.
562: Logically Collective on Vec
564: Input Parameters:
565: + alpha - the scalar
566: - x, y - the vectors
568: Output Parameter:
569: . y - output vector
571: Level: intermediate
573: Notes:
574: x and y MUST be different vectors
575: This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
577: $ VecAXPY(y,alpha,x) y = alpha x + y
578: $ VecAYPX(y,beta,x) y = x + beta y
579: $ VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
580: $ VecWAXPY(w,alpha,x,y) w = alpha x + y
581: $ VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
582: $ VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
585: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPBYPCZ(), VecAXPBY()
586: @*/
587: PetscErrorCode VecAXPY(Vec y,PetscScalar alpha,Vec x)
588: {
597: VecCheckSameSize(x,1,y,3);
598: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
600: if (alpha == (PetscScalar)0.0) return(0);
601: VecSetErrorIfLocked(y,1);
603: VecLockReadPush(x);
604: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
605: (*y->ops->axpy)(y,alpha,x);
606: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
607: VecLockReadPop(x);
608: PetscObjectStateIncrease((PetscObject)y);
609: return(0);
610: }
612: /*@
613: VecAXPBY - Computes y = alpha x + beta y.
615: Logically Collective on Vec
617: Input Parameters:
618: + alpha,beta - the scalars
619: - x, y - the vectors
621: Output Parameter:
622: . y - output vector
624: Level: intermediate
626: Notes:
627: x and y MUST be different vectors
628: The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
631: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ()
632: @*/
633: PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
634: {
643: VecCheckSameSize(y,1,x,4);
644: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
647: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) return(0);
648: VecSetErrorIfLocked(y,1);
649: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
650: (*y->ops->axpby)(y,alpha,beta,x);
651: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
652: PetscObjectStateIncrease((PetscObject)y);
653: return(0);
654: }
656: /*@
657: VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
659: Logically Collective on Vec
661: Input Parameters:
662: + alpha,beta, gamma - the scalars
663: - x, y, z - the vectors
665: Output Parameter:
666: . z - output vector
668: Level: intermediate
670: Notes:
671: x, y and z must be different vectors
672: The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
675: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBY()
676: @*/
677: PetscErrorCode VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
678: {
690: VecCheckSameSize(x,1,y,5);
691: VecCheckSameSize(x,1,z,6);
692: if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
693: if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
697: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) return(0);
698: VecSetErrorIfLocked(z,1);
700: PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
701: (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
702: PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
703: PetscObjectStateIncrease((PetscObject)z);
704: return(0);
705: }
707: /*@
708: VecAYPX - Computes y = x + beta y.
710: Logically Collective on Vec
712: Input Parameters:
713: + beta - the scalar
714: - x, y - the vectors
716: Output Parameter:
717: . y - output vector
719: Level: intermediate
721: Notes:
722: x and y MUST be different vectors
723: The implementation is optimized for beta of -1.0, 0.0, and 1.0
726: .seealso: VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
727: @*/
728: PetscErrorCode VecAYPX(Vec y,PetscScalar beta,Vec x)
729: {
738: VecCheckSameSize(x,1,y,3);
739: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
741: VecSetErrorIfLocked(y,1);
743: PetscLogEventBegin(VEC_AYPX,x,y,0,0);
744: (*y->ops->aypx)(y,beta,x);
745: PetscLogEventEnd(VEC_AYPX,x,y,0,0);
746: PetscObjectStateIncrease((PetscObject)y);
747: return(0);
748: }
751: /*@
752: VecWAXPY - Computes w = alpha x + y.
754: Logically Collective on Vec
756: Input Parameters:
757: + alpha - the scalar
758: - x, y - the vectors
760: Output Parameter:
761: . w - the result
763: Level: intermediate
765: Notes:
766: w cannot be either x or y, but x and y can be the same
767: The implementation is optimzed for alpha of -1.0, 0.0, and 1.0
770: .seealso: VecAXPY(), VecAYPX(), VecAXPBY(), VecMAXPY(), VecAXPBYPCZ()
771: @*/
772: PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
773: {
785: VecCheckSameSize(x,3,y,4);
786: VecCheckSameSize(x,3,w,1);
787: if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
788: if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");
790: VecSetErrorIfLocked(w,1);
792: PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
793: (*w->ops->waxpy)(w,alpha,x,y);
794: PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
795: PetscObjectStateIncrease((PetscObject)w);
796: return(0);
797: }
800: /*@C
801: VecSetValues - Inserts or adds values into certain locations of a vector.
803: Not Collective
805: Input Parameters:
806: + x - vector to insert in
807: . ni - number of elements to add
808: . ix - indices where to add
809: . y - array of values
810: - iora - either INSERT_VALUES or ADD_VALUES, where
811: ADD_VALUES adds values to any existing entries, and
812: INSERT_VALUES replaces existing entries with new values
814: Notes:
815: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
817: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
818: options cannot be mixed without intervening calls to the assembly
819: routines.
821: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
822: MUST be called after all calls to VecSetValues() have been completed.
824: VecSetValues() uses 0-based indices in Fortran as well as in C.
826: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
827: negative indices may be passed in ix. These rows are
828: simply ignored. This allows easily inserting element load matrices
829: with homogeneous Dirchlet boundary conditions that you don't want represented
830: in the vector.
832: Level: beginner
834: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
835: VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
836: @*/
837: PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
838: {
843: if (!ni) return(0);
848: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
849: (*x->ops->setvalues)(x,ni,ix,y,iora);
850: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
851: PetscObjectStateIncrease((PetscObject)x);
852: return(0);
853: }
855: /*@C
856: VecGetValues - Gets values from certain locations of a vector. Currently
857: can only get values on the same processor
859: Not Collective
861: Input Parameters:
862: + x - vector to get values from
863: . ni - number of elements to get
864: - ix - indices where to get them from (in global 1d numbering)
866: Output Parameter:
867: . y - array of values
869: Notes:
870: The user provides the allocated array y; it is NOT allocated in this routine
872: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
874: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
876: VecGetValues() uses 0-based indices in Fortran as well as in C.
878: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
879: negative indices may be passed in ix. These rows are
880: simply ignored.
882: Level: beginner
884: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues()
885: @*/
886: PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
887: {
892: if (!ni) return(0);
896: (*x->ops->getvalues)(x,ni,ix,y);
897: return(0);
898: }
900: /*@C
901: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
903: Not Collective
905: Input Parameters:
906: + x - vector to insert in
907: . ni - number of blocks to add
908: . ix - indices where to add in block count, rather than element count
909: . y - array of values
910: - iora - either INSERT_VALUES or ADD_VALUES, where
911: ADD_VALUES adds values to any existing entries, and
912: INSERT_VALUES replaces existing entries with new values
914: Notes:
915: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
916: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
918: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
919: options cannot be mixed without intervening calls to the assembly
920: routines.
922: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
923: MUST be called after all calls to VecSetValuesBlocked() have been completed.
925: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
927: Negative indices may be passed in ix, these rows are
928: simply ignored. This allows easily inserting element load matrices
929: with homogeneous Dirchlet boundary conditions that you don't want represented
930: in the vector.
932: Level: intermediate
934: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
935: VecSetValues()
936: @*/
937: PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
938: {
943: if (!ni) return(0);
948: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
949: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
950: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
951: PetscObjectStateIncrease((PetscObject)x);
952: return(0);
953: }
956: /*@C
957: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
958: using a local ordering of the nodes.
960: Not Collective
962: Input Parameters:
963: + x - vector to insert in
964: . ni - number of elements to add
965: . ix - indices where to add
966: . y - array of values
967: - iora - either INSERT_VALUES or ADD_VALUES, where
968: ADD_VALUES adds values to any existing entries, and
969: INSERT_VALUES replaces existing entries with new values
971: Level: intermediate
973: Notes:
974: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
976: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
977: options cannot be mixed without intervening calls to the assembly
978: routines.
980: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
981: MUST be called after all calls to VecSetValuesLocal() have been completed.
983: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
985: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
986: VecSetValuesBlockedLocal()
987: @*/
988: PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
989: {
991: PetscInt lixp[128],*lix = lixp;
995: if (!ni) return(0);
1000: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1001: if (!x->ops->setvalueslocal) {
1002: if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
1003: if (ni > 128) {
1004: PetscMalloc1(ni,&lix);
1005: }
1006: ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
1007: (*x->ops->setvalues)(x,ni,lix,y,iora);
1008: if (ni > 128) {
1009: PetscFree(lix);
1010: }
1011: } else {
1012: (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
1013: }
1014: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1015: PetscObjectStateIncrease((PetscObject)x);
1016: return(0);
1017: }
1019: /*@
1020: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1021: using a local ordering of the nodes.
1023: Not Collective
1025: Input Parameters:
1026: + x - vector to insert in
1027: . ni - number of blocks to add
1028: . ix - indices where to add in block count, not element count
1029: . y - array of values
1030: - iora - either INSERT_VALUES or ADD_VALUES, where
1031: ADD_VALUES adds values to any existing entries, and
1032: INSERT_VALUES replaces existing entries with new values
1034: Level: intermediate
1036: Notes:
1037: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
1038: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
1040: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1041: options cannot be mixed without intervening calls to the assembly
1042: routines.
1044: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1045: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
1047: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
1050: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
1051: VecSetLocalToGlobalMapping()
1052: @*/
1053: PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1054: {
1056: PetscInt lixp[128],*lix = lixp;
1060: if (!ni) return(0);
1064: if (ni > 128) {
1065: PetscMalloc1(ni,&lix);
1066: }
1068: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1069: ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
1070: (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1071: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1072: if (ni > 128) {
1073: PetscFree(lix);
1074: }
1075: PetscObjectStateIncrease((PetscObject)x);
1076: return(0);
1077: }
1079: /*@
1080: VecMTDot - Computes indefinite vector multiple dot products.
1081: That is, it does NOT use the complex conjugate.
1083: Collective on Vec
1085: Input Parameters:
1086: + x - one vector
1087: . nv - number of vectors
1088: - y - array of vectors. Note that vectors are pointers
1090: Output Parameter:
1091: . val - array of the dot products
1093: Notes for Users of Complex Numbers:
1094: For complex vectors, VecMTDot() computes the indefinite form
1095: $ val = (x,y) = y^T x,
1096: where y^T denotes the transpose of y.
1098: Use VecMDot() for the inner product
1099: $ val = (x,y) = y^H x,
1100: where y^H denotes the conjugate transpose of y.
1102: Level: intermediate
1105: .seealso: VecMDot(), VecTDot()
1106: @*/
1107: PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1108: {
1114: if (!nv) return(0);
1121: VecCheckSameSize(x,1,*y,3);
1123: PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1124: (*x->ops->mtdot)(x,nv,y,val);
1125: PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1126: return(0);
1127: }
1129: /*@
1130: VecMDot - Computes vector multiple dot products.
1132: Collective on Vec
1134: Input Parameters:
1135: + x - one vector
1136: . nv - number of vectors
1137: - y - array of vectors.
1139: Output Parameter:
1140: . val - array of the dot products (does not allocate the array)
1142: Notes for Users of Complex Numbers:
1143: For complex vectors, VecMDot() computes
1144: $ val = (x,y) = y^H x,
1145: where y^H denotes the conjugate transpose of y.
1147: Use VecMTDot() for the indefinite form
1148: $ val = (x,y) = y^T x,
1149: where y^T denotes the transpose of y.
1151: Level: intermediate
1154: .seealso: VecMTDot(), VecDot()
1155: @*/
1156: PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1157: {
1163: if (!nv) return(0);
1164: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1171: VecCheckSameSize(x,1,*y,3);
1173: PetscLogEventBegin(VEC_MDot,x,*y,0,0);
1174: (*x->ops->mdot)(x,nv,y,val);
1175: PetscLogEventEnd(VEC_MDot,x,*y,0,0);
1176: return(0);
1177: }
1179: /*@
1180: VecMAXPY - Computes y = y + sum alpha[i] x[i]
1182: Logically Collective on Vec
1184: Input Parameters:
1185: + nv - number of scalars and x-vectors
1186: . alpha - array of scalars
1187: . y - one vector
1188: - x - array of vectors
1190: Level: intermediate
1192: Notes:
1193: y cannot be any of the x vectors
1195: .seealso: VecAYPX(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
1196: @*/
1197: PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1198: {
1200: PetscInt i;
1201: PetscBool nonzero;
1206: if (!nv) return(0);
1207: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1214: VecCheckSameSize(y,1,*x,4);
1216: for (i=0, nonzero = PETSC_FALSE; i<nv && !nonzero; i++) nonzero = (PetscBool)(nonzero || alpha[i] != (PetscScalar)0.0);
1217: if (!nonzero) return(0);
1218: VecSetErrorIfLocked(y,1);
1219: PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1220: (*y->ops->maxpy)(y,nv,alpha,x);
1221: PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1222: PetscObjectStateIncrease((PetscObject)y);
1223: return(0);
1224: }
1226: /*@
1227: VecConcatenate - Creates a new vector that is a vertical concatenation of all the given array of vectors
1228: in the order they appear in the array. The concatenated vector resides on the same
1229: communicator and is the same type as the source vectors.
1231: Collective on X
1233: Input Arguments:
1234: + nx - number of vectors to be concatenated
1235: - X - array containing the vectors to be concatenated in the order of concatenation
1237: Output Arguments:
1238: + Y - concatenated vector
1239: - x_is - array of index sets corresponding to the concatenated components of Y (NULL if not needed)
1241: Notes:
1242: Concatenation is similar to the functionality of a VecNest object; they both represent combination of
1243: different vector spaces. However, concatenated vectors do not store any information about their
1244: sub-vectors and own their own data. Consequently, this function provides index sets to enable the
1245: manipulation of data in the concatenated vector that corresponds to the original components at creation.
1247: This is a useful tool for outer loop algorithms, particularly constrained optimizers, where the solver
1248: has to operate on combined vector spaces and cannot utilize VecNest objects due to incompatibility with
1249: bound projections.
1251: Level: advanced
1253: .seealso: VECNEST, VECSCATTER, VecScatterCreate()
1254: @*/
1255: PetscErrorCode VecConcatenate(PetscInt nx, const Vec X[], Vec *Y, IS *x_is[])
1256: {
1257: MPI_Comm comm;
1258: VecType vec_type;
1259: Vec Ytmp, Xtmp;
1260: IS *is_tmp;
1261: PetscInt i, shift=0, Xnl, Xng, Xbegin;
1270: if ((*X)->ops->concatenate) {
1271: /* use the dedicated concatenation function if available */
1272: (*(*X)->ops->concatenate)(nx,X,Y,x_is);
1273: } else {
1274: /* loop over vectors and start creating IS */
1275: comm = PetscObjectComm((PetscObject)(*X));
1276: VecGetType(*X, &vec_type);
1277: PetscMalloc1(nx, &is_tmp);
1278: for (i=0; i<nx; i++) {
1279: VecGetSize(X[i], &Xng);
1280: VecGetLocalSize(X[i], &Xnl);
1281: VecGetOwnershipRange(X[i], &Xbegin, NULL);
1282: ISCreateStride(comm, Xnl, shift + Xbegin, 1, &is_tmp[i]);
1283: shift += Xng;
1284: }
1285: /* create the concatenated vector */
1286: VecCreate(comm, &Ytmp);
1287: VecSetType(Ytmp, vec_type);
1288: VecSetSizes(Ytmp, PETSC_DECIDE, shift);
1289: VecSetUp(Ytmp);
1290: /* copy data from X array to Y and return */
1291: for (i=0; i<nx; i++) {
1292: VecGetSubVector(Ytmp, is_tmp[i], &Xtmp);
1293: VecCopy(X[i], Xtmp);
1294: VecRestoreSubVector(Ytmp, is_tmp[i], &Xtmp);
1295: }
1296: *Y = Ytmp;
1297: if (x_is) {
1298: *x_is = is_tmp;
1299: } else {
1300: for (i=0; i<nx; i++) {
1301: ISDestroy(&is_tmp[i]);
1302: }
1303: PetscFree(is_tmp);
1304: }
1305: }
1306: return(0);
1307: }
1309: /*@
1310: VecGetSubVector - Gets a vector representing part of another vector
1312: Collective on X and IS
1314: Input Arguments:
1315: + X - vector from which to extract a subvector
1316: - is - index set representing portion of X to extract
1318: Output Arguments:
1319: . Y - subvector corresponding to is
1321: Level: advanced
1323: Notes:
1324: The subvector Y should be returned with VecRestoreSubVector().
1325: X and is must be defined on the same communicator
1327: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1328: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1329: 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.
1331: .seealso: MatCreateSubMatrix()
1332: @*/
1333: PetscErrorCode VecGetSubVector(Vec X,IS is,Vec *Y)
1334: {
1335: PetscErrorCode ierr;
1336: Vec Z;
1343: if (X->ops->getsubvector) {
1344: (*X->ops->getsubvector)(X,is,&Z);
1345: } else { /* Default implementation currently does no caching */
1346: PetscInt gstart,gend,start;
1347: PetscBool red[2] = { PETSC_TRUE, PETSC_TRUE };
1348: PetscInt n,N,ibs,vbs,bs = -1;
1350: ISGetLocalSize(is,&n);
1351: ISGetSize(is,&N);
1352: ISGetBlockSize(is,&ibs);
1353: VecGetBlockSize(X,&vbs);
1354: VecGetOwnershipRange(X,&gstart,&gend);
1355: ISContiguousLocal(is,gstart,gend,&start,&red[0]);
1356: /* block size is given by IS if ibs > 1; otherwise, check the vector */
1357: if (ibs > 1) {
1358: MPIU_Allreduce(MPI_IN_PLACE,red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1359: bs = ibs;
1360: } else {
1361: if (n%vbs || vbs == 1) red[1] = PETSC_FALSE; /* this process invalidate the collectiveness of block size */
1362: MPIU_Allreduce(MPI_IN_PLACE,red,2,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1363: if (red[0] && red[1]) bs = vbs; /* all processes have a valid block size and the access will be contiguous */
1364: }
1365: if (red[0]) { /* We can do a no-copy implementation */
1366: const PetscScalar *x;
1367: PetscInt state = 0;
1368: PetscBool isstd,iscuda,iship;
1370: PetscObjectTypeCompareAny((PetscObject)X,&isstd,VECSEQ,VECMPI,VECSTANDARD,"");
1371: PetscObjectTypeCompareAny((PetscObject)X,&iscuda,VECSEQCUDA,VECMPICUDA,"");
1372: PetscObjectTypeCompareAny((PetscObject)X,&iship,VECSEQHIP,VECMPIHIP,"");
1373: if (iscuda) {
1374: #if defined(PETSC_HAVE_CUDA)
1375: const PetscScalar *x_d;
1376: PetscMPIInt size;
1377: PetscOffloadMask flg;
1379: VecCUDAGetArrays_Private(X,&x,&x_d,&flg);
1380: if (flg == PETSC_OFFLOAD_UNALLOCATED) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for PETSC_OFFLOAD_UNALLOCATED");
1381: if (n && !x && !x_d) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Missing vector data");
1382: if (x) x += start;
1383: if (x_d) x_d += start;
1384: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1385: if (size == 1) {
1386: VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)X),bs,n,x,x_d,&Z);
1387: } else {
1388: VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)X),bs,n,N,x,x_d,&Z);
1389: }
1390: Z->offloadmask = flg;
1391: #endif
1392: } else if (iship) {
1393: #if defined(PETSC_HAVE_HIP)
1394: const PetscScalar *x_d;
1395: PetscMPIInt size;
1396: PetscOffloadMask flg;
1398: VecHIPGetArrays_Private(X,&x,&x_d,&flg);
1399: if (flg == PETSC_OFFLOAD_UNALLOCATED) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not for PETSC_OFFLOAD_UNALLOCATED");
1400: if (n && !x && !x_d) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Missing vector data");
1401: if (x) x += start;
1402: if (x_d) x_d += start;
1403: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1404: if (size == 1) {
1405: VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)X),bs,n,x,x_d,&Z);
1406: } else {
1407: VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)X),bs,n,N,x,x_d,&Z);
1408: }
1409: Z->offloadmask = flg;
1410: #endif
1411: } else if (isstd) {
1412: PetscMPIInt size;
1414: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1415: VecGetArrayRead(X,&x);
1416: if (x) x += start;
1417: if (size == 1) {
1418: VecCreateSeqWithArray(PetscObjectComm((PetscObject)X),bs,n,x,&Z);
1419: } else {
1420: VecCreateMPIWithArray(PetscObjectComm((PetscObject)X),bs,n,N,x,&Z);
1421: }
1422: VecRestoreArrayRead(X,&x);
1423: } else { /* default implementation: use place array */
1424: VecGetArrayRead(X,&x);
1425: VecCreate(PetscObjectComm((PetscObject)X),&Z);
1426: VecSetType(Z,((PetscObject)X)->type_name);
1427: VecSetSizes(Z,n,N);
1428: VecSetBlockSize(Z,bs);
1429: VecPlaceArray(Z,x ? x+start : NULL);
1430: VecRestoreArrayRead(X,&x);
1431: }
1433: /* this is relevant only in debug mode */
1434: VecLockGet(X,&state);
1435: if (state) {
1436: VecLockReadPush(Z);
1437: }
1438: Z->ops->placearray = NULL;
1439: Z->ops->replacearray = NULL;
1440: } else { /* Have to create a scatter and do a copy */
1441: VecScatter scatter;
1443: VecCreate(PetscObjectComm((PetscObject)is),&Z);
1444: VecSetSizes(Z,n,N);
1445: VecSetBlockSize(Z,bs);
1446: VecSetType(Z,((PetscObject)X)->type_name);
1447: VecScatterCreate(X,is,Z,NULL,&scatter);
1448: VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1449: VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1450: PetscObjectCompose((PetscObject)Z,"VecGetSubVector_Scatter",(PetscObject)scatter);
1451: VecScatterDestroy(&scatter);
1452: }
1453: }
1454: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1455: if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
1456: PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);
1457: *Y = Z;
1458: return(0);
1459: }
1461: /*@
1462: VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1464: Collective on IS
1466: Input Arguments:
1467: + X - vector from which subvector was obtained
1468: . is - index set representing the subset of X
1469: - Y - subvector being restored
1471: Level: advanced
1473: .seealso: VecGetSubVector()
1474: @*/
1475: PetscErrorCode VecRestoreSubVector(Vec X,IS is,Vec *Y)
1476: {
1485: if (X->ops->restoresubvector) {
1486: (*X->ops->restoresubvector)(X,is,Y);
1487: } else {
1488: PETSC_UNUSED PetscObjectState dummystate = 0;
1489: PetscBool valid;
1491: PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,valid);
1492: if (!valid) {
1493: VecScatter scatter;
1494: PetscInt state;
1496: VecLockGet(X,&state);
1497: if (state != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vec X is locked for read-only or read/write access");
1499: PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);
1500: if (scatter) {
1501: VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1502: VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1503: } else {
1504: PetscBool iscuda,iship;
1505: PetscObjectTypeCompareAny((PetscObject)X,&iscuda,VECSEQCUDA,VECMPICUDA,"");
1506: PetscObjectTypeCompareAny((PetscObject)X,&iship,VECSEQHIP,VECMPIHIP,"");
1508: if (iscuda) {
1509: #if defined(PETSC_HAVE_CUDA)
1510: PetscOffloadMask ymask = (*Y)->offloadmask;
1512: /* The offloadmask of X dictates where to move memory
1513: If X GPU data is valid, then move Y data on GPU if needed
1514: Otherwise, move back to the CPU */
1515: switch (X->offloadmask) {
1516: case PETSC_OFFLOAD_BOTH:
1517: if (ymask == PETSC_OFFLOAD_CPU) {
1518: VecCUDAResetArray(*Y);
1519: } else if (ymask == PETSC_OFFLOAD_GPU) {
1520: X->offloadmask = PETSC_OFFLOAD_GPU;
1521: }
1522: break;
1523: case PETSC_OFFLOAD_GPU:
1524: if (ymask == PETSC_OFFLOAD_CPU) {
1525: VecCUDAResetArray(*Y);
1526: }
1527: break;
1528: case PETSC_OFFLOAD_CPU:
1529: if (ymask == PETSC_OFFLOAD_GPU) {
1530: VecResetArray(*Y);
1531: }
1532: break;
1533: case PETSC_OFFLOAD_UNALLOCATED:
1534: case PETSC_OFFLOAD_VECKOKKOS:
1535: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen");
1536: break;
1537: }
1538: #endif
1539: } else if (iship) {
1540: #if defined(PETSC_HAVE_HIP)
1541: PetscOffloadMask ymask = (*Y)->offloadmask;
1543: /* The offloadmask of X dictates where to move memory
1544: If X GPU data is valid, then move Y data on GPU if needed
1545: Otherwise, move back to the CPU */
1546: switch (X->offloadmask) {
1547: case PETSC_OFFLOAD_BOTH:
1548: if (ymask == PETSC_OFFLOAD_CPU) {
1549: VecHIPResetArray(*Y);
1550: } else if (ymask == PETSC_OFFLOAD_GPU) {
1551: X->offloadmask = PETSC_OFFLOAD_GPU;
1552: }
1553: break;
1554: case PETSC_OFFLOAD_GPU:
1555: if (ymask == PETSC_OFFLOAD_CPU) {
1556: VecHIPResetArray(*Y);
1557: }
1558: break;
1559: case PETSC_OFFLOAD_CPU:
1560: if (ymask == PETSC_OFFLOAD_GPU) {
1561: VecResetArray(*Y);
1562: }
1563: break;
1564: case PETSC_OFFLOAD_UNALLOCATED:
1565: case PETSC_OFFLOAD_VECKOKKOS:
1566: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen");
1567: break;
1568: }
1569: #endif
1570: } else {
1571: /* If OpenCL vecs updated the device memory, this triggers a copy on the CPU */
1572: VecResetArray(*Y);
1573: }
1574: PetscObjectStateIncrease((PetscObject)X);
1575: }
1576: }
1577: VecDestroy(Y);
1578: }
1579: return(0);
1580: }
1582: /*@
1583: VecGetLocalVectorRead - Maps the local portion of a vector into a
1584: vector. You must call VecRestoreLocalVectorRead() when the local
1585: vector is no longer needed.
1587: Not collective.
1589: Input parameter:
1590: . v - The vector for which the local vector is desired.
1592: Output parameter:
1593: . w - Upon exit this contains the local vector.
1595: Level: beginner
1597: Notes:
1598: This function is similar to VecGetArrayRead() which maps the local
1599: portion into a raw pointer. VecGetLocalVectorRead() is usually
1600: almost as efficient as VecGetArrayRead() but in certain circumstances
1601: VecGetLocalVectorRead() can be much more efficient than
1602: VecGetArrayRead(). This is because the construction of a contiguous
1603: array representing the vector data required by VecGetArrayRead() can
1604: be an expensive operation for certain vector types. For example, for
1605: GPU vectors VecGetArrayRead() requires that the data between device
1606: and host is synchronized.
1608: Unlike VecGetLocalVector(), this routine is not collective and
1609: preserves cached information.
1611: .seealso: VecRestoreLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1612: @*/
1613: PetscErrorCode VecGetLocalVectorRead(Vec v,Vec w)
1614: {
1616: PetscScalar *a;
1621: VecCheckSameLocalSize(v,1,w,2);
1622: if (v->ops->getlocalvectorread) {
1623: (*v->ops->getlocalvectorread)(v,w);
1624: } else {
1625: VecGetArrayRead(v,(const PetscScalar**)&a);
1626: VecPlaceArray(w,a);
1627: }
1628: PetscObjectStateIncrease((PetscObject)w);
1629: VecLockReadPush(v);
1630: VecLockReadPush(w);
1631: return(0);
1632: }
1634: /*@
1635: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1636: previously mapped into a vector using VecGetLocalVectorRead().
1638: Not collective.
1640: Input parameter:
1641: + v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
1642: - w - The vector into which the local portion of v was mapped.
1644: Level: beginner
1646: .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1647: @*/
1648: PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
1649: {
1651: PetscScalar *a;
1656: if (v->ops->restorelocalvectorread) {
1657: (*v->ops->restorelocalvectorread)(v,w);
1658: } else {
1659: VecGetArrayRead(w,(const PetscScalar**)&a);
1660: VecRestoreArrayRead(v,(const PetscScalar**)&a);
1661: VecResetArray(w);
1662: }
1663: VecLockReadPop(v);
1664: VecLockReadPop(w);
1665: PetscObjectStateIncrease((PetscObject)w);
1666: return(0);
1667: }
1669: /*@
1670: VecGetLocalVector - Maps the local portion of a vector into a
1671: vector.
1673: Collective on v, not collective on w.
1675: Input parameter:
1676: . v - The vector for which the local vector is desired.
1678: Output parameter:
1679: . w - Upon exit this contains the local vector.
1681: Level: beginner
1683: Notes:
1684: This function is similar to VecGetArray() which maps the local
1685: portion into a raw pointer. VecGetLocalVector() is usually about as
1686: efficient as VecGetArray() but in certain circumstances
1687: VecGetLocalVector() can be much more efficient than VecGetArray().
1688: This is because the construction of a contiguous array representing
1689: the vector data required by VecGetArray() can be an expensive
1690: operation for certain vector types. For example, for GPU vectors
1691: VecGetArray() requires that the data between device and host is
1692: synchronized.
1694: .seealso: VecRestoreLocalVector(), VecGetLocalVectorRead(), VecGetArrayRead(), VecGetArray()
1695: @*/
1696: PetscErrorCode VecGetLocalVector(Vec v,Vec w)
1697: {
1699: PetscScalar *a;
1704: VecCheckSameLocalSize(v,1,w,2);
1705: if (v->ops->getlocalvector) {
1706: (*v->ops->getlocalvector)(v,w);
1707: } else {
1708: VecGetArray(v,&a);
1709: VecPlaceArray(w,a);
1710: }
1711: PetscObjectStateIncrease((PetscObject)w);
1712: return(0);
1713: }
1715: /*@
1716: VecRestoreLocalVector - Unmaps the local portion of a vector
1717: previously mapped into a vector using VecGetLocalVector().
1719: Logically collective.
1721: Input parameter:
1722: + v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
1723: - w - The vector into which the local portion of v was mapped.
1725: Level: beginner
1727: .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
1728: @*/
1729: PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
1730: {
1732: PetscScalar *a;
1737: if (v->ops->restorelocalvector) {
1738: (*v->ops->restorelocalvector)(v,w);
1739: } else {
1740: VecGetArray(w,&a);
1741: VecRestoreArray(v,&a);
1742: VecResetArray(w);
1743: }
1744: PetscObjectStateIncrease((PetscObject)w);
1745: PetscObjectStateIncrease((PetscObject)v);
1746: return(0);
1747: }
1749: /*@C
1750: VecGetArray - Returns a pointer to a contiguous array that contains this
1751: processor's portion of the vector data. For the standard PETSc
1752: vectors, VecGetArray() returns a pointer to the local data array and
1753: does not use any copies. If the underlying vector data is not stored
1754: in a contiguous array this routine will copy the data to a contiguous
1755: array and return a pointer to that. You MUST call VecRestoreArray()
1756: when you no longer need access to the array.
1758: Logically Collective on Vec
1760: Input Parameter:
1761: . x - the vector
1763: Output Parameter:
1764: . a - location to put pointer to the array
1766: Fortran Note:
1767: This routine is used differently from Fortran 77
1768: $ Vec x
1769: $ PetscScalar x_array(1)
1770: $ PetscOffset i_x
1771: $ PetscErrorCode ierr
1772: $ call VecGetArray(x,x_array,i_x,ierr)
1773: $
1774: $ Access first local entry in vector with
1775: $ value = x_array(i_x + 1)
1776: $
1777: $ ...... other code
1778: $ call VecRestoreArray(x,x_array,i_x,ierr)
1779: For Fortran 90 see VecGetArrayF90()
1781: See the Fortran chapter of the users manual and
1782: petsc/src/snes/tutorials/ex5f.F for details.
1784: Level: beginner
1786: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1787: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1788: @*/
1789: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1790: {
1795: VecSetErrorIfLocked(x,1);
1796: if (x->ops->getarray) { /* The if-else order matters! VECNEST, VECCUDA etc should have ops->getarray while VECCUDA etc are petscnative */
1797: (*x->ops->getarray)(x,a);
1798: } else if (x->petscnative) { /* VECSTANDARD */
1799: *a = *((PetscScalar**)x->data);
1800: } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
1801: return(0);
1802: }
1804: /*@C
1805: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1807: Logically Collective on Vec
1809: Input Parameters:
1810: + x - the vector
1811: - a - location of pointer to array obtained from VecGetArray()
1813: Level: beginner
1815: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1816: VecGetArrayPair(), VecRestoreArrayPair()
1817: @*/
1818: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
1819: {
1824: if (x->ops->restorearray) { /* VECNEST, VECCUDA etc */
1825: (*x->ops->restorearray)(x,a);
1826: } else if (x->petscnative) { /* VECSTANDARD */
1827: /* nothing */
1828: } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot restore array for vector type \"%s\"",((PetscObject)x)->type_name);
1829: if (a) *a = NULL;
1830: PetscObjectStateIncrease((PetscObject)x);
1831: return(0);
1832: }
1833: /*@C
1834: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1836: Not Collective
1838: Input Parameter:
1839: . x - the vector
1841: Output Parameter:
1842: . a - the array
1844: Level: beginner
1846: Notes:
1847: The array must be returned using a matching call to VecRestoreArrayRead().
1849: Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1851: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1852: implementations may require a copy, but must such implementations should cache the contiguous representation so that
1853: only one copy is performed when this routine is called multiple times in sequence.
1855: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1856: @*/
1857: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1858: {
1863: if (x->ops->getarray) { /* VECNEST, VECCUDA, VECKOKKOS etc */
1864: (*x->ops->getarray)(x,(PetscScalar**)a);
1865: } else if (x->petscnative) { /* VECSTANDARD */
1866: *a = *((PetscScalar**)x->data);
1867: } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array read for vector type \"%s\"",((PetscObject)x)->type_name);
1868: return(0);
1869: }
1871: /*@C
1872: VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
1874: Not Collective
1876: Input Parameters:
1877: + vec - the vector
1878: - array - the array
1880: Level: beginner
1882: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1883: @*/
1884: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
1885: {
1890: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS etc */
1891: /* nothing */
1892: } else if (x->ops->restorearrayread) { /* VECNEST */
1893: (*x->ops->restorearrayread)(x,a);
1894: } else { /* No one? */
1895: (*x->ops->restorearray)(x,(PetscScalar**)a);
1896: }
1897: if (a) *a = NULL;
1898: return(0);
1899: }
1901: /*@C
1902: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contains this
1903: processor's portion of the vector data. The values in this array are NOT valid, the routine calling this
1904: routine is responsible for putting values into the array; any values it does not set will be invalid
1906: Logically Collective on Vec
1908: Input Parameter:
1909: . x - the vector
1911: Output Parameter:
1912: . a - location to put pointer to the array
1914: Level: intermediate
1916: This is for vectors associate with GPUs, the vector is not copied up before giving access. If you need correct
1917: values in the array use VecGetArray()
1919: Concepts: vector^accessing local values
1921: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1922: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArray(), VecRestoreArrayWrite()
1923: @*/
1924: PetscErrorCode VecGetArrayWrite(Vec x,PetscScalar **a)
1925: {
1930: VecSetErrorIfLocked(x,1);
1931: if (x->ops->getarraywrite) {
1932: (*x->ops->getarraywrite)(x,a);
1933: } else {
1934: VecGetArray(x,a);
1935: }
1936: return(0);
1937: }
1939: /*@C
1940: VecRestoreArrayWrite - Restores a vector after VecGetArrayWrite() has been called.
1942: Logically Collective on Vec
1944: Input Parameters:
1945: + x - the vector
1946: - a - location of pointer to array obtained from VecGetArray()
1948: Level: beginner
1950: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1951: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite()
1952: @*/
1953: PetscErrorCode VecRestoreArrayWrite(Vec x,PetscScalar **a)
1954: {
1959: if (x->ops->restorearraywrite) {
1960: (*x->ops->restorearraywrite)(x,a);
1961: } else if (x->ops->restorearray) {
1962: (*x->ops->restorearray)(x,a);
1963: }
1964: if (a) *a = NULL;
1965: PetscObjectStateIncrease((PetscObject)x);
1966: return(0);
1967: }
1969: /*@C
1970: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1971: that were created by a call to VecDuplicateVecs(). You MUST call
1972: VecRestoreArrays() when you no longer need access to the array.
1974: Logically Collective on Vec
1976: Input Parameters:
1977: + x - the vectors
1978: - n - the number of vectors
1980: Output Parameter:
1981: . a - location to put pointer to the array
1983: Fortran Note:
1984: This routine is not supported in Fortran.
1986: Level: intermediate
1988: .seealso: VecGetArray(), VecRestoreArrays()
1989: @*/
1990: PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1991: {
1993: PetscInt i;
1994: PetscScalar **q;
2000: if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
2001: PetscMalloc1(n,&q);
2002: for (i=0; i<n; ++i) {
2003: VecGetArray(x[i],&q[i]);
2004: }
2005: *a = q;
2006: return(0);
2007: }
2009: /*@C
2010: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
2011: has been called.
2013: Logically Collective on Vec
2015: Input Parameters:
2016: + x - the vector
2017: . n - the number of vectors
2018: - a - location of pointer to arrays obtained from VecGetArrays()
2020: Notes:
2021: For regular PETSc vectors this routine does not involve any copies. For
2022: any special vectors that do not store local vector data in a contiguous
2023: array, this routine will copy the data back into the underlying
2024: vector data structure from the arrays obtained with VecGetArrays().
2026: Fortran Note:
2027: This routine is not supported in Fortran.
2029: Level: intermediate
2031: .seealso: VecGetArrays(), VecRestoreArray()
2032: @*/
2033: PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
2034: {
2036: PetscInt i;
2037: PetscScalar **q = *a;
2044: for (i=0; i<n; ++i) {
2045: VecRestoreArray(x[i],&q[i]);
2046: }
2047: PetscFree(q);
2048: return(0);
2049: }
2051: /*@C
2052: VecGetArrayAndMemType - Like VecGetArray(), but if this is a GPU vector and it is currently offloaded to GPU,
2053: the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
2054: vector data. Otherwise, it functions as VecGetArray().
2056: Logically Collective on Vec
2058: Input Parameter:
2059: . x - the vector
2061: Output Parameters:
2062: + a - location to put pointer to the array
2063: - mtype - memory type of the array
2065: Level: beginner
2067: .seealso: VecRestoreArrayAndMemType(), VecRestoreArrayAndMemType(), VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(),
2068: VecPlaceArray(), VecGetArray2d(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
2069: @*/
2070: PetscErrorCode VecGetArrayAndMemType(Vec x,PetscScalar **a,PetscMemType *mtype)
2071: {
2077: VecSetErrorIfLocked(x,1);
2078: if (x->ops->getarrayandmemtype) { /* VECCUDA, VECKOKKOS etc */
2079: (*x->ops->getarrayandmemtype)(x,a,mtype);
2080: } else { /* VECSTANDARD, VECNEST, VECVIENNACL */
2081: VecGetArray(x,a);
2082: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2083: }
2084: return(0);
2085: }
2087: /*@C
2088: VecRestoreArrayAndMemType - Restores a vector after VecGetArrayAndMemType() has been called.
2090: Logically Collective on Vec
2092: Input Parameters:
2093: + x - the vector
2094: - a - location of pointer to array obtained from VecGetArrayAndMemType()
2096: Level: beginner
2098: .seealso: VecGetArrayAndMemType(), VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(),
2099: VecPlaceArray(), VecRestoreArray2d(), VecGetArrayPair(), VecRestoreArrayPair()
2100: @*/
2101: PetscErrorCode VecRestoreArrayAndMemType(Vec x,PetscScalar **a)
2102: {
2108: if (x->ops->restorearrayandmemtype) { /* VECCUDA, VECKOKKOS etc */
2109: (*x->ops->restorearrayandmemtype)(x,a);
2110: } else if (x->ops->restorearray) { /* VECNEST, VECVIENNACL */
2111: (*x->ops->restorearray)(x,a);
2112: } /* VECSTANDARD does nothing */
2113: if (a) *a = NULL;
2114: PetscObjectStateIncrease((PetscObject)x);
2115: return(0);
2116: }
2118: /*@C
2119: VecGetArrayReadAndMemType - Like VecGetArrayRead(), but if this is a CUDA vector and it is currently offloaded to GPU,
2120: the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
2121: vector data. Otherwise, it functions as VecGetArrayRead().
2123: Not Collective
2125: Input Parameter:
2126: . x - the vector
2128: Output Parameters:
2129: + a - the array
2130: - mtype - memory type of the array
2132: Level: beginner
2134: Notes:
2135: The array must be returned using a matching call to VecRestoreArrayReadAndMemType().
2138: .seealso: VecRestoreArrayReadAndMemType(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayAndMemType()
2139: @*/
2140: PetscErrorCode VecGetArrayReadAndMemType(Vec x,const PetscScalar **a,PetscMemType *mtype)
2141: {
2147: #if defined(PETSC_USE_DEBUG)
2148: if (x->ops->getarrayreadandmemtype) SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Not expected vector type \"%s\" has ops->getarrayreadandmemtype",((PetscObject)x)->type_name);
2149: #endif
2151: if (x->ops->getarrayandmemtype) { /* VECCUDA, VECKOKKOS etc, though they are also petscnative */
2152: (*x->ops->getarrayandmemtype)(x,(PetscScalar**)a,mtype);
2153: } else if (x->ops->getarray) { /* VECNEST, VECVIENNACL */
2154: (*x->ops->getarray)(x,(PetscScalar**)a);
2155: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2156: } else if (x->petscnative) { /* VECSTANDARD */
2157: *a = *((PetscScalar**)x->data);
2158: if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2159: } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array read in place for vector type \"%s\"",((PetscObject)x)->type_name);
2160: return(0);
2161: }
2163: /*@C
2164: VecRestoreArrayReadAndMemType - Restore array obtained with VecGetArrayReadAndMemType()
2166: Not Collective
2168: Input Parameters:
2169: + vec - the vector
2170: - array - the array
2172: Level: beginner
2174: .seealso: VecGetArrayReadAndMemType(), VecRestoreArrayAndMemType(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
2175: @*/
2176: PetscErrorCode VecRestoreArrayReadAndMemType(Vec x,const PetscScalar **a)
2177: {
2183: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS, VECVIENNACL etc */
2184: /* nothing */
2185: } else if (x->ops->restorearrayread) { /* VECNEST */
2186: (*x->ops->restorearrayread)(x,a);
2187: } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot restore array read in place for vector type \"%s\"",((PetscObject)x)->type_name);
2188: if (a) *a = NULL;
2189: return(0);
2190: }
2192: /*@
2193: VecPlaceArray - Allows one to replace the array in a vector with an
2194: array provided by the user. This is useful to avoid copying an array
2195: into a vector.
2197: Not Collective
2199: Input Parameters:
2200: + vec - the vector
2201: - array - the array
2203: Notes:
2204: You can return to the original array with a call to VecResetArray()
2206: Level: developer
2208: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
2210: @*/
2211: PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
2212: {
2219: if (vec->ops->placearray) {
2220: (*vec->ops->placearray)(vec,array);
2221: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
2222: PetscObjectStateIncrease((PetscObject)vec);
2223: return(0);
2224: }
2226: /*@C
2227: VecReplaceArray - Allows one to replace the array in a vector with an
2228: array provided by the user. This is useful to avoid copying an array
2229: into a vector.
2231: Not Collective
2233: Input Parameters:
2234: + vec - the vector
2235: - array - the array
2237: Notes:
2238: This permanently replaces the array and frees the memory associated
2239: with the old array.
2241: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
2242: freed by the user. It will be freed when the vector is destroyed.
2244: Not supported from Fortran
2246: Level: developer
2248: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
2250: @*/
2251: PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
2252: {
2258: if (vec->ops->replacearray) {
2259: (*vec->ops->replacearray)(vec,array);
2260: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
2261: PetscObjectStateIncrease((PetscObject)vec);
2262: return(0);
2263: }
2266: /*@C
2267: VecCUDAGetArray - Provides access to the CUDA buffer inside a vector.
2269: This function has semantics similar to VecGetArray(): the pointer
2270: returned by this function points to a consistent view of the vector
2271: data. This may involve a copy operation of data from the host to the
2272: device if the data on the device is out of date. If the device
2273: memory hasn't been allocated previously it will be allocated as part
2274: of this function call. VecCUDAGetArray() assumes that
2275: the user will modify the vector data. This is similar to
2276: intent(inout) in fortran.
2278: The CUDA device pointer has to be released by calling
2279: VecCUDARestoreArray(). Upon restoring the vector data
2280: the data on the host will be marked as out of date. A subsequent
2281: access of the host data will thus incur a data transfer from the
2282: device to the host.
2285: Input Parameter:
2286: . v - the vector
2288: Output Parameter:
2289: . a - the CUDA device pointer
2291: Fortran note:
2292: This function is not currently available from Fortran.
2294: Level: intermediate
2296: .seealso: VecCUDARestoreArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2297: @*/
2298: PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
2299: {
2302: #if defined(PETSC_HAVE_CUDA)
2303: {
2305: VecCUDACopyToGPU(v);
2306: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2307: }
2308: #endif
2309: return(0);
2310: }
2312: /*@C
2313: VecCUDARestoreArray - Restore a CUDA device pointer previously acquired with VecCUDAGetArray().
2315: This marks the host data as out of date. Subsequent access to the
2316: vector data on the host side with for instance VecGetArray() incurs a
2317: data transfer.
2319: Input Parameter:
2320: + v - the vector
2321: - a - the CUDA device pointer. This pointer is invalid after
2322: VecCUDARestoreArray() returns.
2324: Fortran note:
2325: This function is not currently available from Fortran.
2327: Level: intermediate
2329: .seealso: VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2330: @*/
2331: PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
2332: {
2337: #if defined(PETSC_HAVE_CUDA)
2338: v->offloadmask = PETSC_OFFLOAD_GPU;
2339: #endif
2340: PetscObjectStateIncrease((PetscObject)v);
2341: return(0);
2342: }
2344: /*@C
2345: VecCUDAGetArrayRead - Provides read access to the CUDA buffer inside a vector.
2347: This function is analogous to VecGetArrayRead(): The pointer
2348: returned by this function points to a consistent view of the vector
2349: data. This may involve a copy operation of data from the host to the
2350: device if the data on the device is out of date. If the device
2351: memory hasn't been allocated previously it will be allocated as part
2352: of this function call. VecCUDAGetArrayRead() assumes that the
2353: user will not modify the vector data. This is analgogous to
2354: intent(in) in Fortran.
2356: The CUDA device pointer has to be released by calling
2357: VecCUDARestoreArrayRead(). If the data on the host side was
2358: previously up to date it will remain so, i.e. data on both the device
2359: and the host is up to date. Accessing data on the host side does not
2360: incur a device to host data transfer.
2362: Input Parameter:
2363: . v - the vector
2365: Output Parameter:
2366: . a - the CUDA pointer.
2368: Fortran note:
2369: This function is not currently available from Fortran.
2371: Level: intermediate
2373: .seealso: VecCUDARestoreArrayRead(), VecCUDAGetArray(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2374: @*/
2375: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v,const PetscScalar** a)
2376: {
2379: VecCUDAGetArray(v,(PetscScalar**)a);
2380: return(0);
2381: }
2383: /*@C
2384: VecCUDARestoreArrayRead - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayRead().
2386: If the data on the host side was previously up to date it will remain
2387: so, i.e. data on both the device and the host is up to date.
2388: Accessing data on the host side e.g. with VecGetArray() does not
2389: incur a device to host data transfer.
2391: Input Parameter:
2392: + v - the vector
2393: - a - the CUDA device pointer. This pointer is invalid after
2394: VecCUDARestoreArrayRead() returns.
2396: Fortran note:
2397: This function is not currently available from Fortran.
2399: Level: intermediate
2401: .seealso: VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2402: @*/
2403: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
2404: {
2407: *a = NULL;
2408: return(0);
2409: }
2411: /*@C
2412: VecCUDAGetArrayWrite - Provides write access to the CUDA buffer inside a vector.
2414: The data pointed to by the device pointer is uninitialized. The user
2415: may not read from this data. Furthermore, the entire array needs to
2416: be filled by the user to obtain well-defined behaviour. The device
2417: memory will be allocated by this function if it hasn't been allocated
2418: previously. This is analogous to intent(out) in Fortran.
2420: The device pointer needs to be released with
2421: VecCUDARestoreArrayWrite(). When the pointer is released the
2422: host data of the vector is marked as out of data. Subsequent access
2423: of the host data with e.g. VecGetArray() incurs a device to host data
2424: transfer.
2427: Input Parameter:
2428: . v - the vector
2430: Output Parameter:
2431: . a - the CUDA pointer
2433: Fortran note:
2434: This function is not currently available from Fortran.
2436: Level: advanced
2438: .seealso: VecCUDARestoreArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2439: @*/
2440: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
2441: {
2444: #if defined(PETSC_HAVE_CUDA)
2445: {
2447: VecCUDAAllocateCheck(v);
2448: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2449: }
2450: #endif
2451: return(0);
2452: }
2454: /*@C
2455: VecCUDARestoreArrayWrite - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayWrite().
2457: Data on the host will be marked as out of date. Subsequent access of
2458: the data on the host side e.g. with VecGetArray() will incur a device
2459: to host data transfer.
2461: Input Parameter:
2462: + v - the vector
2463: - a - the CUDA device pointer. This pointer is invalid after
2464: VecCUDARestoreArrayWrite() returns.
2466: Fortran note:
2467: This function is not currently available from Fortran.
2469: Level: intermediate
2471: .seealso: VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2472: @*/
2473: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
2474: {
2479: #if defined(PETSC_HAVE_CUDA)
2480: v->offloadmask = PETSC_OFFLOAD_GPU;
2481: a = NULL;
2482: #endif
2483: PetscObjectStateIncrease((PetscObject)v);
2484: return(0);
2485: }
2487: /*@C
2488: VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
2489: GPU array provided by the user. This is useful to avoid copying an
2490: array into a vector.
2492: Not Collective
2494: Input Parameters:
2495: + vec - the vector
2496: - array - the GPU array
2498: Notes:
2499: You can return to the original GPU array with a call to VecCUDAResetArray()
2500: It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
2501: same time on the same vector.
2503: Level: developer
2505: .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAReplaceArray()
2507: @*/
2508: PetscErrorCode VecCUDAPlaceArray(Vec vin,const PetscScalar a[])
2509: {
2514: #if defined(PETSC_HAVE_CUDA)
2515: VecCUDACopyToGPU(vin);
2516: if (((Vec_Seq*)vin->data)->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"VecCUDAPlaceArray()/VecPlaceArray() was already called on this vector, without a call to VecCUDAResetArray()/VecResetArray()");
2517: ((Vec_Seq*)vin->data)->unplacedarray = (PetscScalar *) ((Vec_CUDA*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2518: ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar*)a;
2519: vin->offloadmask = PETSC_OFFLOAD_GPU;
2520: #endif
2521: PetscObjectStateIncrease((PetscObject)vin);
2522: return(0);
2523: }
2525: /*@C
2526: VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
2527: with a GPU array provided by the user. This is useful to avoid copying
2528: a GPU array into a vector.
2530: Not Collective
2532: Input Parameters:
2533: + vec - the vector
2534: - array - the GPU array
2536: Notes:
2537: This permanently replaces the GPU array and frees the memory associated
2538: with the old GPU array.
2540: The memory passed in CANNOT be freed by the user. It will be freed
2541: when the vector is destroyed.
2543: Not supported from Fortran
2545: Level: developer
2547: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAPlaceArray(), VecReplaceArray()
2549: @*/
2550: PetscErrorCode VecCUDAReplaceArray(Vec vin,const PetscScalar a[])
2551: {
2552: #if defined(PETSC_HAVE_CUDA)
2553: cudaError_t err;
2554: #endif
2559: #if defined(PETSC_HAVE_CUDA)
2560: if (((Vec_CUDA*)vin->spptr)->GPUarray_allocated) {
2561: err = cudaFree(((Vec_CUDA*)vin->spptr)->GPUarray_allocated);CHKERRCUDA(err);
2562: }
2563: ((Vec_CUDA*)vin->spptr)->GPUarray_allocated = ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar*)a;
2564: vin->offloadmask = PETSC_OFFLOAD_GPU;
2565: #endif
2566: PetscObjectStateIncrease((PetscObject)vin);
2567: return(0);
2568: }
2570: /*@C
2571: VecCUDAResetArray - Resets a vector to use its default memory. Call this
2572: after the use of VecCUDAPlaceArray().
2574: Not Collective
2576: Input Parameters:
2577: . vec - the vector
2579: Level: developer
2581: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecCUDAPlaceArray(), VecCUDAReplaceArray()
2583: @*/
2584: PetscErrorCode VecCUDAResetArray(Vec vin)
2585: {
2590: #if defined(PETSC_HAVE_CUDA)
2591: VecCUDACopyToGPU(vin);
2592: ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2593: ((Vec_Seq*)vin->data)->unplacedarray = 0;
2594: vin->offloadmask = PETSC_OFFLOAD_GPU;
2595: #endif
2596: PetscObjectStateIncrease((PetscObject)vin);
2597: return(0);
2598: }
2600: /*@C
2601: VecHIPGetArray - Provides access to the HIP buffer inside a vector.
2603: This function has semantics similar to VecGetArray(): the pointer
2604: returned by this function points to a consistent view of the vector
2605: data. This may involve a copy operation of data from the host to the
2606: device if the data on the device is out of date. If the device
2607: memory hasn't been allocated previously it will be allocated as part
2608: of this function call. VecHIPGetArray() assumes that
2609: the user will modify the vector data. This is similar to
2610: intent(inout) in fortran.
2612: The HIP device pointer has to be released by calling
2613: VecHIPRestoreArray(). Upon restoring the vector data
2614: the data on the host will be marked as out of date. A subsequent
2615: access of the host data will thus incur a data transfer from the
2616: device to the host.
2619: Input Parameter:
2620: . v - the vector
2622: Output Parameter:
2623: . a - the HIP device pointer
2625: Fortran note:
2626: This function is not currently available from Fortran.
2628: Level: intermediate
2630: .seealso: VecHIPRestoreArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2631: @*/
2632: PETSC_EXTERN PetscErrorCode VecHIPGetArray(Vec v, PetscScalar **a)
2633: {
2634: #if defined(PETSC_HAVE_HIP)
2636: #endif
2640: #if defined(PETSC_HAVE_HIP)
2641: *a = 0;
2642: VecHIPCopyToGPU(v);
2643: *a = ((Vec_HIP*)v->spptr)->GPUarray;
2644: #endif
2645: return(0);
2646: }
2648: /*@C
2649: VecHIPRestoreArray - Restore a HIP device pointer previously acquired with VecHIPGetArray().
2651: This marks the host data as out of date. Subsequent access to the
2652: vector data on the host side with for instance VecGetArray() incurs a
2653: data transfer.
2655: Input Parameter:
2656: + v - the vector
2657: - a - the HIP device pointer. This pointer is invalid after
2658: VecHIPRestoreArray() returns.
2660: Fortran note:
2661: This function is not currently available from Fortran.
2663: Level: intermediate
2665: .seealso: VecHIPGetArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2666: @*/
2667: PETSC_EXTERN PetscErrorCode VecHIPRestoreArray(Vec v, PetscScalar **a)
2668: {
2673: #if defined(PETSC_HAVE_HIP)
2674: v->offloadmask = PETSC_OFFLOAD_GPU;
2675: #endif
2677: PetscObjectStateIncrease((PetscObject)v);
2678: return(0);
2679: }
2681: /*@C
2682: VecHIPGetArrayRead - Provides read access to the HIP buffer inside a vector.
2684: This function is analogous to VecGetArrayRead(): The pointer
2685: returned by this function points to a consistent view of the vector
2686: data. This may involve a copy operation of data from the host to the
2687: device if the data on the device is out of date. If the device
2688: memory hasn't been allocated previously it will be allocated as part
2689: of this function call. VecHIPGetArrayRead() assumes that the
2690: user will not modify the vector data. This is analgogous to
2691: intent(in) in Fortran.
2693: The HIP device pointer has to be released by calling
2694: VecHIPRestoreArrayRead(). If the data on the host side was
2695: previously up to date it will remain so, i.e. data on both the device
2696: and the host is up to date. Accessing data on the host side does not
2697: incur a device to host data transfer.
2699: Input Parameter:
2700: . v - the vector
2702: Output Parameter:
2703: . a - the HIP pointer.
2705: Fortran note:
2706: This function is not currently available from Fortran.
2708: Level: intermediate
2710: .seealso: VecHIPRestoreArrayRead(), VecHIPGetArray(), VecHIPGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2711: @*/
2712: PETSC_EXTERN PetscErrorCode VecHIPGetArrayRead(Vec v, const PetscScalar **a)
2713: {
2714: #if defined(PETSC_HAVE_HIP)
2716: #endif
2720: #if defined(PETSC_HAVE_HIP)
2721: *a = 0;
2722: VecHIPCopyToGPU(v);
2723: *a = ((Vec_HIP*)v->spptr)->GPUarray;
2724: #endif
2725: return(0);
2726: }
2728: /*@C
2729: VecHIPRestoreArrayRead - Restore a HIP device pointer previously acquired with VecHIPGetArrayRead().
2731: If the data on the host side was previously up to date it will remain
2732: so, i.e. data on both the device and the host is up to date.
2733: Accessing data on the host side e.g. with VecGetArray() does not
2734: incur a device to host data transfer.
2736: Input Parameter:
2737: + v - the vector
2738: - a - the HIP device pointer. This pointer is invalid after
2739: VecHIPRestoreArrayRead() returns.
2741: Fortran note:
2742: This function is not currently available from Fortran.
2744: Level: intermediate
2746: .seealso: VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecHIPGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2747: @*/
2748: PETSC_EXTERN PetscErrorCode VecHIPRestoreArrayRead(Vec v, const PetscScalar **a)
2749: {
2752: *a = NULL;
2753: return(0);
2754: }
2756: /*@C
2757: VecHIPGetArrayWrite - Provides write access to the HIP buffer inside a vector.
2759: The data pointed to by the device pointer is uninitialized. The user
2760: may not read from this data. Furthermore, the entire array needs to
2761: be filled by the user to obtain well-defined behaviour. The device
2762: memory will be allocated by this function if it hasn't been allocated
2763: previously. This is analogous to intent(out) in Fortran.
2765: The device pointer needs to be released with
2766: VecHIPRestoreArrayWrite(). When the pointer is released the
2767: host data of the vector is marked as out of data. Subsequent access
2768: of the host data with e.g. VecGetArray() incurs a device to host data
2769: transfer.
2772: Input Parameter:
2773: . v - the vector
2775: Output Parameter:
2776: . a - the HIP pointer
2778: Fortran note:
2779: This function is not currently available from Fortran.
2781: Level: advanced
2783: .seealso: VecHIPRestoreArrayWrite(), VecHIPGetArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2784: @*/
2785: PETSC_EXTERN PetscErrorCode VecHIPGetArrayWrite(Vec v, PetscScalar **a)
2786: {
2787: #if defined(PETSC_HAVE_HIP)
2789: #endif
2793: #if defined(PETSC_HAVE_HIP)
2794: *a = 0;
2795: VecHIPAllocateCheck(v);
2796: *a = ((Vec_HIP*)v->spptr)->GPUarray;
2797: #endif
2798: return(0);
2799: }
2801: /*@C
2802: VecHIPRestoreArrayWrite - Restore a HIP device pointer previously acquired with VecHIPGetArrayWrite().
2804: Data on the host will be marked as out of date. Subsequent access of
2805: the data on the host side e.g. with VecGetArray() will incur a device
2806: to host data transfer.
2808: Input Parameter:
2809: + v - the vector
2810: - a - the HIP device pointer. This pointer is invalid after
2811: VecHIPRestoreArrayWrite() returns.
2813: Fortran note:
2814: This function is not currently available from Fortran.
2816: Level: intermediate
2818: .seealso: VecHIPGetArrayWrite(), VecHIPGetArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2819: @*/
2820: PETSC_EXTERN PetscErrorCode VecHIPRestoreArrayWrite(Vec v, PetscScalar **a)
2821: {
2826: #if defined(PETSC_HAVE_HIP)
2827: v->offloadmask = PETSC_OFFLOAD_GPU;
2828: #endif
2830: PetscObjectStateIncrease((PetscObject)v);
2831: return(0);
2832: }
2834: /*@C
2835: VecHIPPlaceArray - Allows one to replace the GPU array in a vector with a
2836: GPU array provided by the user. This is useful to avoid copying an
2837: array into a vector.
2839: Not Collective
2841: Input Parameters:
2842: + vec - the vector
2843: - array - the GPU array
2845: Notes:
2846: You can return to the original GPU array with a call to VecHIPResetArray()
2847: It is not possible to use VecHIPPlaceArray() and VecPlaceArray() at the
2848: same time on the same vector.
2850: Level: developer
2852: .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecHIPResetArray(), VecHIPReplaceArray()
2854: @*/
2855: PetscErrorCode VecHIPPlaceArray(Vec vin,const PetscScalar a[])
2856: {
2861: #if defined(PETSC_HAVE_HIP)
2862: VecHIPCopyToGPU(vin);
2863: if (((Vec_Seq*)vin->data)->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"VecHIPPlaceArray()/VecPlaceArray() was already called on this vector, without a call to VecHIPResetArray()/VecResetArray()");
2864: ((Vec_Seq*)vin->data)->unplacedarray = (PetscScalar *) ((Vec_HIP*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2865: ((Vec_HIP*)vin->spptr)->GPUarray = (PetscScalar*)a;
2866: vin->offloadmask = PETSC_OFFLOAD_GPU;
2867: #endif
2868: PetscObjectStateIncrease((PetscObject)vin);
2869: return(0);
2870: }
2872: /*@C
2873: VecHIPReplaceArray - Allows one to replace the GPU array in a vector
2874: with a GPU array provided by the user. This is useful to avoid copying
2875: a GPU array into a vector.
2877: Not Collective
2879: Input Parameters:
2880: + vec - the vector
2881: - array - the GPU array
2883: Notes:
2884: This permanently replaces the GPU array and frees the memory associated
2885: with the old GPU array.
2887: The memory passed in CANNOT be freed by the user. It will be freed
2888: when the vector is destroyed.
2890: Not supported from Fortran
2892: Level: developer
2894: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecHIPResetArray(), VecHIPPlaceArray(), VecReplaceArray()
2896: @*/
2897: PetscErrorCode VecHIPReplaceArray(Vec vin,const PetscScalar a[])
2898: {
2899: #if defined(PETSC_HAVE_HIP)
2900: hipError_t err;
2901: #endif
2906: #if defined(PETSC_HAVE_HIP)
2907: err = hipFree(((Vec_HIP*)vin->spptr)->GPUarray);CHKERRHIP(err);
2908: ((Vec_HIP*)vin->spptr)->GPUarray = (PetscScalar*)a;
2909: vin->offloadmask = PETSC_OFFLOAD_GPU;
2910: #endif
2911: PetscObjectStateIncrease((PetscObject)vin);
2912: return(0);
2913: }
2915: /*@C
2916: VecHIPResetArray - Resets a vector to use its default memory. Call this
2917: after the use of VecHIPPlaceArray().
2919: Not Collective
2921: Input Parameters:
2922: . vec - the vector
2924: Level: developer
2926: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecHIPPlaceArray(), VecHIPReplaceArray()
2928: @*/
2929: PetscErrorCode VecHIPResetArray(Vec vin)
2930: {
2935: #if defined(PETSC_HAVE_HIP)
2936: VecHIPCopyToGPU(vin);
2937: ((Vec_HIP*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2938: ((Vec_Seq*)vin->data)->unplacedarray = 0;
2939: vin->offloadmask = PETSC_OFFLOAD_GPU;
2940: #endif
2941: PetscObjectStateIncrease((PetscObject)vin);
2942: return(0);
2943: }
2945: /*MC
2946: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2947: and makes them accessible via a Fortran90 pointer.
2949: Synopsis:
2950: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2952: Collective on Vec
2954: Input Parameters:
2955: + x - a vector to mimic
2956: - n - the number of vectors to obtain
2958: Output Parameters:
2959: + y - Fortran90 pointer to the array of vectors
2960: - ierr - error code
2962: Example of Usage:
2963: .vb
2964: #include <petsc/finclude/petscvec.h>
2965: use petscvec
2967: Vec x
2968: Vec, pointer :: y(:)
2969: ....
2970: call VecDuplicateVecsF90(x,2,y,ierr)
2971: call VecSet(y(2),alpha,ierr)
2972: call VecSet(y(2),alpha,ierr)
2973: ....
2974: call VecDestroyVecsF90(2,y,ierr)
2975: .ve
2977: Notes:
2978: Not yet supported for all F90 compilers
2980: Use VecDestroyVecsF90() to free the space.
2982: Level: beginner
2984: .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
2986: M*/
2988: /*MC
2989: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2990: VecGetArrayF90().
2992: Synopsis:
2993: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2995: Logically Collective on Vec
2997: Input Parameters:
2998: + x - vector
2999: - xx_v - the Fortran90 pointer to the array
3001: Output Parameter:
3002: . ierr - error code
3004: Example of Usage:
3005: .vb
3006: #include <petsc/finclude/petscvec.h>
3007: use petscvec
3009: PetscScalar, pointer :: xx_v(:)
3010: ....
3011: call VecGetArrayF90(x,xx_v,ierr)
3012: xx_v(3) = a
3013: call VecRestoreArrayF90(x,xx_v,ierr)
3014: .ve
3016: Level: beginner
3018: .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran, VecRestoreArrayReadF90()
3020: M*/
3022: /*MC
3023: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
3025: Synopsis:
3026: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
3028: Collective on Vec
3030: Input Parameters:
3031: + n - the number of vectors previously obtained
3032: - x - pointer to array of vector pointers
3034: Output Parameter:
3035: . ierr - error code
3037: Notes:
3038: Not yet supported for all F90 compilers
3040: Level: beginner
3042: .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
3044: M*/
3046: /*MC
3047: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
3048: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
3049: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
3050: when you no longer need access to the array.
3052: Synopsis:
3053: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3055: Logically Collective on Vec
3057: Input Parameter:
3058: . x - vector
3060: Output Parameters:
3061: + xx_v - the Fortran90 pointer to the array
3062: - ierr - error code
3064: Example of Usage:
3065: .vb
3066: #include <petsc/finclude/petscvec.h>
3067: use petscvec
3069: PetscScalar, pointer :: xx_v(:)
3070: ....
3071: call VecGetArrayF90(x,xx_v,ierr)
3072: xx_v(3) = a
3073: call VecRestoreArrayF90(x,xx_v,ierr)
3074: .ve
3076: If you ONLY intend to read entries from the array and not change any entries you should use VecGetArrayReadF90().
3078: Level: beginner
3080: .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), VecGetArrayReadF90(), UsingFortran
3082: M*/
3084: /*MC
3085: VecGetArrayReadF90 - Accesses a read only array from Fortran90. For default PETSc
3086: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
3087: this routine is implementation dependent. You MUST call VecRestoreArrayReadF90()
3088: when you no longer need access to the array.
3090: Synopsis:
3091: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3093: Logically Collective on Vec
3095: Input Parameter:
3096: . x - vector
3098: Output Parameters:
3099: + xx_v - the Fortran90 pointer to the array
3100: - ierr - error code
3102: Example of Usage:
3103: .vb
3104: #include <petsc/finclude/petscvec.h>
3105: use petscvec
3107: PetscScalar, pointer :: xx_v(:)
3108: ....
3109: call VecGetArrayReadF90(x,xx_v,ierr)
3110: a = xx_v(3)
3111: call VecRestoreArrayReadF90(x,xx_v,ierr)
3112: .ve
3114: If you intend to write entries into the array you must use VecGetArrayF90().
3116: Level: beginner
3118: .seealso: VecRestoreArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(), VecGetArrayF90(), UsingFortran
3120: M*/
3122: /*MC
3123: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
3124: VecGetArrayReadF90().
3126: Synopsis:
3127: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3129: Logically Collective on Vec
3131: Input Parameters:
3132: + x - vector
3133: - xx_v - the Fortran90 pointer to the array
3135: Output Parameter:
3136: . ierr - error code
3138: Example of Usage:
3139: .vb
3140: #include <petsc/finclude/petscvec.h>
3141: use petscvec
3143: PetscScalar, pointer :: xx_v(:)
3144: ....
3145: call VecGetArrayReadF90(x,xx_v,ierr)
3146: a = xx_v(3)
3147: call VecRestoreArrayReadF90(x,xx_v,ierr)
3148: .ve
3150: Level: beginner
3152: .seealso: VecGetArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(),UsingFortran, VecRestoreArrayF90()
3154: M*/
3156: /*@C
3157: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
3158: processor's portion of the vector data. You MUST call VecRestoreArray2d()
3159: when you no longer need access to the array.
3161: Logically Collective
3163: Input Parameter:
3164: + x - the vector
3165: . m - first dimension of two dimensional array
3166: . n - second dimension of two dimensional array
3167: . mstart - first index you will use in first coordinate direction (often 0)
3168: - nstart - first index in the second coordinate direction (often 0)
3170: Output Parameter:
3171: . a - location to put pointer to the array
3173: Level: developer
3175: Notes:
3176: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3177: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3178: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3179: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3181: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3183: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3184: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3185: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3186: @*/
3187: PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3188: {
3190: PetscInt i,N;
3191: PetscScalar *aa;
3197: VecGetLocalSize(x,&N);
3198: if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
3199: VecGetArray(x,&aa);
3201: PetscMalloc1(m,a);
3202: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
3203: *a -= mstart;
3204: return(0);
3205: }
3207: /*@C
3208: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
3209: processor's portion of the vector data. You MUST call VecRestoreArray2dWrite()
3210: when you no longer need access to the array.
3212: Logically Collective
3214: Input Parameter:
3215: + x - the vector
3216: . m - first dimension of two dimensional array
3217: . n - second dimension of two dimensional array
3218: . mstart - first index you will use in first coordinate direction (often 0)
3219: - nstart - first index in the second coordinate direction (often 0)
3221: Output Parameter:
3222: . a - location to put pointer to the array
3224: Level: developer
3226: Notes:
3227: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3228: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3229: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3230: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3232: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3234: Concepts: vector^accessing local values as 2d array
3236: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3237: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3238: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3239: @*/
3240: PetscErrorCode VecGetArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3241: {
3243: PetscInt i,N;
3244: PetscScalar *aa;
3250: VecGetLocalSize(x,&N);
3251: if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
3252: VecGetArrayWrite(x,&aa);
3254: PetscMalloc1(m,a);
3255: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
3256: *a -= mstart;
3257: return(0);
3258: }
3260: /*@C
3261: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
3263: Logically Collective
3265: Input Parameters:
3266: + x - the vector
3267: . m - first dimension of two dimensional array
3268: . n - second dimension of the two dimensional array
3269: . mstart - first index you will use in first coordinate direction (often 0)
3270: . nstart - first index in the second coordinate direction (often 0)
3271: - a - location of pointer to array obtained from VecGetArray2d()
3273: Level: developer
3275: Notes:
3276: For regular PETSc vectors this routine does not involve any copies. For
3277: any special vectors that do not store local vector data in a contiguous
3278: array, this routine will copy the data back into the underlying
3279: vector data structure from the array obtained with VecGetArray().
3281: This routine actually zeros out the a pointer.
3283: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3284: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3285: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3286: @*/
3287: PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3288: {
3290: void *dummy;
3296: dummy = (void*)(*a + mstart);
3297: PetscFree(dummy);
3298: VecRestoreArray(x,NULL);
3299: return(0);
3300: }
3302: /*@C
3303: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite() has been called.
3305: Logically Collective
3307: Input Parameters:
3308: + x - the vector
3309: . m - first dimension of two dimensional array
3310: . n - second dimension of the two dimensional array
3311: . mstart - first index you will use in first coordinate direction (often 0)
3312: . nstart - first index in the second coordinate direction (often 0)
3313: - a - location of pointer to array obtained from VecGetArray2d()
3315: Level: developer
3317: Notes:
3318: For regular PETSc vectors this routine does not involve any copies. For
3319: any special vectors that do not store local vector data in a contiguous
3320: array, this routine will copy the data back into the underlying
3321: vector data structure from the array obtained with VecGetArray().
3323: This routine actually zeros out the a pointer.
3325: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3326: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3327: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3328: @*/
3329: PetscErrorCode VecRestoreArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3330: {
3332: void *dummy;
3338: dummy = (void*)(*a + mstart);
3339: PetscFree(dummy);
3340: VecRestoreArrayWrite(x,NULL);
3341: return(0);
3342: }
3344: /*@C
3345: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
3346: processor's portion of the vector data. You MUST call VecRestoreArray1d()
3347: when you no longer need access to the array.
3349: Logically Collective
3351: Input Parameter:
3352: + x - the vector
3353: . m - first dimension of two dimensional array
3354: - mstart - first index you will use in first coordinate direction (often 0)
3356: Output Parameter:
3357: . a - location to put pointer to the array
3359: Level: developer
3361: Notes:
3362: For a vector obtained from DMCreateLocalVector() mstart are likely
3363: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3364: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3366: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3368: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3369: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3370: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3371: @*/
3372: PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3373: {
3375: PetscInt N;
3381: VecGetLocalSize(x,&N);
3382: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3383: VecGetArray(x,a);
3384: *a -= mstart;
3385: return(0);
3386: }
3388: /*@C
3389: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
3390: processor's portion of the vector data. You MUST call VecRestoreArray1dWrite()
3391: when you no longer need access to the array.
3393: Logically Collective
3395: Input Parameter:
3396: + x - the vector
3397: . m - first dimension of two dimensional array
3398: - mstart - first index you will use in first coordinate direction (often 0)
3400: Output Parameter:
3401: . a - location to put pointer to the array
3403: Level: developer
3405: Notes:
3406: For a vector obtained from DMCreateLocalVector() mstart are likely
3407: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3408: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3410: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3412: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3413: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3414: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3415: @*/
3416: PetscErrorCode VecGetArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3417: {
3419: PetscInt N;
3425: VecGetLocalSize(x,&N);
3426: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3427: VecGetArrayWrite(x,a);
3428: *a -= mstart;
3429: return(0);
3430: }
3432: /*@C
3433: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
3435: Logically Collective
3437: Input Parameters:
3438: + x - the vector
3439: . m - first dimension of two dimensional array
3440: . mstart - first index you will use in first coordinate direction (often 0)
3441: - a - location of pointer to array obtained from VecGetArray21()
3443: Level: developer
3445: Notes:
3446: For regular PETSc vectors this routine does not involve any copies. For
3447: any special vectors that do not store local vector data in a contiguous
3448: array, this routine will copy the data back into the underlying
3449: vector data structure from the array obtained with VecGetArray1d().
3451: This routine actually zeros out the a pointer.
3453: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3454: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3455: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3456: @*/
3457: PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3458: {
3464: VecRestoreArray(x,NULL);
3465: return(0);
3466: }
3468: /*@C
3469: VecRestoreArray1dWrite - Restores a vector after VecGetArray1dWrite() has been called.
3471: Logically Collective
3473: Input Parameters:
3474: + x - the vector
3475: . m - first dimension of two dimensional array
3476: . mstart - first index you will use in first coordinate direction (often 0)
3477: - a - location of pointer to array obtained from VecGetArray21()
3479: Level: developer
3481: Notes:
3482: For regular PETSc vectors this routine does not involve any copies. For
3483: any special vectors that do not store local vector data in a contiguous
3484: array, this routine will copy the data back into the underlying
3485: vector data structure from the array obtained with VecGetArray1d().
3487: This routine actually zeros out the a pointer.
3489: Concepts: vector^accessing local values as 1d array
3491: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3492: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3493: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3494: @*/
3495: PetscErrorCode VecRestoreArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3496: {
3502: VecRestoreArrayWrite(x,NULL);
3503: return(0);
3504: }
3506: /*@C
3507: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
3508: processor's portion of the vector data. You MUST call VecRestoreArray3d()
3509: when you no longer need access to the array.
3511: Logically Collective
3513: Input Parameter:
3514: + x - the vector
3515: . m - first dimension of three dimensional array
3516: . n - second dimension of three dimensional array
3517: . p - third dimension of three dimensional array
3518: . mstart - first index you will use in first coordinate direction (often 0)
3519: . nstart - first index in the second coordinate direction (often 0)
3520: - pstart - first index in the third coordinate direction (often 0)
3522: Output Parameter:
3523: . a - location to put pointer to the array
3525: Level: developer
3527: Notes:
3528: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3529: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3530: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3531: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3533: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3535: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3536: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3537: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3538: @*/
3539: PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3540: {
3542: PetscInt i,N,j;
3543: PetscScalar *aa,**b;
3549: VecGetLocalSize(x,&N);
3550: if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3551: VecGetArray(x,&aa);
3553: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3554: b = (PetscScalar**)((*a) + m);
3555: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3556: for (i=0; i<m; i++)
3557: for (j=0; j<n; j++)
3558: b[i*n+j] = aa + i*n*p + j*p - pstart;
3560: *a -= mstart;
3561: return(0);
3562: }
3564: /*@C
3565: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3566: processor's portion of the vector data. You MUST call VecRestoreArray3dWrite()
3567: when you no longer need access to the array.
3569: Logically Collective
3571: Input Parameter:
3572: + x - the vector
3573: . m - first dimension of three dimensional array
3574: . n - second dimension of three dimensional array
3575: . p - third dimension of three dimensional array
3576: . mstart - first index you will use in first coordinate direction (often 0)
3577: . nstart - first index in the second coordinate direction (often 0)
3578: - pstart - first index in the third coordinate direction (often 0)
3580: Output Parameter:
3581: . a - location to put pointer to the array
3583: Level: developer
3585: Notes:
3586: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3587: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3588: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3589: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3591: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3593: Concepts: vector^accessing local values as 3d array
3595: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3596: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3597: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3598: @*/
3599: PetscErrorCode VecGetArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3600: {
3602: PetscInt i,N,j;
3603: PetscScalar *aa,**b;
3609: VecGetLocalSize(x,&N);
3610: if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3611: VecGetArrayWrite(x,&aa);
3613: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3614: b = (PetscScalar**)((*a) + m);
3615: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3616: for (i=0; i<m; i++)
3617: for (j=0; j<n; j++)
3618: b[i*n+j] = aa + i*n*p + j*p - pstart;
3620: *a -= mstart;
3621: return(0);
3622: }
3624: /*@C
3625: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
3627: Logically Collective
3629: Input Parameters:
3630: + x - the vector
3631: . m - first dimension of three dimensional array
3632: . n - second dimension of the three dimensional array
3633: . p - third dimension of the three dimensional array
3634: . mstart - first index you will use in first coordinate direction (often 0)
3635: . nstart - first index in the second coordinate direction (often 0)
3636: . pstart - first index in the third coordinate direction (often 0)
3637: - a - location of pointer to array obtained from VecGetArray3d()
3639: Level: developer
3641: Notes:
3642: For regular PETSc vectors this routine does not involve any copies. For
3643: any special vectors that do not store local vector data in a contiguous
3644: array, this routine will copy the data back into the underlying
3645: vector data structure from the array obtained with VecGetArray().
3647: This routine actually zeros out the a pointer.
3649: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3650: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3651: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3652: @*/
3653: PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3654: {
3656: void *dummy;
3662: dummy = (void*)(*a + mstart);
3663: PetscFree(dummy);
3664: VecRestoreArray(x,NULL);
3665: return(0);
3666: }
3668: /*@C
3669: VecRestoreArray3dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3671: Logically Collective
3673: Input Parameters:
3674: + x - the vector
3675: . m - first dimension of three dimensional array
3676: . n - second dimension of the three dimensional array
3677: . p - third dimension of the three dimensional array
3678: . mstart - first index you will use in first coordinate direction (often 0)
3679: . nstart - first index in the second coordinate direction (often 0)
3680: . pstart - first index in the third coordinate direction (often 0)
3681: - a - location of pointer to array obtained from VecGetArray3d()
3683: Level: developer
3685: Notes:
3686: For regular PETSc vectors this routine does not involve any copies. For
3687: any special vectors that do not store local vector data in a contiguous
3688: array, this routine will copy the data back into the underlying
3689: vector data structure from the array obtained with VecGetArray().
3691: This routine actually zeros out the a pointer.
3693: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3694: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3695: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3696: @*/
3697: PetscErrorCode VecRestoreArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3698: {
3700: void *dummy;
3706: dummy = (void*)(*a + mstart);
3707: PetscFree(dummy);
3708: VecRestoreArrayWrite(x,NULL);
3709: return(0);
3710: }
3712: /*@C
3713: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3714: processor's portion of the vector data. You MUST call VecRestoreArray4d()
3715: when you no longer need access to the array.
3717: Logically Collective
3719: Input Parameter:
3720: + x - the vector
3721: . m - first dimension of four dimensional array
3722: . n - second dimension of four dimensional array
3723: . p - third dimension of four dimensional array
3724: . q - fourth dimension of four dimensional array
3725: . mstart - first index you will use in first coordinate direction (often 0)
3726: . nstart - first index in the second coordinate direction (often 0)
3727: . pstart - first index in the third coordinate direction (often 0)
3728: - qstart - first index in the fourth coordinate direction (often 0)
3730: Output Parameter:
3731: . a - location to put pointer to the array
3733: Level: beginner
3735: Notes:
3736: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3737: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3738: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3739: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3741: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3743: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3744: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3745: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3746: @*/
3747: PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3748: {
3750: PetscInt i,N,j,k;
3751: PetscScalar *aa,***b,**c;
3757: VecGetLocalSize(x,&N);
3758: if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
3759: VecGetArray(x,&aa);
3761: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3762: b = (PetscScalar***)((*a) + m);
3763: c = (PetscScalar**)(b + m*n);
3764: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3765: for (i=0; i<m; i++)
3766: for (j=0; j<n; j++)
3767: b[i*n+j] = c + i*n*p + j*p - pstart;
3768: for (i=0; i<m; i++)
3769: for (j=0; j<n; j++)
3770: for (k=0; k<p; k++)
3771: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3772: *a -= mstart;
3773: return(0);
3774: }
3776: /*@C
3777: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3778: processor's portion of the vector data. You MUST call VecRestoreArray4dWrite()
3779: when you no longer need access to the array.
3781: Logically Collective
3783: Input Parameter:
3784: + x - the vector
3785: . m - first dimension of four dimensional array
3786: . n - second dimension of four dimensional array
3787: . p - third dimension of four dimensional array
3788: . q - fourth dimension of four dimensional array
3789: . mstart - first index you will use in first coordinate direction (often 0)
3790: . nstart - first index in the second coordinate direction (often 0)
3791: . pstart - first index in the third coordinate direction (often 0)
3792: - qstart - first index in the fourth coordinate direction (often 0)
3794: Output Parameter:
3795: . a - location to put pointer to the array
3797: Level: beginner
3799: Notes:
3800: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3801: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3802: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3803: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3805: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3807: Concepts: vector^accessing local values as 3d array
3809: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3810: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3811: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3812: @*/
3813: PetscErrorCode VecGetArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3814: {
3816: PetscInt i,N,j,k;
3817: PetscScalar *aa,***b,**c;
3823: VecGetLocalSize(x,&N);
3824: if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
3825: VecGetArrayWrite(x,&aa);
3827: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3828: b = (PetscScalar***)((*a) + m);
3829: c = (PetscScalar**)(b + m*n);
3830: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3831: for (i=0; i<m; i++)
3832: for (j=0; j<n; j++)
3833: b[i*n+j] = c + i*n*p + j*p - pstart;
3834: for (i=0; i<m; i++)
3835: for (j=0; j<n; j++)
3836: for (k=0; k<p; k++)
3837: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3838: *a -= mstart;
3839: return(0);
3840: }
3842: /*@C
3843: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
3845: Logically Collective
3847: Input Parameters:
3848: + x - the vector
3849: . m - first dimension of four dimensional array
3850: . n - second dimension of the four dimensional array
3851: . p - third dimension of the four dimensional array
3852: . q - fourth dimension of the four dimensional array
3853: . mstart - first index you will use in first coordinate direction (often 0)
3854: . nstart - first index in the second coordinate direction (often 0)
3855: . pstart - first index in the third coordinate direction (often 0)
3856: . qstart - first index in the fourth coordinate direction (often 0)
3857: - a - location of pointer to array obtained from VecGetArray4d()
3859: Level: beginner
3861: Notes:
3862: For regular PETSc vectors this routine does not involve any copies. For
3863: any special vectors that do not store local vector data in a contiguous
3864: array, this routine will copy the data back into the underlying
3865: vector data structure from the array obtained with VecGetArray().
3867: This routine actually zeros out the a pointer.
3869: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3870: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3871: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3872: @*/
3873: PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3874: {
3876: void *dummy;
3882: dummy = (void*)(*a + mstart);
3883: PetscFree(dummy);
3884: VecRestoreArray(x,NULL);
3885: return(0);
3886: }
3888: /*@C
3889: VecRestoreArray4dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3891: Logically Collective
3893: Input Parameters:
3894: + x - the vector
3895: . m - first dimension of four dimensional array
3896: . n - second dimension of the four dimensional array
3897: . p - third dimension of the four dimensional array
3898: . q - fourth dimension of the four dimensional array
3899: . mstart - first index you will use in first coordinate direction (often 0)
3900: . nstart - first index in the second coordinate direction (often 0)
3901: . pstart - first index in the third coordinate direction (often 0)
3902: . qstart - first index in the fourth coordinate direction (often 0)
3903: - a - location of pointer to array obtained from VecGetArray4d()
3905: Level: beginner
3907: Notes:
3908: For regular PETSc vectors this routine does not involve any copies. For
3909: any special vectors that do not store local vector data in a contiguous
3910: array, this routine will copy the data back into the underlying
3911: vector data structure from the array obtained with VecGetArray().
3913: This routine actually zeros out the a pointer.
3915: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3916: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3917: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3918: @*/
3919: PetscErrorCode VecRestoreArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3920: {
3922: void *dummy;
3928: dummy = (void*)(*a + mstart);
3929: PetscFree(dummy);
3930: VecRestoreArrayWrite(x,NULL);
3931: return(0);
3932: }
3934: /*@C
3935: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3936: processor's portion of the vector data. You MUST call VecRestoreArray2dRead()
3937: when you no longer need access to the array.
3939: Logically Collective
3941: Input Parameter:
3942: + x - the vector
3943: . m - first dimension of two dimensional array
3944: . n - second dimension of two dimensional array
3945: . mstart - first index you will use in first coordinate direction (often 0)
3946: - nstart - first index in the second coordinate direction (often 0)
3948: Output Parameter:
3949: . a - location to put pointer to the array
3951: Level: developer
3953: Notes:
3954: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3955: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3956: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3957: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3959: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3961: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3962: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3963: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3964: @*/
3965: PetscErrorCode VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3966: {
3967: PetscErrorCode ierr;
3968: PetscInt i,N;
3969: const PetscScalar *aa;
3975: VecGetLocalSize(x,&N);
3976: if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
3977: VecGetArrayRead(x,&aa);
3979: PetscMalloc1(m,a);
3980: for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
3981: *a -= mstart;
3982: return(0);
3983: }
3985: /*@C
3986: VecRestoreArray2dRead - Restores a vector after VecGetArray2dRead() has been called.
3988: Logically Collective
3990: Input Parameters:
3991: + x - the vector
3992: . m - first dimension of two dimensional array
3993: . n - second dimension of the two dimensional array
3994: . mstart - first index you will use in first coordinate direction (often 0)
3995: . nstart - first index in the second coordinate direction (often 0)
3996: - a - location of pointer to array obtained from VecGetArray2d()
3998: Level: developer
4000: Notes:
4001: For regular PETSc vectors this routine does not involve any copies. For
4002: any special vectors that do not store local vector data in a contiguous
4003: array, this routine will copy the data back into the underlying
4004: vector data structure from the array obtained with VecGetArray().
4006: This routine actually zeros out the a pointer.
4008: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
4009: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
4010: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
4011: @*/
4012: PetscErrorCode VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
4013: {
4015: void *dummy;
4021: dummy = (void*)(*a + mstart);
4022: PetscFree(dummy);
4023: VecRestoreArrayRead(x,NULL);
4024: return(0);
4025: }
4027: /*@C
4028: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
4029: processor's portion of the vector data. You MUST call VecRestoreArray1dRead()
4030: when you no longer need access to the array.
4032: Logically Collective
4034: Input Parameter:
4035: + x - the vector
4036: . m - first dimension of two dimensional array
4037: - mstart - first index you will use in first coordinate direction (often 0)
4039: Output Parameter:
4040: . a - location to put pointer to the array
4042: Level: developer
4044: Notes:
4045: For a vector obtained from DMCreateLocalVector() mstart are likely
4046: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
4047: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
4049: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4051: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
4052: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
4053: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
4054: @*/
4055: PetscErrorCode VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
4056: {
4058: PetscInt N;
4064: VecGetLocalSize(x,&N);
4065: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
4066: VecGetArrayRead(x,(const PetscScalar**)a);
4067: *a -= mstart;
4068: return(0);
4069: }
4071: /*@C
4072: VecRestoreArray1dRead - Restores a vector after VecGetArray1dRead() has been called.
4074: Logically Collective
4076: Input Parameters:
4077: + x - the vector
4078: . m - first dimension of two dimensional array
4079: . mstart - first index you will use in first coordinate direction (often 0)
4080: - a - location of pointer to array obtained from VecGetArray21()
4082: Level: developer
4084: Notes:
4085: For regular PETSc vectors this routine does not involve any copies. For
4086: any special vectors that do not store local vector data in a contiguous
4087: array, this routine will copy the data back into the underlying
4088: vector data structure from the array obtained with VecGetArray1dRead().
4090: This routine actually zeros out the a pointer.
4092: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
4093: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
4094: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
4095: @*/
4096: PetscErrorCode VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
4097: {
4103: VecRestoreArrayRead(x,NULL);
4104: return(0);
4105: }
4108: /*@C
4109: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
4110: processor's portion of the vector data. You MUST call VecRestoreArray3dRead()
4111: when you no longer need access to the array.
4113: Logically Collective
4115: Input Parameter:
4116: + x - the vector
4117: . m - first dimension of three dimensional array
4118: . n - second dimension of three dimensional array
4119: . p - third dimension of three dimensional array
4120: . mstart - first index you will use in first coordinate direction (often 0)
4121: . nstart - first index in the second coordinate direction (often 0)
4122: - pstart - first index in the third coordinate direction (often 0)
4124: Output Parameter:
4125: . a - location to put pointer to the array
4127: Level: developer
4129: Notes:
4130: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
4131: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
4132: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
4133: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3dRead().
4135: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4137: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
4138: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
4139: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
4140: @*/
4141: PetscErrorCode VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
4142: {
4143: PetscErrorCode ierr;
4144: PetscInt i,N,j;
4145: const PetscScalar *aa;
4146: PetscScalar **b;
4152: VecGetLocalSize(x,&N);
4153: if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
4154: VecGetArrayRead(x,&aa);
4156: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
4157: b = (PetscScalar**)((*a) + m);
4158: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
4159: for (i=0; i<m; i++)
4160: for (j=0; j<n; j++)
4161: b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;
4163: *a -= mstart;
4164: return(0);
4165: }
4167: /*@C
4168: VecRestoreArray3dRead - Restores a vector after VecGetArray3dRead() has been called.
4170: Logically Collective
4172: Input Parameters:
4173: + x - the vector
4174: . m - first dimension of three dimensional array
4175: . n - second dimension of the three dimensional array
4176: . p - third dimension of the three 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: - a - location of pointer to array obtained from VecGetArray3dRead()
4182: Level: developer
4184: Notes:
4185: For regular PETSc vectors this routine does not involve any copies. For
4186: any special vectors that do not store local vector data in a contiguous
4187: array, this routine will copy the data back into the underlying
4188: vector data structure from the array obtained with VecGetArray().
4190: This routine actually zeros out the a pointer.
4192: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
4193: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
4194: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
4195: @*/
4196: PetscErrorCode VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
4197: {
4199: void *dummy;
4205: dummy = (void*)(*a + mstart);
4206: PetscFree(dummy);
4207: VecRestoreArrayRead(x,NULL);
4208: return(0);
4209: }
4211: /*@C
4212: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
4213: processor's portion of the vector data. You MUST call VecRestoreArray4dRead()
4214: when you no longer need access to the array.
4216: Logically Collective
4218: Input Parameter:
4219: + x - the vector
4220: . m - first dimension of four dimensional array
4221: . n - second dimension of four dimensional array
4222: . p - third dimension of four dimensional array
4223: . q - fourth dimension of four dimensional array
4224: . mstart - first index you will use in first coordinate direction (often 0)
4225: . nstart - first index in the second coordinate direction (often 0)
4226: . pstart - first index in the third coordinate direction (often 0)
4227: - qstart - first index in the fourth coordinate direction (often 0)
4229: Output Parameter:
4230: . a - location to put pointer to the array
4232: Level: beginner
4234: Notes:
4235: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
4236: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
4237: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
4238: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
4240: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4242: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
4243: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
4244: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
4245: @*/
4246: PetscErrorCode VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
4247: {
4248: PetscErrorCode ierr;
4249: PetscInt i,N,j,k;
4250: const PetscScalar *aa;
4251: PetscScalar ***b,**c;
4257: VecGetLocalSize(x,&N);
4258: if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
4259: VecGetArrayRead(x,&aa);
4261: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
4262: b = (PetscScalar***)((*a) + m);
4263: c = (PetscScalar**)(b + m*n);
4264: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
4265: for (i=0; i<m; i++)
4266: for (j=0; j<n; j++)
4267: b[i*n+j] = c + i*n*p + j*p - pstart;
4268: for (i=0; i<m; i++)
4269: for (j=0; j<n; j++)
4270: for (k=0; k<p; k++)
4271: c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
4272: *a -= mstart;
4273: return(0);
4274: }
4276: /*@C
4277: VecRestoreArray4dRead - Restores a vector after VecGetArray3d() has been called.
4279: Logically Collective
4281: Input Parameters:
4282: + x - the vector
4283: . m - first dimension of four dimensional array
4284: . n - second dimension of the four dimensional array
4285: . p - third dimension of the four dimensional array
4286: . q - fourth dimension of the four dimensional array
4287: . mstart - first index you will use in first coordinate direction (often 0)
4288: . nstart - first index in the second coordinate direction (often 0)
4289: . pstart - first index in the third coordinate direction (often 0)
4290: . qstart - first index in the fourth coordinate direction (often 0)
4291: - a - location of pointer to array obtained from VecGetArray4dRead()
4293: Level: beginner
4295: Notes:
4296: For regular PETSc vectors this routine does not involve any copies. For
4297: any special vectors that do not store local vector data in a contiguous
4298: array, this routine will copy the data back into the underlying
4299: vector data structure from the array obtained with VecGetArray().
4301: This routine actually zeros out the a pointer.
4303: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
4304: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
4305: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
4306: @*/
4307: PetscErrorCode VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
4308: {
4310: void *dummy;
4316: dummy = (void*)(*a + mstart);
4317: PetscFree(dummy);
4318: VecRestoreArrayRead(x,NULL);
4319: return(0);
4320: }
4322: #if defined(PETSC_USE_DEBUG)
4324: /*@
4325: VecLockGet - Gets the current lock status of a vector
4327: Logically Collective on Vec
4329: Input Parameter:
4330: . x - the vector
4332: Output Parameter:
4333: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
4334: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
4336: Level: beginner
4338: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop()
4339: @*/
4340: PetscErrorCode VecLockGet(Vec x,PetscInt *state)
4341: {
4344: *state = x->lock;
4345: return(0);
4346: }
4348: /*@
4349: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from writing
4351: Logically Collective on Vec
4353: Input Parameter:
4354: . x - the vector
4356: Notes:
4357: If this is set then calls to VecGetArray() or VecSetValues() or any other routines that change the vectors values will fail.
4359: The call can be nested, i.e., called multiple times on the same vector, but each VecLockReadPush(x) has to have one matching
4360: VecLockReadPop(x), which removes the latest read-only lock.
4362: Level: beginner
4364: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPop(), VecLockGet()
4365: @*/
4366: PetscErrorCode VecLockReadPush(Vec x)
4367: {
4370: if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to read it");
4371: x->lock++;
4372: return(0);
4373: }
4375: /*@
4376: VecLockReadPop - Pops a read-only lock from a vector
4378: Logically Collective on Vec
4380: Input Parameter:
4381: . x - the vector
4383: Level: beginner
4385: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockGet()
4386: @*/
4387: PetscErrorCode VecLockReadPop(Vec x)
4388: {
4391: x->lock--;
4392: if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector has been unlocked from read-only access too many times");
4393: return(0);
4394: }
4396: /*@C
4397: VecLockWriteSet_Private - Lock or unlock a vector for exclusive read/write access
4399: Logically Collective on Vec
4401: Input Parameter:
4402: + x - the vector
4403: - flg - PETSC_TRUE to lock the vector for writing; PETSC_FALSE to unlock it.
4405: Notes:
4406: The function is usefull in split-phase computations, which usually have a begin phase and an end phase.
4407: One can call VecLockWriteSet_Private(x,PETSC_TRUE) in the begin phase to lock a vector for exclusive
4408: access, and call VecLockWriteSet_Private(x,PETSC_FALSE) in the end phase to unlock the vector from exclusive
4409: access. In this way, one is ensured no other operations can access the vector in between. The code may like
4412: VecGetArray(x,&xdata); // begin phase
4413: VecLockWriteSet_Private(v,PETSC_TRUE);
4415: Other operations, which can not acceess x anymore (they can access xdata, of course)
4417: VecRestoreArray(x,&vdata); // end phase
4418: VecLockWriteSet_Private(v,PETSC_FALSE);
4420: The call can not be nested on the same vector, in other words, one can not call VecLockWriteSet_Private(x,PETSC_TRUE)
4421: again before calling VecLockWriteSet_Private(v,PETSC_FALSE).
4423: Level: beginner
4425: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop(), VecLockGet()
4426: @*/
4427: PetscErrorCode VecLockWriteSet_Private(Vec x,PetscBool flg)
4428: {
4431: if (flg) {
4432: if (x->lock > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for read-only access but you want to write it");
4433: else if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to write it");
4434: else x->lock = -1;
4435: } else {
4436: if (x->lock != -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is not locked for exclusive write access but you want to unlock it from that");
4437: x->lock = 0;
4438: }
4439: return(0);
4440: }
4442: /*@
4443: VecLockPush - Pushes a read-only lock on a vector to prevent it from writing
4445: Level: deprecated
4447: .seealso: VecLockReadPush()
4448: @*/
4449: PetscErrorCode VecLockPush(Vec x)
4450: {
4453: VecLockReadPush(x);
4454: return(0);
4455: }
4457: /*@
4458: VecLockPop - Pops a read-only lock from a vector
4460: Level: deprecated
4462: .seealso: VecLockReadPop()
4463: @*/
4464: PetscErrorCode VecLockPop(Vec x)
4465: {
4468: VecLockReadPop(x);
4469: return(0);
4470: }
4472: #endif