Actual source code: rvector.c
1: /*
2: Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
3: These are the vector functions the user calls.
4: */
5: #include "petsc/private/sfimpl.h"
6: #include "petscsystypes.h"
7: #include <petsc/private/vecimpl.h>
8: #if defined(PETSC_HAVE_CUDA)
9: #include <../src/vec/vec/impls/dvecimpl.h>
10: #include <petsc/private/cudavecimpl.h>
11: #endif
12: #if defined(PETSC_HAVE_HIP)
13: #include <../src/vec/vec/impls/dvecimpl.h>
14: #include <petsc/private/hipvecimpl.h>
15: #endif
16: PetscInt VecGetSubVectorSavedStateId = -1;
18: PETSC_EXTERN PetscErrorCode VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)
19: {
20: #if defined(PETSC_USE_DEBUG)
21: PetscInt n,i;
22: const PetscScalar *x;
24: #if defined(PETSC_HAVE_DEVICE)
25: if ((vec->petscnative || vec->ops->getarray) && (vec->offloadmask & PETSC_OFFLOAD_CPU)) {
26: #else
27: if (vec->petscnative || vec->ops->getarray) {
28: #endif
29: VecGetLocalSize(vec,&n);
30: VecGetArrayRead(vec,&x);
31: for (i=0; i<n; i++) {
32: if (begin) {
34: } else {
36: }
37: }
38: VecRestoreArrayRead(vec,&x);
39: }
40: #else
41: #endif
42: return 0;
43: }
45: /*@
46: VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
48: Logically Collective on Vec
50: Input Parameters:
51: . x, y - the vectors
53: Output Parameter:
54: . max - the result
56: Level: advanced
58: Notes:
59: x and y may be the same vector
60: if a particular y_i is zero, it is treated as 1 in the above formula
62: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
63: @*/
64: PetscErrorCode VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
65: {
72: VecCheckSameSize(x,1,y,2);
73: (*x->ops->maxpointwisedivide)(x,y,max);
74: return 0;
75: }
77: /*@
78: VecDot - Computes the vector dot product.
80: Collective on Vec
82: Input Parameters:
83: . x, y - the vectors
85: Output Parameter:
86: . val - the dot product
88: Performance Issues:
89: $ per-processor memory bandwidth
90: $ interprocessor latency
91: $ work load imbalance that causes certain processes to arrive much earlier than others
93: Notes for Users of Complex Numbers:
94: For complex vectors, VecDot() computes
95: $ val = (x,y) = y^H x,
96: where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex
97: inner product where the SECOND argument gets the complex conjugate. Since the BLASdot() complex conjugates the first
98: first argument we call the BLASdot() with the arguments reversed.
100: Use VecTDot() for the indefinite form
101: $ val = (x,y) = y^T x,
102: where y^T denotes the transpose of y.
104: Level: intermediate
106: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDotRealPart()
107: @*/
108: PetscErrorCode VecDot(Vec x,Vec y,PetscScalar *val)
109: {
116: VecCheckSameSize(x,1,y,2);
118: PetscLogEventBegin(VEC_Dot,x,y,0,0);
119: (*x->ops->dot)(x,y,val);
120: PetscLogEventEnd(VEC_Dot,x,y,0,0);
121: return 0;
122: }
124: /*@
125: VecDotRealPart - Computes the real part of the vector dot product.
127: Collective on Vec
129: Input Parameters:
130: . x, y - the vectors
132: Output Parameter:
133: . val - the real part of the dot product;
135: Performance Issues:
136: $ per-processor memory bandwidth
137: $ interprocessor latency
138: $ work load imbalance that causes certain processes to arrive much earlier than others
140: Notes for Users of Complex Numbers:
141: See VecDot() for more details on the definition of the dot product for complex numbers
143: For real numbers this returns the same value as VecDot()
145: 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
146: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
148: Developer Note: This is not currently optimized to compute only the real part of the dot product.
150: Level: intermediate
152: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDot(), VecDotNorm2()
153: @*/
154: PetscErrorCode VecDotRealPart(Vec x,Vec y,PetscReal *val)
155: {
156: PetscScalar fdot;
158: VecDot(x,y,&fdot);
159: *val = PetscRealPart(fdot);
160: return 0;
161: }
163: /*@
164: VecNorm - Computes the vector norm.
166: Collective on Vec
168: Input Parameters:
169: + x - the vector
170: - type - the type of the norm requested
172: Output Parameter:
173: . val - the norm
175: Values of NormType:
176: + NORM_1 - sum_i |x_i|
177: . NORM_2 - sqrt(sum_i |x_i|^2)
178: . NORM_INFINITY - max_i |x_i|
179: - NORM_1_AND_2 - computes efficiently both NORM_1 and NORM_2 and stores them each in an output array
181: Notes:
182: For complex numbers NORM_1 will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
183: norm of the absolute values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
184: the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
185: people expect the former.
187: This routine stashes the computed norm value, repeated calls before the vector entries are changed are then rapid since the
188: precomputed value is immediately available. Certain vector operations such as VecSet() store the norms so the value is
189: immediately available and does not need to be explicitly computed. VecScale() updates any stashed norm values, thus calls after VecScale()
190: do not need to explicitly recompute the norm.
192: Level: intermediate
194: Performance Issues:
195: + per-processor memory bandwidth - limits the speed of the computation of local portion of the norm
196: . interprocessor latency - limits the accumulation of the result across ranks, .i.e. MPI_Allreduce() time
197: . number of ranks - the time for the result will grow with the log base 2 of the number of ranks sharing the vector
198: - work load imbalance - the rank with the largest number of vector entries will limit the speed up
200: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
201: VecNormBegin(), VecNormEnd(), NormType()
203: @*/
204: PetscErrorCode VecNorm(Vec x,NormType type,PetscReal *val)
205: {
206: PetscBool flg;
212: /*
213: * Cached data?
214: */
215: if (type!=NORM_1_AND_2) {
216: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
217: if (flg) return 0;
218: }
219: PetscLogEventBegin(VEC_Norm,x,0,0,0);
220: (*x->ops->norm)(x,type,val);
221: PetscLogEventEnd(VEC_Norm,x,0,0,0);
222: if (type!=NORM_1_AND_2) {
223: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
224: }
225: return 0;
226: }
228: /*@
229: VecNormAvailable - Returns the vector norm if it is already known.
231: Not Collective
233: Input Parameters:
234: + x - the vector
235: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
236: NORM_1_AND_2, which computes both norms and stores them
237: in a two element array.
239: Output Parameters:
240: + available - PETSC_TRUE if the val returned is valid
241: - val - the norm
243: Notes:
244: $ NORM_1 denotes sum_i |x_i|
245: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
246: $ NORM_INFINITY denotes max_i |x_i|
248: Level: intermediate
250: Performance Issues:
251: $ per-processor memory bandwidth
252: $ interprocessor latency
253: $ work load imbalance that causes certain processes to arrive much earlier than others
255: Compile Option:
256: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
257: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
258: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
260: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
261: VecNormBegin(), VecNormEnd()
263: @*/
264: PetscErrorCode VecNormAvailable(Vec x,NormType type,PetscBool *available,PetscReal *val)
265: {
270: *available = PETSC_FALSE;
271: if (type!=NORM_1_AND_2) {
272: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
273: }
274: return 0;
275: }
277: /*@
278: VecNormalize - Normalizes a vector by 2-norm.
280: Collective on Vec
282: Input Parameter:
283: . x - the vector
285: Output Parameter:
286: . val - the vector norm before normalization
288: Level: intermediate
290: @*/
291: PetscErrorCode VecNormalize(Vec x,PetscReal *val)
292: {
293: PetscReal norm;
297: PetscLogEventBegin(VEC_Normalize,x,0,0,0);
298: VecNorm(x,NORM_2,&norm);
299: if (norm == 0.0) {
300: PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
301: } else if (norm != 1.0) {
302: PetscScalar tmp = 1.0/norm;
303: VecScale(x,tmp);
304: }
305: if (val) *val = norm;
306: PetscLogEventEnd(VEC_Normalize,x,0,0,0);
307: return 0;
308: }
310: /*@C
311: VecMax - Determines the vector component with maximum real part and its location.
313: Collective on Vec
315: Input Parameter:
316: . x - the vector
318: Output Parameters:
319: + p - the location of val (pass NULL if you don't want this)
320: - val - the maximum component
322: Notes:
323: Returns the value PETSC_MIN_REAL and negative p if the vector is of length 0.
325: Returns the smallest index with the maximum value
326: Level: intermediate
328: .seealso: VecNorm(), VecMin()
329: @*/
330: PetscErrorCode VecMax(Vec x,PetscInt *p,PetscReal *val)
331: {
335: PetscLogEventBegin(VEC_Max,x,0,0,0);
336: (*x->ops->max)(x,p,val);
337: PetscLogEventEnd(VEC_Max,x,0,0,0);
338: return 0;
339: }
341: /*@C
342: VecMin - Determines the vector component with minimum real part and its location.
344: Collective on Vec
346: Input Parameter:
347: . x - the vector
349: Output Parameters:
350: + p - the location of val (pass NULL if you don't want this location)
351: - val - the minimum component
353: Level: intermediate
355: Notes:
356: Returns the value PETSC_MAX_REAL and negative p if the vector is of length 0.
358: This returns the smallest index with the minumum value
360: .seealso: VecMax()
361: @*/
362: PetscErrorCode VecMin(Vec x,PetscInt *p,PetscReal *val)
363: {
367: PetscLogEventBegin(VEC_Min,x,0,0,0);
368: (*x->ops->min)(x,p,val);
369: PetscLogEventEnd(VEC_Min,x,0,0,0);
370: return 0;
371: }
373: /*@
374: VecTDot - Computes an indefinite vector dot product. That is, this
375: routine does NOT use the complex conjugate.
377: Collective on Vec
379: Input Parameters:
380: . x, y - the vectors
382: Output Parameter:
383: . val - the dot product
385: Notes for Users of Complex Numbers:
386: For complex vectors, VecTDot() computes the indefinite form
387: $ val = (x,y) = y^T x,
388: where y^T denotes the transpose of y.
390: Use VecDot() for the inner product
391: $ val = (x,y) = y^H x,
392: where y^H denotes the conjugate transpose of y.
394: Level: intermediate
396: .seealso: VecDot(), VecMTDot()
397: @*/
398: PetscErrorCode VecTDot(Vec x,Vec y,PetscScalar *val)
399: {
406: VecCheckSameSize(x,1,y,2);
408: PetscLogEventBegin(VEC_TDot,x,y,0,0);
409: (*x->ops->tdot)(x,y,val);
410: PetscLogEventEnd(VEC_TDot,x,y,0,0);
411: return 0;
412: }
414: /*@
415: VecScale - Scales a vector.
417: Not collective on Vec
419: Input Parameters:
420: + x - the vector
421: - alpha - the scalar
423: Note:
424: For a vector with n components, VecScale() computes
425: $ x[i] = alpha * x[i], for i=1,...,n.
427: Level: intermediate
429: @*/
430: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
431: {
432: PetscReal norms[4] = {0.0,0.0,0.0, 0.0};
433: PetscBool flgs[4];
434: PetscInt i;
439: PetscLogEventBegin(VEC_Scale,x,0,0,0);
440: if (alpha != (PetscScalar)1.0) {
441: VecSetErrorIfLocked(x,1);
442: /* get current stashed norms */
443: for (i=0; i<4; i++) {
444: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
445: }
446: (*x->ops->scale)(x,alpha);
447: PetscObjectStateIncrease((PetscObject)x);
448: /* put the scaled stashed norms back into the Vec */
449: for (i=0; i<4; i++) {
450: if (flgs[i]) {
451: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
452: }
453: }
454: }
455: PetscLogEventEnd(VEC_Scale,x,0,0,0);
456: return 0;
457: }
459: /*@
460: VecSet - Sets all components of a vector to a single scalar value.
462: Logically Collective on Vec
464: Input Parameters:
465: + x - the vector
466: - alpha - the scalar
468: Output Parameter:
469: . x - the vector
471: Note:
472: For a vector of dimension n, VecSet() computes
473: $ x[i] = alpha, for i=1,...,n,
474: so that all vector entries then equal the identical
475: scalar value, alpha. Use the more general routine
476: VecSetValues() to set different vector entries.
478: You CANNOT call this after you have called VecSetValues() but before you call
479: VecAssemblyBegin/End().
481: Level: beginner
483: .seealso VecSetValues(), VecSetValuesBlocked(), VecSetRandom()
485: @*/
486: PetscErrorCode VecSet(Vec x,PetscScalar alpha)
487: {
488: PetscReal val;
494: VecSetErrorIfLocked(x,1);
496: PetscLogEventBegin(VEC_Set,x,0,0,0);
497: (*x->ops->set)(x,alpha);
498: PetscLogEventEnd(VEC_Set,x,0,0,0);
499: PetscObjectStateIncrease((PetscObject)x);
501: /* norms can be simply set (if |alpha|*N not too large) */
502: val = PetscAbsScalar(alpha);
503: if (x->map->N == 0) {
504: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],0.0l);
505: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],0.0);
506: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],0.0);
507: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],0.0);
508: } else if (val > PETSC_MAX_REAL/x->map->N) {
509: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
510: } else {
511: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
512: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
513: val = PetscSqrtReal((PetscReal)x->map->N) * val;
514: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
515: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
516: }
517: return 0;
518: }
520: /*@
521: VecAXPY - Computes y = alpha x + y.
523: Logically Collective on Vec
525: Input Parameters:
526: + alpha - the scalar
527: - x, y - the vectors
529: Output Parameter:
530: . y - output vector
532: Level: intermediate
534: Notes:
535: x and y MUST be different vectors
536: This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
538: $ VecAXPY(y,alpha,x) y = alpha x + y
539: $ VecAYPX(y,beta,x) y = x + beta y
540: $ VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
541: $ VecWAXPY(w,alpha,x,y) w = alpha x + y
542: $ VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
543: $ VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
545: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPBYPCZ(), VecAXPBY()
546: @*/
547: PetscErrorCode VecAXPY(Vec y,PetscScalar alpha,Vec x)
548: {
554: VecCheckSameSize(x,3,y,1);
557: if (alpha == (PetscScalar)0.0) return 0;
558: VecSetErrorIfLocked(y,1);
560: VecLockReadPush(x);
561: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
562: (*y->ops->axpy)(y,alpha,x);
563: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
564: VecLockReadPop(x);
565: PetscObjectStateIncrease((PetscObject)y);
566: return 0;
567: }
569: /*@
570: VecAXPBY - Computes y = alpha x + beta y.
572: Logically Collective on Vec
574: Input Parameters:
575: + alpha,beta - the scalars
576: - x, y - the vectors
578: Output Parameter:
579: . y - output vector
581: Level: intermediate
583: Notes:
584: x and y MUST be different vectors
585: The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
587: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ()
588: @*/
589: PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
590: {
596: VecCheckSameSize(y,1,x,4);
600: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) return 0;
601: VecSetErrorIfLocked(y,1);
602: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
603: (*y->ops->axpby)(y,alpha,beta,x);
604: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
605: PetscObjectStateIncrease((PetscObject)y);
606: return 0;
607: }
609: /*@
610: VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
612: Logically Collective on Vec
614: Input Parameters:
615: + alpha,beta, gamma - the scalars
616: - x, y, z - the vectors
618: Output Parameter:
619: . z - output vector
621: Level: intermediate
623: Notes:
624: x, y and z must be different vectors
625: The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
627: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBY()
628: @*/
629: PetscErrorCode VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
630: {
639: VecCheckSameSize(x,1,y,5);
640: VecCheckSameSize(x,1,z,6);
646: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) return 0;
647: VecSetErrorIfLocked(z,1);
649: PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
650: (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
651: PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
652: PetscObjectStateIncrease((PetscObject)z);
653: return 0;
654: }
656: /*@
657: VecAYPX - Computes y = x + beta y.
659: Logically Collective on Vec
661: Input Parameters:
662: + beta - the scalar
663: - x, y - the vectors
665: Output Parameter:
666: . y - output vector
668: Level: intermediate
670: Notes:
671: x and y MUST be different vectors
672: The implementation is optimized for beta of -1.0, 0.0, and 1.0
674: .seealso: VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
675: @*/
676: PetscErrorCode VecAYPX(Vec y,PetscScalar beta,Vec x)
677: {
683: VecCheckSameSize(x,1,y,3);
686: VecSetErrorIfLocked(y,1);
688: PetscLogEventBegin(VEC_AYPX,x,y,0,0);
689: (*y->ops->aypx)(y,beta,x);
690: PetscLogEventEnd(VEC_AYPX,x,y,0,0);
691: PetscObjectStateIncrease((PetscObject)y);
692: return 0;
693: }
695: /*@
696: VecWAXPY - Computes w = alpha x + y.
698: Logically Collective on Vec
700: Input Parameters:
701: + alpha - the scalar
702: - x, y - the vectors
704: Output Parameter:
705: . w - the result
707: Level: intermediate
709: Notes:
710: w cannot be either x or y, but x and y can be the same
711: The implementation is optimzed for alpha of -1.0, 0.0, and 1.0
713: .seealso: VecAXPY(), VecAYPX(), VecAXPBY(), VecMAXPY(), VecAXPBYPCZ()
714: @*/
715: PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
716: {
725: VecCheckSameSize(x,3,y,4);
726: VecCheckSameSize(x,3,w,1);
730: VecSetErrorIfLocked(w,1);
732: PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
733: (*w->ops->waxpy)(w,alpha,x,y);
734: PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
735: PetscObjectStateIncrease((PetscObject)w);
736: return 0;
737: }
739: /*@C
740: VecSetValues - Inserts or adds values into certain locations of a vector.
742: Not Collective
744: Input Parameters:
745: + x - vector to insert in
746: . ni - number of elements to add
747: . ix - indices where to add
748: . y - array of values
749: - iora - either INSERT_VALUES or ADD_VALUES, where
750: ADD_VALUES adds values to any existing entries, and
751: INSERT_VALUES replaces existing entries with new values
753: Notes:
754: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
756: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
757: options cannot be mixed without intervening calls to the assembly
758: routines.
760: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
761: MUST be called after all calls to VecSetValues() have been completed.
763: VecSetValues() uses 0-based indices in Fortran as well as in C.
765: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
766: negative indices may be passed in ix. These rows are
767: simply ignored. This allows easily inserting element load matrices
768: with homogeneous Dirchlet boundary conditions that you don't want represented
769: in the vector.
771: Level: beginner
773: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
774: VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
775: @*/
776: PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
777: {
780: if (!ni) return 0;
785: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
786: (*x->ops->setvalues)(x,ni,ix,y,iora);
787: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
788: PetscObjectStateIncrease((PetscObject)x);
789: return 0;
790: }
792: /*@C
793: VecGetValues - Gets values from certain locations of a vector. Currently
794: can only get values on the same processor
796: Not Collective
798: Input Parameters:
799: + x - vector to get values from
800: . ni - number of elements to get
801: - ix - indices where to get them from (in global 1d numbering)
803: Output Parameter:
804: . y - array of values
806: Notes:
807: The user provides the allocated array y; it is NOT allocated in this routine
809: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
811: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
813: VecGetValues() uses 0-based indices in Fortran as well as in C.
815: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
816: negative indices may be passed in ix. These rows are
817: simply ignored.
819: Level: beginner
821: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues()
822: @*/
823: PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
824: {
826: if (!ni) return 0;
830: (*x->ops->getvalues)(x,ni,ix,y);
831: return 0;
832: }
834: /*@C
835: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
837: Not Collective
839: Input Parameters:
840: + x - vector to insert in
841: . ni - number of blocks to add
842: . ix - indices where to add in block count, rather than element count
843: . y - array of values
844: - iora - either INSERT_VALUES or ADD_VALUES, where
845: ADD_VALUES adds values to any existing entries, and
846: INSERT_VALUES replaces existing entries with new values
848: Notes:
849: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
850: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
852: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
853: options cannot be mixed without intervening calls to the assembly
854: routines.
856: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
857: MUST be called after all calls to VecSetValuesBlocked() have been completed.
859: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
861: Negative indices may be passed in ix, these rows are
862: simply ignored. This allows easily inserting element load matrices
863: with homogeneous Dirchlet boundary conditions that you don't want represented
864: in the vector.
866: Level: intermediate
868: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
869: VecSetValues()
870: @*/
871: PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
872: {
875: if (!ni) return 0;
880: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
881: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
882: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
883: PetscObjectStateIncrease((PetscObject)x);
884: return 0;
885: }
887: /*@C
888: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
889: using a local ordering of the nodes.
891: Not Collective
893: Input Parameters:
894: + x - vector to insert in
895: . ni - number of elements to add
896: . ix - indices where to add
897: . y - array of values
898: - iora - either INSERT_VALUES or ADD_VALUES, where
899: ADD_VALUES adds values to any existing entries, and
900: INSERT_VALUES replaces existing entries with new values
902: Level: intermediate
904: Notes:
905: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
907: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
908: options cannot be mixed without intervening calls to the assembly
909: routines.
911: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
912: MUST be called after all calls to VecSetValuesLocal() have been completed.
914: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
916: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
917: VecSetValuesBlockedLocal()
918: @*/
919: PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
920: {
921: PetscInt lixp[128],*lix = lixp;
925: if (!ni) return 0;
930: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
931: if (!x->ops->setvalueslocal) {
932: if (x->map->mapping) {
933: if (ni > 128) {
934: PetscMalloc1(ni,&lix);
935: }
936: ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
937: (*x->ops->setvalues)(x,ni,lix,y,iora);
938: if (ni > 128) {
939: PetscFree(lix);
940: }
941: } else {
942: (*x->ops->setvalues)(x,ni,ix,y,iora);
943: }
944: } else {
945: (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
946: }
947: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
948: PetscObjectStateIncrease((PetscObject)x);
949: return 0;
950: }
952: /*@
953: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
954: using a local ordering of the nodes.
956: Not Collective
958: Input Parameters:
959: + x - vector to insert in
960: . ni - number of blocks to add
961: . ix - indices where to add in block count, not element count
962: . y - array of values
963: - iora - either INSERT_VALUES or ADD_VALUES, where
964: ADD_VALUES adds values to any existing entries, and
965: INSERT_VALUES replaces existing entries with new values
967: Level: intermediate
969: Notes:
970: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
971: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
973: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
974: options cannot be mixed without intervening calls to the assembly
975: routines.
977: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
978: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
980: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
982: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
983: VecSetLocalToGlobalMapping()
984: @*/
985: PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
986: {
987: PetscInt lixp[128],*lix = lixp;
991: if (!ni) return 0;
995: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
996: if (x->map->mapping) {
997: if (ni > 128) {
998: PetscMalloc1(ni,&lix);
999: }
1000: ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
1001: (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1002: if (ni > 128) {
1003: PetscFree(lix);
1004: }
1005: } else {
1006: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
1007: }
1008: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1009: PetscObjectStateIncrease((PetscObject)x);
1010: return 0;
1011: }
1013: /*@
1014: VecMTDot - Computes indefinite vector multiple dot products.
1015: That is, it does NOT use the complex conjugate.
1017: Collective on Vec
1019: Input Parameters:
1020: + x - one vector
1021: . nv - number of vectors
1022: - y - array of vectors. Note that vectors are pointers
1024: Output Parameter:
1025: . val - array of the dot products
1027: Notes for Users of Complex Numbers:
1028: For complex vectors, VecMTDot() computes the indefinite form
1029: $ val = (x,y) = y^T x,
1030: where y^T denotes the transpose of y.
1032: Use VecMDot() for the inner product
1033: $ val = (x,y) = y^H x,
1034: where y^H denotes the conjugate transpose of y.
1036: Level: intermediate
1038: .seealso: VecMDot(), VecTDot()
1039: @*/
1040: PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1041: {
1044: if (!nv) return 0;
1051: VecCheckSameSize(x,1,*y,3);
1053: PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1054: (*x->ops->mtdot)(x,nv,y,val);
1055: PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1056: return 0;
1057: }
1059: /*@
1060: VecMDot - Computes vector multiple dot products.
1062: Collective on Vec
1064: Input Parameters:
1065: + x - one vector
1066: . nv - number of vectors
1067: - y - array of vectors.
1069: Output Parameter:
1070: . val - array of the dot products (does not allocate the array)
1072: Notes for Users of Complex Numbers:
1073: For complex vectors, VecMDot() computes
1074: $ val = (x,y) = y^H x,
1075: where y^H denotes the conjugate transpose of y.
1077: Use VecMTDot() for the indefinite form
1078: $ val = (x,y) = y^T x,
1079: where y^T denotes the transpose of y.
1081: Level: intermediate
1083: .seealso: VecMTDot(), VecDot()
1084: @*/
1085: PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1086: {
1089: if (!nv) return 0;
1097: VecCheckSameSize(x,1,*y,3);
1099: PetscLogEventBegin(VEC_MDot,x,*y,0,0);
1100: (*x->ops->mdot)(x,nv,y,val);
1101: PetscLogEventEnd(VEC_MDot,x,*y,0,0);
1102: return 0;
1103: }
1105: /*@
1106: VecMAXPY - Computes y = y + sum alpha[i] x[i]
1108: Logically Collective on Vec
1110: Input Parameters:
1111: + nv - number of scalars and x-vectors
1112: . alpha - array of scalars
1113: . y - one vector
1114: - x - array of vectors
1116: Level: intermediate
1118: Notes:
1119: y cannot be any of the x vectors
1121: .seealso: VecAYPX(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
1122: @*/
1123: PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1124: {
1125: PetscInt i;
1126: PetscBool nonzero;
1130: if (!nv) return 0;
1138: VecCheckSameSize(y,1,*x,4);
1140: for (i=0, nonzero = PETSC_FALSE; i<nv && !nonzero; i++) nonzero = (PetscBool)(nonzero || alpha[i] != (PetscScalar)0.0);
1141: if (!nonzero) return 0;
1142: VecSetErrorIfLocked(y,1);
1143: PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1144: (*y->ops->maxpy)(y,nv,alpha,x);
1145: PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1146: PetscObjectStateIncrease((PetscObject)y);
1147: return 0;
1148: }
1150: /*@
1151: VecConcatenate - Creates a new vector that is a vertical concatenation of all the given array of vectors
1152: in the order they appear in the array. The concatenated vector resides on the same
1153: communicator and is the same type as the source vectors.
1155: Collective on X
1157: Input Parameters:
1158: + nx - number of vectors to be concatenated
1159: - X - array containing the vectors to be concatenated in the order of concatenation
1161: Output Parameters:
1162: + Y - concatenated vector
1163: - x_is - array of index sets corresponding to the concatenated components of Y (NULL if not needed)
1165: Notes:
1166: Concatenation is similar to the functionality of a VecNest object; they both represent combination of
1167: different vector spaces. However, concatenated vectors do not store any information about their
1168: sub-vectors and own their own data. Consequently, this function provides index sets to enable the
1169: manipulation of data in the concatenated vector that corresponds to the original components at creation.
1171: This is a useful tool for outer loop algorithms, particularly constrained optimizers, where the solver
1172: has to operate on combined vector spaces and cannot utilize VecNest objects due to incompatibility with
1173: bound projections.
1175: Level: advanced
1177: .seealso: VECNEST, VECSCATTER, VecScatterCreate()
1178: @*/
1179: PetscErrorCode VecConcatenate(PetscInt nx, const Vec X[], Vec *Y, IS *x_is[])
1180: {
1181: MPI_Comm comm;
1182: VecType vec_type;
1183: Vec Ytmp, Xtmp;
1184: IS *is_tmp;
1185: PetscInt i, shift=0, Xnl, Xng, Xbegin;
1192: if ((*X)->ops->concatenate) {
1193: /* use the dedicated concatenation function if available */
1194: (*(*X)->ops->concatenate)(nx,X,Y,x_is);
1195: } else {
1196: /* loop over vectors and start creating IS */
1197: comm = PetscObjectComm((PetscObject)(*X));
1198: VecGetType(*X, &vec_type);
1199: PetscMalloc1(nx, &is_tmp);
1200: for (i=0; i<nx; i++) {
1201: VecGetSize(X[i], &Xng);
1202: VecGetLocalSize(X[i], &Xnl);
1203: VecGetOwnershipRange(X[i], &Xbegin, NULL);
1204: ISCreateStride(comm, Xnl, shift + Xbegin, 1, &is_tmp[i]);
1205: shift += Xng;
1206: }
1207: /* create the concatenated vector */
1208: VecCreate(comm, &Ytmp);
1209: VecSetType(Ytmp, vec_type);
1210: VecSetSizes(Ytmp, PETSC_DECIDE, shift);
1211: VecSetUp(Ytmp);
1212: /* copy data from X array to Y and return */
1213: for (i=0; i<nx; i++) {
1214: VecGetSubVector(Ytmp, is_tmp[i], &Xtmp);
1215: VecCopy(X[i], Xtmp);
1216: VecRestoreSubVector(Ytmp, is_tmp[i], &Xtmp);
1217: }
1218: *Y = Ytmp;
1219: if (x_is) {
1220: *x_is = is_tmp;
1221: } else {
1222: for (i=0; i<nx; i++) {
1223: ISDestroy(&is_tmp[i]);
1224: }
1225: PetscFree(is_tmp);
1226: }
1227: }
1228: return 0;
1229: }
1231: /* A helper function for VecGetSubVector to check if we can implement it with no-copy (i.e. the subvector shares
1232: memory with the original vector), and the block size of the subvector.
1234: Input Parameters:
1235: + X - the original vector
1236: - is - the index set of the subvector
1238: Output Parameters:
1239: + contig - PETSC_TRUE if the index set refers to contiguous entries on this process, else PETSC_FALSE
1240: . start - start of contiguous block, as an offset from the start of the ownership range of the original vector
1241: - blocksize - the block size of the subvector
1243: */
1244: PetscErrorCode VecGetSubVectorContiguityAndBS_Private(Vec X,IS is,PetscBool *contig,PetscInt *start,PetscInt *blocksize)
1245: {
1246: PetscInt gstart,gend,lstart;
1247: PetscBool red[2] = {PETSC_TRUE/*contiguous*/,PETSC_TRUE/*validVBS*/};
1248: PetscInt n,N,ibs,vbs,bs = -1;
1250: ISGetLocalSize(is,&n);
1251: ISGetSize(is,&N);
1252: ISGetBlockSize(is,&ibs);
1253: VecGetBlockSize(X,&vbs);
1254: VecGetOwnershipRange(X,&gstart,&gend);
1255: ISContiguousLocal(is,gstart,gend,&lstart,&red[0]);
1256: /* block size is given by IS if ibs > 1; otherwise, check the vector */
1257: if (ibs > 1) {
1258: MPIU_Allreduce(MPI_IN_PLACE,red,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1259: bs = ibs;
1260: } else {
1261: if (n%vbs || vbs == 1) red[1] = PETSC_FALSE; /* this process invalidate the collectiveness of block size */
1262: MPIU_Allreduce(MPI_IN_PLACE,red,2,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1263: if (red[0] && red[1]) bs = vbs; /* all processes have a valid block size and the access will be contiguous */
1264: }
1266: *contig = red[0];
1267: *start = lstart;
1268: *blocksize = bs;
1269: return 0;
1270: }
1272: /* A helper function for VecGetSubVector, to be used when we have to build a standalone subvector through VecScatter
1274: Input Parameters:
1275: + X - the original vector
1276: . is - the index set of the subvector
1277: - bs - the block size of the subvector, gotten from VecGetSubVectorContiguityAndBS_Private()
1279: Output Parameters:
1280: . Z - the subvector, which will compose the VecScatter context on output
1281: */
1282: PetscErrorCode VecGetSubVectorThroughVecScatter_Private(Vec X,IS is,PetscInt bs,Vec *Z)
1283: {
1284: PetscInt n,N;
1285: VecScatter vscat;
1286: Vec Y;
1288: ISGetLocalSize(is,&n);
1289: ISGetSize(is,&N);
1290: VecCreate(PetscObjectComm((PetscObject)is),&Y);
1291: VecSetSizes(Y,n,N);
1292: VecSetBlockSize(Y,bs);
1293: VecSetType(Y,((PetscObject)X)->type_name);
1294: VecScatterCreate(X,is,Y,NULL,&vscat);
1295: VecScatterBegin(vscat,X,Y,INSERT_VALUES,SCATTER_FORWARD);
1296: VecScatterEnd(vscat,X,Y,INSERT_VALUES,SCATTER_FORWARD);
1297: PetscObjectCompose((PetscObject)Y,"VecGetSubVector_Scatter",(PetscObject)vscat);
1298: VecScatterDestroy(&vscat);
1299: *Z = Y;
1300: return 0;
1301: }
1303: /*@
1304: VecGetSubVector - Gets a vector representing part of another vector
1306: Collective on X and IS
1308: Input Parameters:
1309: + X - vector from which to extract a subvector
1310: - is - index set representing portion of X to extract
1312: Output Parameter:
1313: . Y - subvector corresponding to is
1315: Level: advanced
1317: Notes:
1318: The subvector Y should be returned with VecRestoreSubVector().
1319: X and is must be defined on the same communicator
1321: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1322: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1323: 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.
1325: .seealso: MatCreateSubMatrix()
1326: @*/
1327: PetscErrorCode VecGetSubVector(Vec X,IS is,Vec *Y)
1328: {
1329: Vec Z;
1335: if (X->ops->getsubvector) {
1336: (*X->ops->getsubvector)(X,is,&Z);
1337: } else { /* Default implementation currently does no caching */
1338: PetscBool contig;
1339: PetscInt n,N,start,bs;
1341: ISGetLocalSize(is,&n);
1342: ISGetSize(is,&N);
1343: VecGetSubVectorContiguityAndBS_Private(X,is,&contig,&start,&bs);
1344: if (contig) { /* We can do a no-copy implementation */
1345: const PetscScalar *x;
1346: PetscInt state = 0;
1347: PetscBool isstd,iscuda,iship;
1349: PetscObjectTypeCompareAny((PetscObject)X,&isstd,VECSEQ,VECMPI,VECSTANDARD,"");
1350: PetscObjectTypeCompareAny((PetscObject)X,&iscuda,VECSEQCUDA,VECMPICUDA,"");
1351: PetscObjectTypeCompareAny((PetscObject)X,&iship,VECSEQHIP,VECMPIHIP,"");
1352: if (iscuda) {
1353: #if defined(PETSC_HAVE_CUDA)
1354: const PetscScalar *x_d;
1355: PetscMPIInt size;
1356: PetscOffloadMask flg;
1358: VecCUDAGetArrays_Private(X,&x,&x_d,&flg);
1361: if (x) x += start;
1362: if (x_d) x_d += start;
1363: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1364: if (size == 1) {
1365: VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)X),bs,n,x,x_d,&Z);
1366: } else {
1367: VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)X),bs,n,N,x,x_d,&Z);
1368: }
1369: Z->offloadmask = flg;
1370: #endif
1371: } else if (iship) {
1372: #if defined(PETSC_HAVE_HIP)
1373: const PetscScalar *x_d;
1374: PetscMPIInt size;
1375: PetscOffloadMask flg;
1377: VecHIPGetArrays_Private(X,&x,&x_d,&flg);
1380: if (x) x += start;
1381: if (x_d) x_d += start;
1382: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1383: if (size == 1) {
1384: VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)X),bs,n,x,x_d,&Z);
1385: } else {
1386: VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)X),bs,n,N,x,x_d,&Z);
1387: }
1388: Z->offloadmask = flg;
1389: #endif
1390: } else if (isstd) {
1391: PetscMPIInt size;
1393: MPI_Comm_size(PetscObjectComm((PetscObject)X),&size);
1394: VecGetArrayRead(X,&x);
1395: if (x) x += start;
1396: if (size == 1) {
1397: VecCreateSeqWithArray(PetscObjectComm((PetscObject)X),bs,n,x,&Z);
1398: } else {
1399: VecCreateMPIWithArray(PetscObjectComm((PetscObject)X),bs,n,N,x,&Z);
1400: }
1401: VecRestoreArrayRead(X,&x);
1402: } else { /* default implementation: use place array */
1403: VecGetArrayRead(X,&x);
1404: VecCreate(PetscObjectComm((PetscObject)X),&Z);
1405: VecSetType(Z,((PetscObject)X)->type_name);
1406: VecSetSizes(Z,n,N);
1407: VecSetBlockSize(Z,bs);
1408: VecPlaceArray(Z,x ? x+start : NULL);
1409: VecRestoreArrayRead(X,&x);
1410: }
1412: /* this is relevant only in debug mode */
1413: VecLockGet(X,&state);
1414: if (state) {
1415: VecLockReadPush(Z);
1416: }
1417: Z->ops->placearray = NULL;
1418: Z->ops->replacearray = NULL;
1419: } else { /* Have to create a scatter and do a copy */
1420: VecGetSubVectorThroughVecScatter_Private(X,is,bs,&Z);
1421: }
1422: }
1423: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1424: if (VecGetSubVectorSavedStateId < 0) PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);
1425: PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);
1426: *Y = Z;
1427: return 0;
1428: }
1430: /*@
1431: VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1433: Collective on IS
1435: Input Parameters:
1436: + X - vector from which subvector was obtained
1437: . is - index set representing the subset of X
1438: - Y - subvector being restored
1440: Level: advanced
1442: .seealso: VecGetSubVector()
1443: @*/
1444: PetscErrorCode VecRestoreSubVector(Vec X,IS is,Vec *Y)
1445: {
1446: PETSC_UNUSED PetscObjectState dummystate = 0;
1447: PetscBool unchanged;
1455: if (X->ops->restoresubvector) {
1456: (*X->ops->restoresubvector)(X,is,Y);
1457: } else {
1458: PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,unchanged);
1459: if (!unchanged) { /* If Y's state has not changed since VecGetSubVector(), we only need to destroy Y */
1460: VecScatter scatter;
1461: PetscInt state;
1463: VecLockGet(X,&state);
1466: PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);
1467: if (scatter) {
1468: VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1469: VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1470: } else {
1471: PetscBool iscuda,iship;
1472: PetscObjectTypeCompareAny((PetscObject)X,&iscuda,VECSEQCUDA,VECMPICUDA,"");
1473: PetscObjectTypeCompareAny((PetscObject)X,&iship,VECSEQHIP,VECMPIHIP,"");
1475: if (iscuda) {
1476: #if defined(PETSC_HAVE_CUDA)
1477: PetscOffloadMask ymask = (*Y)->offloadmask;
1479: /* The offloadmask of X dictates where to move memory
1480: If X GPU data is valid, then move Y data on GPU if needed
1481: Otherwise, move back to the CPU */
1482: switch (X->offloadmask) {
1483: case PETSC_OFFLOAD_BOTH:
1484: if (ymask == PETSC_OFFLOAD_CPU) {
1485: VecCUDAResetArray(*Y);
1486: } else if (ymask == PETSC_OFFLOAD_GPU) {
1487: X->offloadmask = PETSC_OFFLOAD_GPU;
1488: }
1489: break;
1490: case PETSC_OFFLOAD_GPU:
1491: if (ymask == PETSC_OFFLOAD_CPU) {
1492: VecCUDAResetArray(*Y);
1493: }
1494: break;
1495: case PETSC_OFFLOAD_CPU:
1496: if (ymask == PETSC_OFFLOAD_GPU) {
1497: VecResetArray(*Y);
1498: }
1499: break;
1500: case PETSC_OFFLOAD_UNALLOCATED:
1501: case PETSC_OFFLOAD_KOKKOS:
1502: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen");
1503: }
1504: #endif
1505: } else if (iship) {
1506: #if defined(PETSC_HAVE_HIP)
1507: PetscOffloadMask ymask = (*Y)->offloadmask;
1509: /* The offloadmask of X dictates where to move memory
1510: If X GPU data is valid, then move Y data on GPU if needed
1511: Otherwise, move back to the CPU */
1512: switch (X->offloadmask) {
1513: case PETSC_OFFLOAD_BOTH:
1514: if (ymask == PETSC_OFFLOAD_CPU) {
1515: VecHIPResetArray(*Y);
1516: } else if (ymask == PETSC_OFFLOAD_GPU) {
1517: X->offloadmask = PETSC_OFFLOAD_GPU;
1518: }
1519: break;
1520: case PETSC_OFFLOAD_GPU:
1521: if (ymask == PETSC_OFFLOAD_CPU) {
1522: VecHIPResetArray(*Y);
1523: }
1524: break;
1525: case PETSC_OFFLOAD_CPU:
1526: if (ymask == PETSC_OFFLOAD_GPU) {
1527: VecResetArray(*Y);
1528: }
1529: break;
1530: case PETSC_OFFLOAD_UNALLOCATED:
1531: case PETSC_OFFLOAD_KOKKOS:
1532: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen");
1533: }
1534: #endif
1535: } else {
1536: /* If OpenCL vecs updated the device memory, this triggers a copy on the CPU */
1537: VecResetArray(*Y);
1538: }
1539: PetscObjectStateIncrease((PetscObject)X);
1540: }
1541: }
1542: }
1543: VecDestroy(Y);
1544: return 0;
1545: }
1547: /*@
1548: VecGetLocalVectorRead - Maps the local portion of a vector into a
1549: vector. You must call VecRestoreLocalVectorRead() when the local
1550: vector is no longer needed.
1552: Not collective.
1554: Input parameter:
1555: . v - The vector for which the local vector is desired.
1557: Output parameter:
1558: . w - Upon exit this contains the local vector.
1560: Level: beginner
1562: Notes:
1563: This function is similar to VecGetArrayRead() which maps the local
1564: portion into a raw pointer. VecGetLocalVectorRead() is usually
1565: almost as efficient as VecGetArrayRead() but in certain circumstances
1566: VecGetLocalVectorRead() can be much more efficient than
1567: VecGetArrayRead(). This is because the construction of a contiguous
1568: array representing the vector data required by VecGetArrayRead() can
1569: be an expensive operation for certain vector types. For example, for
1570: GPU vectors VecGetArrayRead() requires that the data between device
1571: and host is synchronized.
1573: Unlike VecGetLocalVector(), this routine is not collective and
1574: preserves cached information.
1576: .seealso: VecRestoreLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1577: @*/
1578: PetscErrorCode VecGetLocalVectorRead(Vec v,Vec w)
1579: {
1580: PetscScalar *a;
1584: VecCheckSameLocalSize(v,1,w,2);
1585: if (v->ops->getlocalvectorread) {
1586: (*v->ops->getlocalvectorread)(v,w);
1587: } else {
1588: VecGetArrayRead(v,(const PetscScalar**)&a);
1589: VecPlaceArray(w,a);
1590: }
1591: PetscObjectStateIncrease((PetscObject)w);
1592: VecLockReadPush(v);
1593: VecLockReadPush(w);
1594: return 0;
1595: }
1597: /*@
1598: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1599: previously mapped into a vector using VecGetLocalVectorRead().
1601: Not collective.
1603: Input parameter:
1604: + v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
1605: - w - The vector into which the local portion of v was mapped.
1607: Level: beginner
1609: .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1610: @*/
1611: PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
1612: {
1613: PetscScalar *a;
1617: if (v->ops->restorelocalvectorread) {
1618: (*v->ops->restorelocalvectorread)(v,w);
1619: } else {
1620: VecGetArrayRead(w,(const PetscScalar**)&a);
1621: VecRestoreArrayRead(v,(const PetscScalar**)&a);
1622: VecResetArray(w);
1623: }
1624: VecLockReadPop(v);
1625: VecLockReadPop(w);
1626: PetscObjectStateIncrease((PetscObject)w);
1627: return 0;
1628: }
1630: /*@
1631: VecGetLocalVector - Maps the local portion of a vector into a
1632: vector.
1634: Collective on v, not collective on w.
1636: Input parameter:
1637: . v - The vector for which the local vector is desired.
1639: Output parameter:
1640: . w - Upon exit this contains the local vector.
1642: Level: beginner
1644: Notes:
1645: This function is similar to VecGetArray() which maps the local
1646: portion into a raw pointer. VecGetLocalVector() is usually about as
1647: efficient as VecGetArray() but in certain circumstances
1648: VecGetLocalVector() can be much more efficient than VecGetArray().
1649: This is because the construction of a contiguous array representing
1650: the vector data required by VecGetArray() can be an expensive
1651: operation for certain vector types. For example, for GPU vectors
1652: VecGetArray() requires that the data between device and host is
1653: synchronized.
1655: .seealso: VecRestoreLocalVector(), VecGetLocalVectorRead(), VecGetArrayRead(), VecGetArray()
1656: @*/
1657: PetscErrorCode VecGetLocalVector(Vec v,Vec w)
1658: {
1659: PetscScalar *a;
1663: VecCheckSameLocalSize(v,1,w,2);
1664: if (v->ops->getlocalvector) {
1665: (*v->ops->getlocalvector)(v,w);
1666: } else {
1667: VecGetArray(v,&a);
1668: VecPlaceArray(w,a);
1669: }
1670: PetscObjectStateIncrease((PetscObject)w);
1671: return 0;
1672: }
1674: /*@
1675: VecRestoreLocalVector - Unmaps the local portion of a vector
1676: previously mapped into a vector using VecGetLocalVector().
1678: Logically collective.
1680: Input parameter:
1681: + v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
1682: - w - The vector into which the local portion of v was mapped.
1684: Level: beginner
1686: .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
1687: @*/
1688: PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
1689: {
1690: PetscScalar *a;
1694: if (v->ops->restorelocalvector) {
1695: (*v->ops->restorelocalvector)(v,w);
1696: } else {
1697: VecGetArray(w,&a);
1698: VecRestoreArray(v,&a);
1699: VecResetArray(w);
1700: }
1701: PetscObjectStateIncrease((PetscObject)w);
1702: PetscObjectStateIncrease((PetscObject)v);
1703: return 0;
1704: }
1706: /*@C
1707: VecGetArray - Returns a pointer to a contiguous array that contains this
1708: processor's portion of the vector data. For the standard PETSc
1709: vectors, VecGetArray() returns a pointer to the local data array and
1710: does not use any copies. If the underlying vector data is not stored
1711: in a contiguous array this routine will copy the data to a contiguous
1712: array and return a pointer to that. You MUST call VecRestoreArray()
1713: when you no longer need access to the array.
1715: Logically Collective on Vec
1717: Input Parameter:
1718: . x - the vector
1720: Output Parameter:
1721: . a - location to put pointer to the array
1723: Fortran Note:
1724: This routine is used differently from Fortran 77
1725: $ Vec x
1726: $ PetscScalar x_array(1)
1727: $ PetscOffset i_x
1728: $ PetscErrorCode ierr
1729: $ call VecGetArray(x,x_array,i_x,ierr)
1730: $
1731: $ Access first local entry in vector with
1732: $ value = x_array(i_x + 1)
1733: $
1734: $ ...... other code
1735: $ call VecRestoreArray(x,x_array,i_x,ierr)
1736: For Fortran 90 see VecGetArrayF90()
1738: See the Fortran chapter of the users manual and
1739: petsc/src/snes/tutorials/ex5f.F for details.
1741: Level: beginner
1743: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1744: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1745: @*/
1746: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1747: {
1749: VecSetErrorIfLocked(x,1);
1750: if (x->ops->getarray) { /* The if-else order matters! VECNEST, VECCUDA etc should have ops->getarray while VECCUDA etc are petscnative */
1751: (*x->ops->getarray)(x,a);
1752: } else if (x->petscnative) { /* VECSTANDARD */
1753: *a = *((PetscScalar**)x->data);
1754: } else SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
1755: return 0;
1756: }
1758: /*@C
1759: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1761: Logically Collective on Vec
1763: Input Parameters:
1764: + x - the vector
1765: - a - location of pointer to array obtained from VecGetArray()
1767: Level: beginner
1769: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1770: VecGetArrayPair(), VecRestoreArrayPair()
1771: @*/
1772: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
1773: {
1775: if (x->ops->restorearray) { /* VECNEST, VECCUDA etc */
1776: (*x->ops->restorearray)(x,a);
1777: } else if (x->petscnative) { /* VECSTANDARD */
1778: /* nothing */
1779: } else SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot restore array for vector type \"%s\"",((PetscObject)x)->type_name);
1780: if (a) *a = NULL;
1781: PetscObjectStateIncrease((PetscObject)x);
1782: return 0;
1783: }
1784: /*@C
1785: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1787: Not Collective
1789: Input Parameter:
1790: . x - the vector
1792: Output Parameter:
1793: . a - the array
1795: Level: beginner
1797: Notes:
1798: The array must be returned using a matching call to VecRestoreArrayRead().
1800: Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1802: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1803: implementations may require a copy, but must such implementations should cache the contiguous representation so that
1804: only one copy is performed when this routine is called multiple times in sequence.
1806: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1807: @*/
1808: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1809: {
1811: if (x->ops->getarray) { /* VECNEST, VECCUDA, VECKOKKOS etc */
1812: (*x->ops->getarray)(x,(PetscScalar**)a);
1813: } else if (x->petscnative) { /* VECSTANDARD */
1814: *a = *((PetscScalar**)x->data);
1815: } else SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array read for vector type \"%s\"",((PetscObject)x)->type_name);
1816: return 0;
1817: }
1819: /*@C
1820: VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
1822: Not Collective
1824: Input Parameters:
1825: + vec - the vector
1826: - array - the array
1828: Level: beginner
1830: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1831: @*/
1832: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
1833: {
1835: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS etc */
1836: /* nothing */
1837: } else if (x->ops->restorearrayread) { /* VECNEST */
1838: (*x->ops->restorearrayread)(x,a);
1839: } else { /* No one? */
1840: (*x->ops->restorearray)(x,(PetscScalar**)a);
1841: }
1842: if (a) *a = NULL;
1843: return 0;
1844: }
1846: /*@C
1847: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contains this
1848: processor's portion of the vector data. The values in this array are NOT valid, the routine calling this
1849: routine is responsible for putting values into the array; any values it does not set will be invalid
1851: Logically Collective on Vec
1853: Input Parameter:
1854: . x - the vector
1856: Output Parameter:
1857: . a - location to put pointer to the array
1859: Level: intermediate
1861: This is for vectors associate with GPUs, the vector is not copied up before giving access. If you need correct
1862: values in the array use VecGetArray()
1864: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1865: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArray(), VecRestoreArrayWrite()
1866: @*/
1867: PetscErrorCode VecGetArrayWrite(Vec x,PetscScalar **a)
1868: {
1870: VecSetErrorIfLocked(x,1);
1871: if (x->ops->getarraywrite) {
1872: (*x->ops->getarraywrite)(x,a);
1873: } else {
1874: VecGetArray(x,a);
1875: }
1876: return 0;
1877: }
1879: /*@C
1880: VecRestoreArrayWrite - Restores a vector after VecGetArrayWrite() has been called.
1882: Logically Collective on Vec
1884: Input Parameters:
1885: + x - the vector
1886: - a - location of pointer to array obtained from VecGetArray()
1888: Level: beginner
1890: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1891: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite()
1892: @*/
1893: PetscErrorCode VecRestoreArrayWrite(Vec x,PetscScalar **a)
1894: {
1896: if (x->ops->restorearraywrite) {
1897: (*x->ops->restorearraywrite)(x,a);
1898: } else if (x->ops->restorearray) {
1899: (*x->ops->restorearray)(x,a);
1900: }
1901: if (a) *a = NULL;
1902: PetscObjectStateIncrease((PetscObject)x);
1903: return 0;
1904: }
1906: /*@C
1907: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1908: that were created by a call to VecDuplicateVecs(). You MUST call
1909: VecRestoreArrays() when you no longer need access to the array.
1911: Logically Collective on Vec
1913: Input Parameters:
1914: + x - the vectors
1915: - n - the number of vectors
1917: Output Parameter:
1918: . a - location to put pointer to the array
1920: Fortran Note:
1921: This routine is not supported in Fortran.
1923: Level: intermediate
1925: .seealso: VecGetArray(), VecRestoreArrays()
1926: @*/
1927: PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1928: {
1929: PetscInt i;
1930: PetscScalar **q;
1936: PetscMalloc1(n,&q);
1937: for (i=0; i<n; ++i) {
1938: VecGetArray(x[i],&q[i]);
1939: }
1940: *a = q;
1941: return 0;
1942: }
1944: /*@C
1945: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1946: has been called.
1948: Logically Collective on Vec
1950: Input Parameters:
1951: + x - the vector
1952: . n - the number of vectors
1953: - a - location of pointer to arrays obtained from VecGetArrays()
1955: Notes:
1956: For regular PETSc vectors this routine does not involve any copies. For
1957: any special vectors that do not store local vector data in a contiguous
1958: array, this routine will copy the data back into the underlying
1959: vector data structure from the arrays obtained with VecGetArrays().
1961: Fortran Note:
1962: This routine is not supported in Fortran.
1964: Level: intermediate
1966: .seealso: VecGetArrays(), VecRestoreArray()
1967: @*/
1968: PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1969: {
1970: PetscInt i;
1971: PetscScalar **q = *a;
1977: for (i=0; i<n; ++i) {
1978: VecRestoreArray(x[i],&q[i]);
1979: }
1980: PetscFree(q);
1981: return 0;
1982: }
1984: /*@C
1985: VecGetArrayAndMemType - Like VecGetArray(), but if this is a standard device vector (e.g., VECCUDA), the returned pointer will be a device
1986: pointer to the device memory that contains this processor's portion of the vector data. Device data is guaranteed to have the latest value.
1987: Otherwise, when this is a host vector (e.g., VECMPI), this routine functions the same as VecGetArray() and returns a host pointer.
1989: For VECKOKKOS, if Kokkos is configured without device (e.g., use serial or openmp), per this function, the vector works like VECSEQ/VECMPI;
1990: otherwise, it works like VECCUDA or VECHIP etc.
1992: Logically Collective on Vec
1994: Input Parameter:
1995: . x - the vector
1997: Output Parameters:
1998: + a - location to put pointer to the array
1999: - mtype - memory type of the array
2001: Level: beginner
2003: .seealso: VecRestoreArrayAndMemType(), VecGetArrayReadAndMemType(), VecGetArrayWriteAndMemType(), VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(),
2004: VecPlaceArray(), VecGetArray2d(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
2005: @*/
2006: PetscErrorCode VecGetArrayAndMemType(Vec x,PetscScalar **a,PetscMemType *mtype)
2007: {
2008: PetscMemType omtype;
2012: VecSetErrorIfLocked(x,1);
2013: if (x->ops->getarrayandmemtype) { /* VECCUDA, VECKOKKOS etc */
2014: (*x->ops->getarrayandmemtype)(x,a,&omtype);
2015: } else { /* VECSTANDARD, VECNEST, VECVIENNACL */
2016: VecGetArray(x,a);
2017: omtype = PETSC_MEMTYPE_HOST;
2018: }
2019: if (mtype) *mtype = omtype;
2020: return 0;
2021: }
2023: /*@C
2024: VecRestoreArrayAndMemType - Restores a vector after VecGetArrayAndMemType() has been called.
2026: Logically Collective on Vec
2028: Input Parameters:
2029: + x - the vector
2030: - a - location of pointer to array obtained from VecGetArrayAndMemType()
2032: Level: beginner
2034: .seealso: VecGetArrayAndMemType(), VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(),
2035: VecPlaceArray(), VecRestoreArray2d(), VecGetArrayPair(), VecRestoreArrayPair()
2036: @*/
2037: PetscErrorCode VecRestoreArrayAndMemType(Vec x,PetscScalar **a)
2038: {
2041: if (x->ops->restorearrayandmemtype) { /* VECCUDA, VECKOKKOS etc */
2042: (*x->ops->restorearrayandmemtype)(x,a);
2043: } else if (x->ops->restorearray) { /* VECNEST, VECVIENNACL */
2044: (*x->ops->restorearray)(x,a);
2045: } /* VECSTANDARD does nothing */
2046: if (a) *a = NULL;
2047: PetscObjectStateIncrease((PetscObject)x);
2048: return 0;
2049: }
2051: /*@C
2052: VecGetArrayReadAndMemType - Like VecGetArrayRead(), but if the input vector is a device vector, it will return a read-only device pointer. The returned pointer is guarenteed to point to up-to-date data. For host vectors, it functions as VecGetArrayRead().
2054: Not Collective
2056: Input Parameter:
2057: . x - the vector
2059: Output Parameters:
2060: + a - the array
2061: - mtype - memory type of the array
2063: Level: beginner
2065: Notes:
2066: The array must be returned using a matching call to VecRestoreArrayReadAndMemType().
2068: .seealso: VecRestoreArrayReadAndMemType(), VecGetArrayAndMemType(), VecGetArrayWriteAndMemType(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayAndMemType()
2069: @*/
2070: PetscErrorCode VecGetArrayReadAndMemType(Vec x,const PetscScalar **a,PetscMemType *mtype)
2071: {
2072: PetscMemType omtype;
2076: #if defined(PETSC_USE_DEBUG)
2078: #endif
2080: if (x->ops->getarrayandmemtype) { /* VECCUDA, VECKOKKOS etc, though they are also petscnative */
2081: (*x->ops->getarrayandmemtype)(x,(PetscScalar**)a,&omtype);
2082: } else if (x->ops->getarray) { /* VECNEST, VECVIENNACL */
2083: (*x->ops->getarray)(x,(PetscScalar**)a);
2084: omtype = PETSC_MEMTYPE_HOST;
2085: } else if (x->petscnative) { /* VECSTANDARD */
2086: *a = *((PetscScalar**)x->data);
2087: omtype = PETSC_MEMTYPE_HOST;
2088: } else SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array read in place for vector type \"%s\"",((PetscObject)x)->type_name);
2089: if (mtype) *mtype = omtype;
2090: return 0;
2091: }
2093: /*@C
2094: VecRestoreArrayReadAndMemType - Restore array obtained with VecGetArrayReadAndMemType()
2096: Not Collective
2098: Input Parameters:
2099: + vec - the vector
2100: - array - the array
2102: Level: beginner
2104: .seealso: VecGetArrayReadAndMemType(), VecRestoreArrayAndMemType(), VecRestoreArrayWriteAndMemType(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
2105: @*/
2106: PetscErrorCode VecRestoreArrayReadAndMemType(Vec x,const PetscScalar **a)
2107: {
2110: if (x->petscnative) { /* VECSTANDARD, VECCUDA, VECKOKKOS, VECVIENNACL etc */
2111: /* nothing */
2112: } else if (x->ops->restorearrayread) { /* VECNEST */
2113: (*x->ops->restorearrayread)(x,a);
2114: } else SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot restore array read in place for vector type \"%s\"",((PetscObject)x)->type_name);
2115: if (a) *a = NULL;
2116: return 0;
2117: }
2119: /*@C
2120: VecGetArrayWriteAndMemType - Like VecGetArrayWrite(), but if this is a device vector it will aways return
2121: a device pointer to the device memory that contains this processor's portion of the vector data.
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 VecRestoreArrayWriteAndMemType(), where it will label the device memory as most recent.
2137: .seealso: VecRestoreArrayWriteAndMemType(), VecGetArrayReadAndMemType(), VecGetArrayAndMemType(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(),
2138: @*/
2139: PetscErrorCode VecGetArrayWriteAndMemType(Vec x,PetscScalar **a,PetscMemType *mtype)
2140: {
2141: PetscMemType omtype;
2145: if (x->ops->getarraywriteandmemtype) { /* VECCUDA, VECHIP, VECKOKKOS etc, though they are also petscnative */
2146: (*x->ops->getarrayandmemtype)(x,a,&omtype);
2147: } else if (x->ops->getarraywrite) { /* VECNEST, VECVIENNACL */
2148: (*x->ops->getarraywrite)(x,a);
2149: omtype = PETSC_MEMTYPE_HOST;
2150: } else if (x->petscnative) { /* VECSTANDARD */
2151: *a = *((PetscScalar**)x->data);
2152: omtype = PETSC_MEMTYPE_HOST;
2153: } else SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array read in place for vector type \"%s\"",((PetscObject)x)->type_name);
2154: if (mtype) *mtype = omtype;
2155: return 0;
2156: }
2158: /*@C
2159: VecRestoreArrayWriteAndMemType - Restore array obtained with VecGetArrayWriteAndMemType()
2161: Not Collective
2163: Input Parameters:
2164: + vec - the vector
2165: - array - the array
2167: Level: beginner
2169: .seealso: VecGetArrayWriteAndMemType(), VecRestoreArrayAndMemType(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
2170: @*/
2171: PetscErrorCode VecRestoreArrayWriteAndMemType(Vec x,PetscScalar **a)
2172: {
2173: VecRestoreArrayAndMemType(x,a);
2174: return 0;
2175: }
2177: /*@
2178: VecPlaceArray - Allows one to replace the array in a vector with an
2179: array provided by the user. This is useful to avoid copying an array
2180: into a vector.
2182: Not Collective
2184: Input Parameters:
2185: + vec - the vector
2186: - array - the array
2188: Notes:
2189: You can return to the original array with a call to VecResetArray()
2191: Level: developer
2193: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
2195: @*/
2196: PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
2197: {
2201: if (vec->ops->placearray) {
2202: (*vec->ops->placearray)(vec,array);
2203: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
2204: PetscObjectStateIncrease((PetscObject)vec);
2205: return 0;
2206: }
2208: /*@C
2209: VecReplaceArray - Allows one to replace the array in a vector with an
2210: array provided by the user. This is useful to avoid copying an array
2211: into a vector.
2213: Not Collective
2215: Input Parameters:
2216: + vec - the vector
2217: - array - the array
2219: Notes:
2220: This permanently replaces the array and frees the memory associated
2221: with the old array.
2223: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
2224: freed by the user. It will be freed when the vector is destroyed.
2226: Not supported from Fortran
2228: Level: developer
2230: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
2232: @*/
2233: PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
2234: {
2237: if (vec->ops->replacearray) {
2238: (*vec->ops->replacearray)(vec,array);
2239: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
2240: PetscObjectStateIncrease((PetscObject)vec);
2241: return 0;
2242: }
2244: /*@C
2245: VecCUDAGetArray - Provides access to the CUDA buffer inside a vector.
2247: This function has semantics similar to VecGetArray(): the pointer
2248: returned by this function points to a consistent view of the vector
2249: data. This may involve a copy operation of data from the host to the
2250: device if the data on the device is out of date. If the device
2251: memory hasn't been allocated previously it will be allocated as part
2252: of this function call. VecCUDAGetArray() assumes that
2253: the user will modify the vector data. This is similar to
2254: intent(inout) in fortran.
2256: The CUDA device pointer has to be released by calling
2257: VecCUDARestoreArray(). Upon restoring the vector data
2258: the data on the host will be marked as out of date. A subsequent
2259: access of the host data will thus incur a data transfer from the
2260: device to the host.
2262: Input Parameter:
2263: . v - the vector
2265: Output Parameter:
2266: . a - the CUDA device pointer
2268: Fortran note:
2269: This function is not currently available from Fortran.
2271: Level: intermediate
2273: .seealso: VecCUDARestoreArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2274: @*/
2275: PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
2276: {
2278: #if defined(PETSC_HAVE_CUDA)
2279: {
2280: VecCUDACopyToGPU(v);
2281: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2282: }
2283: #endif
2284: return 0;
2285: }
2287: /*@C
2288: VecCUDARestoreArray - Restore a CUDA device pointer previously acquired with VecCUDAGetArray().
2290: This marks the host data as out of date. Subsequent access to the
2291: vector data on the host side with for instance VecGetArray() incurs a
2292: data transfer.
2294: Input Parameters:
2295: + v - the vector
2296: - a - the CUDA device pointer. This pointer is invalid after
2297: VecCUDARestoreArray() returns.
2299: Fortran note:
2300: This function is not currently available from Fortran.
2302: Level: intermediate
2304: .seealso: VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2305: @*/
2306: PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
2307: {
2309: #if defined(PETSC_HAVE_CUDA)
2310: v->offloadmask = PETSC_OFFLOAD_GPU;
2311: #endif
2312: PetscObjectStateIncrease((PetscObject)v);
2313: return 0;
2314: }
2316: /*@C
2317: VecCUDAGetArrayRead - Provides read access to the CUDA buffer inside a vector.
2319: This function is analogous to VecGetArrayRead(): The pointer
2320: returned by this function points to a consistent view of the vector
2321: data. This may involve a copy operation of data from the host to the
2322: device if the data on the device is out of date. If the device
2323: memory hasn't been allocated previously it will be allocated as part
2324: of this function call. VecCUDAGetArrayRead() assumes that the
2325: user will not modify the vector data. This is analgogous to
2326: intent(in) in Fortran.
2328: The CUDA device pointer has to be released by calling
2329: VecCUDARestoreArrayRead(). If the data on the host side was
2330: previously up to date it will remain so, i.e. data on both the device
2331: and the host is up to date. Accessing data on the host side does not
2332: incur a device to host data transfer.
2334: Input Parameter:
2335: . v - the vector
2337: Output Parameter:
2338: . a - the CUDA pointer.
2340: Fortran note:
2341: This function is not currently available from Fortran.
2343: Level: intermediate
2345: .seealso: VecCUDARestoreArrayRead(), VecCUDAGetArray(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2346: @*/
2347: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v,const PetscScalar** a)
2348: {
2349: VecCUDAGetArray(v,(PetscScalar**)a);
2350: return 0;
2351: }
2353: /*@C
2354: VecCUDARestoreArrayRead - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayRead().
2356: If the data on the host side was previously up to date it will remain
2357: so, i.e. data on both the device and the host is up to date.
2358: Accessing data on the host side e.g. with VecGetArray() does not
2359: incur a device to host data transfer.
2361: Input Parameters:
2362: + v - the vector
2363: - a - the CUDA device pointer. This pointer is invalid after
2364: VecCUDARestoreArrayRead() returns.
2366: Fortran note:
2367: This function is not currently available from Fortran.
2369: Level: intermediate
2371: .seealso: VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2372: @*/
2373: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
2374: {
2376: *a = NULL;
2377: return 0;
2378: }
2380: /*@C
2381: VecCUDAGetArrayWrite - Provides write access to the CUDA buffer inside a vector.
2383: The data pointed to by the device pointer is uninitialized. The user
2384: may not read from this data. Furthermore, the entire array needs to
2385: be filled by the user to obtain well-defined behaviour. The device
2386: memory will be allocated by this function if it hasn't been allocated
2387: previously. This is analogous to intent(out) in Fortran.
2389: The device pointer needs to be released with
2390: VecCUDARestoreArrayWrite(). When the pointer is released the
2391: host data of the vector is marked as out of data. Subsequent access
2392: of the host data with e.g. VecGetArray() incurs a device to host data
2393: transfer.
2395: Input Parameter:
2396: . v - the vector
2398: Output Parameter:
2399: . a - the CUDA pointer
2401: Fortran note:
2402: This function is not currently available from Fortran.
2404: Level: advanced
2406: .seealso: VecCUDARestoreArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2407: @*/
2408: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
2409: {
2411: #if defined(PETSC_HAVE_CUDA)
2412: {
2413: VecCUDAAllocateCheck(v);
2414: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2415: }
2416: #endif
2417: return 0;
2418: }
2420: /*@C
2421: VecCUDARestoreArrayWrite - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayWrite().
2423: Data on the host will be marked as out of date. Subsequent access of
2424: the data on the host side e.g. with VecGetArray() will incur a device
2425: to host data transfer.
2427: Input Parameters:
2428: + v - the vector
2429: - a - the CUDA device pointer. This pointer is invalid after
2430: VecCUDARestoreArrayWrite() returns.
2432: Fortran note:
2433: This function is not currently available from Fortran.
2435: Level: intermediate
2437: .seealso: VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2438: @*/
2439: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
2440: {
2442: #if defined(PETSC_HAVE_CUDA)
2443: v->offloadmask = PETSC_OFFLOAD_GPU;
2444: if (a) *a = NULL;
2445: #endif
2446: PetscObjectStateIncrease((PetscObject)v);
2447: return 0;
2448: }
2450: /*@C
2451: VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
2452: GPU array provided by the user. This is useful to avoid copying an
2453: array into a vector.
2455: Not Collective
2457: Input Parameters:
2458: + vec - the vector
2459: - array - the GPU array
2461: Notes:
2462: You can return to the original GPU array with a call to VecCUDAResetArray()
2463: It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
2464: same time on the same vector.
2466: Level: developer
2468: .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAReplaceArray()
2470: @*/
2471: PetscErrorCode VecCUDAPlaceArray(Vec vin,const PetscScalar a[])
2472: {
2474: #if defined(PETSC_HAVE_CUDA)
2475: VecCUDACopyToGPU(vin);
2477: ((Vec_Seq*)vin->data)->unplacedarray = (PetscScalar *) ((Vec_CUDA*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2478: ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar*)a;
2479: vin->offloadmask = PETSC_OFFLOAD_GPU;
2480: #endif
2481: PetscObjectStateIncrease((PetscObject)vin);
2482: return 0;
2483: }
2485: /*@C
2486: VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
2487: with a GPU array provided by the user. This is useful to avoid copying
2488: a GPU array into a vector.
2490: Not Collective
2492: Input Parameters:
2493: + vec - the vector
2494: - array - the GPU array
2496: Notes:
2497: This permanently replaces the GPU array and frees the memory associated
2498: with the old GPU array.
2500: The memory passed in CANNOT be freed by the user. It will be freed
2501: when the vector is destroyed.
2503: Not supported from Fortran
2505: Level: developer
2507: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAPlaceArray(), VecReplaceArray()
2509: @*/
2510: PetscErrorCode VecCUDAReplaceArray(Vec vin,const PetscScalar a[])
2511: {
2512: #if defined(PETSC_HAVE_CUDA)
2513: #endif
2516: #if defined(PETSC_HAVE_CUDA)
2517: if (((Vec_CUDA*)vin->spptr)->GPUarray_allocated) {
2518: cudaFree(((Vec_CUDA*)vin->spptr)->GPUarray_allocated);
2519: }
2520: ((Vec_CUDA*)vin->spptr)->GPUarray_allocated = ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar*)a;
2521: vin->offloadmask = PETSC_OFFLOAD_GPU;
2522: #endif
2523: PetscObjectStateIncrease((PetscObject)vin);
2524: return 0;
2525: }
2527: /*@C
2528: VecCUDAResetArray - Resets a vector to use its default memory. Call this
2529: after the use of VecCUDAPlaceArray().
2531: Not Collective
2533: Input Parameters:
2534: . vec - the vector
2536: Level: developer
2538: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecCUDAPlaceArray(), VecCUDAReplaceArray()
2540: @*/
2541: PetscErrorCode VecCUDAResetArray(Vec vin)
2542: {
2544: #if defined(PETSC_HAVE_CUDA)
2545: VecCUDACopyToGPU(vin);
2546: ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2547: ((Vec_Seq*)vin->data)->unplacedarray = 0;
2548: vin->offloadmask = PETSC_OFFLOAD_GPU;
2549: #endif
2550: PetscObjectStateIncrease((PetscObject)vin);
2551: return 0;
2552: }
2554: /*@C
2555: VecHIPGetArray - Provides access to the HIP buffer inside a vector.
2557: This function has semantics similar to VecGetArray(): the pointer
2558: returned by this function points to a consistent view of the vector
2559: data. This may involve a copy operation of data from the host to the
2560: device if the data on the device is out of date. If the device
2561: memory hasn't been allocated previously it will be allocated as part
2562: of this function call. VecHIPGetArray() assumes that
2563: the user will modify the vector data. This is similar to
2564: intent(inout) in fortran.
2566: The HIP device pointer has to be released by calling
2567: VecHIPRestoreArray(). Upon restoring the vector data
2568: the data on the host will be marked as out of date. A subsequent
2569: access of the host data will thus incur a data transfer from the
2570: device to the host.
2572: Input Parameter:
2573: . v - the vector
2575: Output Parameter:
2576: . a - the HIP device pointer
2578: Fortran note:
2579: This function is not currently available from Fortran.
2581: Level: intermediate
2583: .seealso: VecHIPRestoreArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2584: @*/
2585: PETSC_EXTERN PetscErrorCode VecHIPGetArray(Vec v, PetscScalar **a)
2586: {
2588: #if defined(PETSC_HAVE_HIP)
2589: *a = 0;
2590: VecHIPCopyToGPU(v);
2591: *a = ((Vec_HIP*)v->spptr)->GPUarray;
2592: #endif
2593: return 0;
2594: }
2596: /*@C
2597: VecHIPRestoreArray - Restore a HIP device pointer previously acquired with VecHIPGetArray().
2599: This marks the host data as out of date. Subsequent access to the
2600: vector data on the host side with for instance VecGetArray() incurs a
2601: data transfer.
2603: Input Parameters:
2604: + v - the vector
2605: - a - the HIP device pointer. This pointer is invalid after
2606: VecHIPRestoreArray() returns.
2608: Fortran note:
2609: This function is not currently available from Fortran.
2611: Level: intermediate
2613: .seealso: VecHIPGetArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2614: @*/
2615: PETSC_EXTERN PetscErrorCode VecHIPRestoreArray(Vec v, PetscScalar **a)
2616: {
2618: #if defined(PETSC_HAVE_HIP)
2619: v->offloadmask = PETSC_OFFLOAD_GPU;
2620: #endif
2622: PetscObjectStateIncrease((PetscObject)v);
2623: return 0;
2624: }
2626: /*@C
2627: VecHIPGetArrayRead - Provides read access to the HIP buffer inside a vector.
2629: This function is analogous to VecGetArrayRead(): The pointer
2630: returned by this function points to a consistent view of the vector
2631: data. This may involve a copy operation of data from the host to the
2632: device if the data on the device is out of date. If the device
2633: memory hasn't been allocated previously it will be allocated as part
2634: of this function call. VecHIPGetArrayRead() assumes that the
2635: user will not modify the vector data. This is analgogous to
2636: intent(in) in Fortran.
2638: The HIP device pointer has to be released by calling
2639: VecHIPRestoreArrayRead(). If the data on the host side was
2640: previously up to date it will remain so, i.e. data on both the device
2641: and the host is up to date. Accessing data on the host side does not
2642: incur a device to host data transfer.
2644: Input Parameter:
2645: . v - the vector
2647: Output Parameter:
2648: . a - the HIP pointer.
2650: Fortran note:
2651: This function is not currently available from Fortran.
2653: Level: intermediate
2655: .seealso: VecHIPRestoreArrayRead(), VecHIPGetArray(), VecHIPGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2656: @*/
2657: PETSC_EXTERN PetscErrorCode VecHIPGetArrayRead(Vec v, const PetscScalar **a)
2658: {
2660: #if defined(PETSC_HAVE_HIP)
2661: *a = 0;
2662: VecHIPCopyToGPU(v);
2663: *a = ((Vec_HIP*)v->spptr)->GPUarray;
2664: #endif
2665: return 0;
2666: }
2668: /*@C
2669: VecHIPRestoreArrayRead - Restore a HIP device pointer previously acquired with VecHIPGetArrayRead().
2671: If the data on the host side was previously up to date it will remain
2672: so, i.e. data on both the device and the host is up to date.
2673: Accessing data on the host side e.g. with VecGetArray() does not
2674: incur a device to host data transfer.
2676: Input Parameters:
2677: + v - the vector
2678: - a - the HIP device pointer. This pointer is invalid after
2679: VecHIPRestoreArrayRead() returns.
2681: Fortran note:
2682: This function is not currently available from Fortran.
2684: Level: intermediate
2686: .seealso: VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecHIPGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2687: @*/
2688: PETSC_EXTERN PetscErrorCode VecHIPRestoreArrayRead(Vec v, const PetscScalar **a)
2689: {
2691: *a = NULL;
2692: return 0;
2693: }
2695: /*@C
2696: VecHIPGetArrayWrite - Provides write access to the HIP buffer inside a vector.
2698: The data pointed to by the device pointer is uninitialized. The user
2699: may not read from this data. Furthermore, the entire array needs to
2700: be filled by the user to obtain well-defined behaviour. The device
2701: memory will be allocated by this function if it hasn't been allocated
2702: previously. This is analogous to intent(out) in Fortran.
2704: The device pointer needs to be released with
2705: VecHIPRestoreArrayWrite(). When the pointer is released the
2706: host data of the vector is marked as out of data. Subsequent access
2707: of the host data with e.g. VecGetArray() incurs a device to host data
2708: transfer.
2710: Input Parameter:
2711: . v - the vector
2713: Output Parameter:
2714: . a - the HIP pointer
2716: Fortran note:
2717: This function is not currently available from Fortran.
2719: Level: advanced
2721: .seealso: VecHIPRestoreArrayWrite(), VecHIPGetArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2722: @*/
2723: PETSC_EXTERN PetscErrorCode VecHIPGetArrayWrite(Vec v, PetscScalar **a)
2724: {
2726: #if defined(PETSC_HAVE_HIP)
2727: *a = 0;
2728: VecHIPAllocateCheck(v);
2729: *a = ((Vec_HIP*)v->spptr)->GPUarray;
2730: #endif
2731: return 0;
2732: }
2734: /*@C
2735: VecHIPRestoreArrayWrite - Restore a HIP device pointer previously acquired with VecHIPGetArrayWrite().
2737: Data on the host will be marked as out of date. Subsequent access of
2738: the data on the host side e.g. with VecGetArray() will incur a device
2739: to host data transfer.
2741: Input Parameters:
2742: + v - the vector
2743: - a - the HIP device pointer. This pointer is invalid after
2744: VecHIPRestoreArrayWrite() returns.
2746: Fortran note:
2747: This function is not currently available from Fortran.
2749: Level: intermediate
2751: .seealso: VecHIPGetArrayWrite(), VecHIPGetArray(), VecHIPGetArrayRead(), VecHIPGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2752: @*/
2753: PETSC_EXTERN PetscErrorCode VecHIPRestoreArrayWrite(Vec v, PetscScalar **a)
2754: {
2756: #if defined(PETSC_HAVE_HIP)
2757: v->offloadmask = PETSC_OFFLOAD_GPU;
2758: #endif
2760: PetscObjectStateIncrease((PetscObject)v);
2761: return 0;
2762: }
2764: /*@C
2765: VecHIPPlaceArray - Allows one to replace the GPU array in a vector with a
2766: GPU array provided by the user. This is useful to avoid copying an
2767: array into a vector.
2769: Not Collective
2771: Input Parameters:
2772: + vec - the vector
2773: - array - the GPU array
2775: Notes:
2776: You can return to the original GPU array with a call to VecHIPResetArray()
2777: It is not possible to use VecHIPPlaceArray() and VecPlaceArray() at the
2778: same time on the same vector.
2780: Level: developer
2782: .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecHIPResetArray(), VecHIPReplaceArray()
2784: @*/
2785: PetscErrorCode VecHIPPlaceArray(Vec vin,const PetscScalar a[])
2786: {
2788: #if defined(PETSC_HAVE_HIP)
2789: VecHIPCopyToGPU(vin);
2791: ((Vec_Seq*)vin->data)->unplacedarray = (PetscScalar *) ((Vec_HIP*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2792: ((Vec_HIP*)vin->spptr)->GPUarray = (PetscScalar*)a;
2793: vin->offloadmask = PETSC_OFFLOAD_GPU;
2794: #endif
2795: PetscObjectStateIncrease((PetscObject)vin);
2796: return 0;
2797: }
2799: /*@C
2800: VecHIPReplaceArray - Allows one to replace the GPU array in a vector
2801: with a GPU array provided by the user. This is useful to avoid copying
2802: a GPU array into a vector.
2804: Not Collective
2806: Input Parameters:
2807: + vec - the vector
2808: - array - the GPU array
2810: Notes:
2811: This permanently replaces the GPU array and frees the memory associated
2812: with the old GPU array.
2814: The memory passed in CANNOT be freed by the user. It will be freed
2815: when the vector is destroyed.
2817: Not supported from Fortran
2819: Level: developer
2821: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecHIPResetArray(), VecHIPPlaceArray(), VecReplaceArray()
2823: @*/
2824: PetscErrorCode VecHIPReplaceArray(Vec vin,const PetscScalar a[])
2825: {
2827: #if defined(PETSC_HAVE_HIP)
2828: hipFree(((Vec_HIP*)vin->spptr)->GPUarray);
2829: ((Vec_HIP*)vin->spptr)->GPUarray = (PetscScalar*)a;
2830: vin->offloadmask = PETSC_OFFLOAD_GPU;
2831: #endif
2832: PetscObjectStateIncrease((PetscObject)vin);
2833: return 0;
2834: }
2836: /*@C
2837: VecHIPResetArray - Resets a vector to use its default memory. Call this
2838: after the use of VecHIPPlaceArray().
2840: Not Collective
2842: Input Parameters:
2843: . vec - the vector
2845: Level: developer
2847: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecHIPPlaceArray(), VecHIPReplaceArray()
2849: @*/
2850: PetscErrorCode VecHIPResetArray(Vec vin)
2851: {
2853: #if defined(PETSC_HAVE_HIP)
2854: VecHIPCopyToGPU(vin);
2855: ((Vec_HIP*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2856: ((Vec_Seq*)vin->data)->unplacedarray = 0;
2857: vin->offloadmask = PETSC_OFFLOAD_GPU;
2858: #endif
2859: PetscObjectStateIncrease((PetscObject)vin);
2860: return 0;
2861: }
2863: /*MC
2864: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2865: and makes them accessible via a Fortran90 pointer.
2867: Synopsis:
2868: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2870: Collective on Vec
2872: Input Parameters:
2873: + x - a vector to mimic
2874: - n - the number of vectors to obtain
2876: Output Parameters:
2877: + y - Fortran90 pointer to the array of vectors
2878: - ierr - error code
2880: Example of Usage:
2881: .vb
2882: #include <petsc/finclude/petscvec.h>
2883: use petscvec
2885: Vec x
2886: Vec, pointer :: y(:)
2887: ....
2888: call VecDuplicateVecsF90(x,2,y,ierr)
2889: call VecSet(y(2),alpha,ierr)
2890: call VecSet(y(2),alpha,ierr)
2891: ....
2892: call VecDestroyVecsF90(2,y,ierr)
2893: .ve
2895: Notes:
2896: Not yet supported for all F90 compilers
2898: Use VecDestroyVecsF90() to free the space.
2900: Level: beginner
2902: .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
2904: M*/
2906: /*MC
2907: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2908: VecGetArrayF90().
2910: Synopsis:
2911: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2913: Logically Collective on Vec
2915: Input Parameters:
2916: + x - vector
2917: - xx_v - the Fortran90 pointer to the array
2919: Output Parameter:
2920: . ierr - error code
2922: Example of Usage:
2923: .vb
2924: #include <petsc/finclude/petscvec.h>
2925: use petscvec
2927: PetscScalar, pointer :: xx_v(:)
2928: ....
2929: call VecGetArrayF90(x,xx_v,ierr)
2930: xx_v(3) = a
2931: call VecRestoreArrayF90(x,xx_v,ierr)
2932: .ve
2934: Level: beginner
2936: .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray(), VecRestoreArrayReadF90()
2938: M*/
2940: /*MC
2941: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
2943: Synopsis:
2944: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
2946: Collective on Vec
2948: Input Parameters:
2949: + n - the number of vectors previously obtained
2950: - x - pointer to array of vector pointers
2952: Output Parameter:
2953: . ierr - error code
2955: Notes:
2956: Not yet supported for all F90 compilers
2958: Level: beginner
2960: .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
2962: M*/
2964: /*MC
2965: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
2966: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2967: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
2968: when you no longer need access to the array.
2970: Synopsis:
2971: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2973: Logically Collective on Vec
2975: Input Parameter:
2976: . x - vector
2978: Output Parameters:
2979: + xx_v - the Fortran90 pointer to the array
2980: - ierr - error code
2982: Example of Usage:
2983: .vb
2984: #include <petsc/finclude/petscvec.h>
2985: use petscvec
2987: PetscScalar, pointer :: xx_v(:)
2988: ....
2989: call VecGetArrayF90(x,xx_v,ierr)
2990: xx_v(3) = a
2991: call VecRestoreArrayF90(x,xx_v,ierr)
2992: .ve
2994: If you ONLY intend to read entries from the array and not change any entries you should use VecGetArrayReadF90().
2996: Level: beginner
2998: .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), VecGetArrayReadF90()
3000: M*/
3002: /*MC
3003: VecGetArrayReadF90 - Accesses a read only array from Fortran90. For default PETSc
3004: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
3005: this routine is implementation dependent. You MUST call VecRestoreArrayReadF90()
3006: when you no longer need access to the array.
3008: Synopsis:
3009: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3011: Logically Collective on Vec
3013: Input Parameter:
3014: . x - vector
3016: Output Parameters:
3017: + xx_v - the Fortran90 pointer to the array
3018: - ierr - error code
3020: Example of Usage:
3021: .vb
3022: #include <petsc/finclude/petscvec.h>
3023: use petscvec
3025: PetscScalar, pointer :: xx_v(:)
3026: ....
3027: call VecGetArrayReadF90(x,xx_v,ierr)
3028: a = xx_v(3)
3029: call VecRestoreArrayReadF90(x,xx_v,ierr)
3030: .ve
3032: If you intend to write entries into the array you must use VecGetArrayF90().
3034: Level: beginner
3036: .seealso: VecRestoreArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(), VecGetArrayF90()
3038: M*/
3040: /*MC
3041: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
3042: VecGetArrayReadF90().
3044: Synopsis:
3045: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
3047: Logically Collective on Vec
3049: Input Parameters:
3050: + x - vector
3051: - xx_v - the Fortran90 pointer to the array
3053: Output Parameter:
3054: . ierr - error code
3056: Example of Usage:
3057: .vb
3058: #include <petsc/finclude/petscvec.h>
3059: use petscvec
3061: PetscScalar, pointer :: xx_v(:)
3062: ....
3063: call VecGetArrayReadF90(x,xx_v,ierr)
3064: a = xx_v(3)
3065: call VecRestoreArrayReadF90(x,xx_v,ierr)
3066: .ve
3068: Level: beginner
3070: .seealso: VecGetArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(), VecRestoreArrayF90()
3072: M*/
3074: /*@C
3075: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
3076: processor's portion of the vector data. You MUST call VecRestoreArray2d()
3077: when you no longer need access to the array.
3079: Logically Collective
3081: Input Parameters:
3082: + x - the vector
3083: . m - first dimension of two dimensional array
3084: . n - second dimension of two dimensional array
3085: . mstart - first index you will use in first coordinate direction (often 0)
3086: - nstart - first index in the second coordinate direction (often 0)
3088: Output Parameter:
3089: . a - location to put pointer to the array
3091: Level: developer
3093: Notes:
3094: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3095: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3096: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3097: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3099: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3101: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3102: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3103: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3104: @*/
3105: PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3106: {
3107: PetscInt i,N;
3108: PetscScalar *aa;
3113: VecGetLocalSize(x,&N);
3115: VecGetArray(x,&aa);
3117: PetscMalloc1(m,a);
3118: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
3119: *a -= mstart;
3120: return 0;
3121: }
3123: /*@C
3124: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
3125: processor's portion of the vector data. You MUST call VecRestoreArray2dWrite()
3126: when you no longer need access to the array.
3128: Logically Collective
3130: Input Parameters:
3131: + x - the vector
3132: . m - first dimension of two dimensional array
3133: . n - second dimension of two dimensional array
3134: . mstart - first index you will use in first coordinate direction (often 0)
3135: - nstart - first index in the second coordinate direction (often 0)
3137: Output Parameter:
3138: . a - location to put pointer to the array
3140: Level: developer
3142: Notes:
3143: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3144: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3145: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3146: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3148: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3150: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3151: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3152: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3153: @*/
3154: PetscErrorCode VecGetArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3155: {
3156: PetscInt i,N;
3157: PetscScalar *aa;
3162: VecGetLocalSize(x,&N);
3164: VecGetArrayWrite(x,&aa);
3166: PetscMalloc1(m,a);
3167: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
3168: *a -= mstart;
3169: return 0;
3170: }
3172: /*@C
3173: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
3175: Logically Collective
3177: Input Parameters:
3178: + x - the vector
3179: . m - first dimension of two dimensional array
3180: . n - second dimension of the two dimensional array
3181: . mstart - first index you will use in first coordinate direction (often 0)
3182: . nstart - first index in the second coordinate direction (often 0)
3183: - a - location of pointer to array obtained from VecGetArray2d()
3185: Level: developer
3187: Notes:
3188: For regular PETSc vectors this routine does not involve any copies. For
3189: any special vectors that do not store local vector data in a contiguous
3190: array, this routine will copy the data back into the underlying
3191: vector data structure from the array obtained with VecGetArray().
3193: This routine actually zeros out the a pointer.
3195: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3196: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3197: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3198: @*/
3199: PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3200: {
3201: void *dummy;
3206: dummy = (void*)(*a + mstart);
3207: PetscFree(dummy);
3208: VecRestoreArray(x,NULL);
3209: return 0;
3210: }
3212: /*@C
3213: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite() has been called.
3215: Logically Collective
3217: Input Parameters:
3218: + x - the vector
3219: . m - first dimension of two dimensional array
3220: . n - second dimension of the two dimensional array
3221: . mstart - first index you will use in first coordinate direction (often 0)
3222: . nstart - first index in the second coordinate direction (often 0)
3223: - a - location of pointer to array obtained from VecGetArray2d()
3225: Level: developer
3227: Notes:
3228: For regular PETSc vectors this routine does not involve any copies. For
3229: any special vectors that do not store local vector data in a contiguous
3230: array, this routine will copy the data back into the underlying
3231: vector data structure from the array obtained with VecGetArray().
3233: This routine actually zeros out the a pointer.
3235: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3236: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3237: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3238: @*/
3239: PetscErrorCode VecRestoreArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3240: {
3241: void *dummy;
3246: dummy = (void*)(*a + mstart);
3247: PetscFree(dummy);
3248: VecRestoreArrayWrite(x,NULL);
3249: return 0;
3250: }
3252: /*@C
3253: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
3254: processor's portion of the vector data. You MUST call VecRestoreArray1d()
3255: when you no longer need access to the array.
3257: Logically Collective
3259: Input Parameters:
3260: + x - the vector
3261: . m - first dimension of two dimensional array
3262: - mstart - first index you will use in first coordinate direction (often 0)
3264: Output Parameter:
3265: . a - location to put pointer to the array
3267: Level: developer
3269: Notes:
3270: For a vector obtained from DMCreateLocalVector() mstart are likely
3271: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3272: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3274: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3276: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3277: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3278: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3279: @*/
3280: PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3281: {
3282: PetscInt N;
3287: VecGetLocalSize(x,&N);
3289: VecGetArray(x,a);
3290: *a -= mstart;
3291: return 0;
3292: }
3294: /*@C
3295: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
3296: processor's portion of the vector data. You MUST call VecRestoreArray1dWrite()
3297: when you no longer need access to the array.
3299: Logically Collective
3301: Input Parameters:
3302: + x - the vector
3303: . m - first dimension of two dimensional array
3304: - mstart - first index you will use in first coordinate direction (often 0)
3306: Output Parameter:
3307: . a - location to put pointer to the array
3309: Level: developer
3311: Notes:
3312: For a vector obtained from DMCreateLocalVector() mstart are likely
3313: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3314: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3316: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3318: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3319: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3320: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3321: @*/
3322: PetscErrorCode VecGetArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3323: {
3324: PetscInt N;
3329: VecGetLocalSize(x,&N);
3331: VecGetArrayWrite(x,a);
3332: *a -= mstart;
3333: return 0;
3334: }
3336: /*@C
3337: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
3339: Logically Collective
3341: Input Parameters:
3342: + x - the vector
3343: . m - first dimension of two dimensional array
3344: . mstart - first index you will use in first coordinate direction (often 0)
3345: - a - location of pointer to array obtained from VecGetArray21()
3347: Level: developer
3349: Notes:
3350: For regular PETSc vectors this routine does not involve any copies. For
3351: any special vectors that do not store local vector data in a contiguous
3352: array, this routine will copy the data back into the underlying
3353: vector data structure from the array obtained with VecGetArray1d().
3355: This routine actually zeros out the a pointer.
3357: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3358: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3359: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3360: @*/
3361: PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3362: {
3365: VecRestoreArray(x,NULL);
3366: return 0;
3367: }
3369: /*@C
3370: VecRestoreArray1dWrite - Restores a vector after VecGetArray1dWrite() has been called.
3372: Logically Collective
3374: Input Parameters:
3375: + x - the vector
3376: . m - first dimension of two dimensional array
3377: . mstart - first index you will use in first coordinate direction (often 0)
3378: - a - location of pointer to array obtained from VecGetArray21()
3380: Level: developer
3382: Notes:
3383: For regular PETSc vectors this routine does not involve any copies. For
3384: any special vectors that do not store local vector data in a contiguous
3385: array, this routine will copy the data back into the underlying
3386: vector data structure from the array obtained with VecGetArray1d().
3388: This routine actually zeros out the a pointer.
3390: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3391: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3392: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3393: @*/
3394: PetscErrorCode VecRestoreArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3395: {
3398: VecRestoreArrayWrite(x,NULL);
3399: return 0;
3400: }
3402: /*@C
3403: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
3404: processor's portion of the vector data. You MUST call VecRestoreArray3d()
3405: when you no longer need access to the array.
3407: Logically Collective
3409: Input Parameters:
3410: + x - the vector
3411: . m - first dimension of three dimensional array
3412: . n - second dimension of three dimensional array
3413: . p - third dimension of three dimensional array
3414: . mstart - first index you will use in first coordinate direction (often 0)
3415: . nstart - first index in the second coordinate direction (often 0)
3416: - pstart - first index in the third coordinate direction (often 0)
3418: Output Parameter:
3419: . a - location to put pointer to the array
3421: Level: developer
3423: Notes:
3424: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3425: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3426: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3427: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3429: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3431: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3432: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3433: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3434: @*/
3435: PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3436: {
3437: PetscInt i,N,j;
3438: PetscScalar *aa,**b;
3443: VecGetLocalSize(x,&N);
3445: VecGetArray(x,&aa);
3447: PetscMalloc(m*sizeof(PetscScalar**)+m*n*sizeof(PetscScalar*),a);
3448: b = (PetscScalar**)((*a) + m);
3449: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3450: for (i=0; i<m; i++)
3451: for (j=0; j<n; j++)
3452: b[i*n+j] = aa + i*n*p + j*p - pstart;
3453: *a -= mstart;
3454: return 0;
3455: }
3457: /*@C
3458: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3459: processor's portion of the vector data. You MUST call VecRestoreArray3dWrite()
3460: when you no longer need access to the array.
3462: Logically Collective
3464: Input Parameters:
3465: + x - the vector
3466: . m - first dimension of three dimensional array
3467: . n - second dimension of three dimensional array
3468: . p - third dimension of three dimensional array
3469: . mstart - first index you will use in first coordinate direction (often 0)
3470: . nstart - first index in the second coordinate direction (often 0)
3471: - pstart - first index in the third coordinate direction (often 0)
3473: Output Parameter:
3474: . a - location to put pointer to the array
3476: Level: developer
3478: Notes:
3479: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3480: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3481: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3482: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3484: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3486: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3487: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3488: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3489: @*/
3490: PetscErrorCode VecGetArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3491: {
3492: PetscInt i,N,j;
3493: PetscScalar *aa,**b;
3498: VecGetLocalSize(x,&N);
3500: VecGetArrayWrite(x,&aa);
3502: PetscMalloc(m*sizeof(PetscScalar**)+m*n*sizeof(PetscScalar*),a);
3503: b = (PetscScalar**)((*a) + m);
3504: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3505: for (i=0; i<m; i++)
3506: for (j=0; j<n; j++)
3507: b[i*n+j] = aa + i*n*p + j*p - pstart;
3509: *a -= mstart;
3510: return 0;
3511: }
3513: /*@C
3514: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
3516: Logically Collective
3518: Input Parameters:
3519: + x - the vector
3520: . m - first dimension of three dimensional array
3521: . n - second dimension of the three dimensional array
3522: . p - third dimension of the three dimensional array
3523: . mstart - first index you will use in first coordinate direction (often 0)
3524: . nstart - first index in the second coordinate direction (often 0)
3525: . pstart - first index in the third coordinate direction (often 0)
3526: - a - location of pointer to array obtained from VecGetArray3d()
3528: Level: developer
3530: Notes:
3531: For regular PETSc vectors this routine does not involve any copies. For
3532: any special vectors that do not store local vector data in a contiguous
3533: array, this routine will copy the data back into the underlying
3534: vector data structure from the array obtained with VecGetArray().
3536: This routine actually zeros out the a pointer.
3538: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3539: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3540: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3541: @*/
3542: PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3543: {
3544: void *dummy;
3549: dummy = (void*)(*a + mstart);
3550: PetscFree(dummy);
3551: VecRestoreArray(x,NULL);
3552: return 0;
3553: }
3555: /*@C
3556: VecRestoreArray3dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3558: Logically Collective
3560: Input Parameters:
3561: + x - the vector
3562: . m - first dimension of three dimensional array
3563: . n - second dimension of the three dimensional array
3564: . p - third dimension of the three dimensional array
3565: . mstart - first index you will use in first coordinate direction (often 0)
3566: . nstart - first index in the second coordinate direction (often 0)
3567: . pstart - first index in the third coordinate direction (often 0)
3568: - a - location of pointer to array obtained from VecGetArray3d()
3570: Level: developer
3572: Notes:
3573: For regular PETSc vectors this routine does not involve any copies. For
3574: any special vectors that do not store local vector data in a contiguous
3575: array, this routine will copy the data back into the underlying
3576: vector data structure from the array obtained with VecGetArray().
3578: This routine actually zeros out the a pointer.
3580: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3581: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3582: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3583: @*/
3584: PetscErrorCode VecRestoreArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3585: {
3586: void *dummy;
3591: dummy = (void*)(*a + mstart);
3592: PetscFree(dummy);
3593: VecRestoreArrayWrite(x,NULL);
3594: return 0;
3595: }
3597: /*@C
3598: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3599: processor's portion of the vector data. You MUST call VecRestoreArray4d()
3600: when you no longer need access to the array.
3602: Logically Collective
3604: Input Parameters:
3605: + x - the vector
3606: . m - first dimension of four dimensional array
3607: . n - second dimension of four dimensional array
3608: . p - third dimension of four dimensional array
3609: . q - fourth dimension of four dimensional array
3610: . mstart - first index you will use in first coordinate direction (often 0)
3611: . nstart - first index in the second coordinate direction (often 0)
3612: . pstart - first index in the third coordinate direction (often 0)
3613: - qstart - first index in the fourth coordinate direction (often 0)
3615: Output Parameter:
3616: . a - location to put pointer to the array
3618: Level: beginner
3620: Notes:
3621: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3622: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3623: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3624: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3626: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3628: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3629: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3630: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3631: @*/
3632: PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3633: {
3634: PetscInt i,N,j,k;
3635: PetscScalar *aa,***b,**c;
3640: VecGetLocalSize(x,&N);
3642: VecGetArray(x,&aa);
3644: PetscMalloc(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p*sizeof(PetscScalar*),a);
3645: b = (PetscScalar***)((*a) + m);
3646: c = (PetscScalar**)(b + m*n);
3647: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3648: for (i=0; i<m; i++)
3649: for (j=0; j<n; j++)
3650: b[i*n+j] = c + i*n*p + j*p - pstart;
3651: for (i=0; i<m; i++)
3652: for (j=0; j<n; j++)
3653: for (k=0; k<p; k++)
3654: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3655: *a -= mstart;
3656: return 0;
3657: }
3659: /*@C
3660: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3661: processor's portion of the vector data. You MUST call VecRestoreArray4dWrite()
3662: when you no longer need access to the array.
3664: Logically Collective
3666: Input Parameters:
3667: + x - the vector
3668: . m - first dimension of four dimensional array
3669: . n - second dimension of four dimensional array
3670: . p - third dimension of four dimensional array
3671: . q - fourth dimension of four dimensional array
3672: . mstart - first index you will use in first coordinate direction (often 0)
3673: . nstart - first index in the second coordinate direction (often 0)
3674: . pstart - first index in the third coordinate direction (often 0)
3675: - qstart - first index in the fourth coordinate direction (often 0)
3677: Output Parameter:
3678: . a - location to put pointer to the array
3680: Level: beginner
3682: Notes:
3683: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3684: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3685: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3686: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3688: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3690: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3691: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3692: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3693: @*/
3694: PetscErrorCode VecGetArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3695: {
3696: PetscInt i,N,j,k;
3697: PetscScalar *aa,***b,**c;
3702: VecGetLocalSize(x,&N);
3704: VecGetArrayWrite(x,&aa);
3706: PetscMalloc(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p*sizeof(PetscScalar*),a);
3707: b = (PetscScalar***)((*a) + m);
3708: c = (PetscScalar**)(b + m*n);
3709: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3710: for (i=0; i<m; i++)
3711: for (j=0; j<n; j++)
3712: b[i*n+j] = c + i*n*p + j*p - pstart;
3713: for (i=0; i<m; i++)
3714: for (j=0; j<n; j++)
3715: for (k=0; k<p; k++)
3716: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3717: *a -= mstart;
3718: return 0;
3719: }
3721: /*@C
3722: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
3724: Logically Collective
3726: Input Parameters:
3727: + x - the vector
3728: . m - first dimension of four dimensional array
3729: . n - second dimension of the four dimensional array
3730: . p - third dimension of the four dimensional array
3731: . q - fourth dimension of the four dimensional array
3732: . mstart - first index you will use in first coordinate direction (often 0)
3733: . nstart - first index in the second coordinate direction (often 0)
3734: . pstart - first index in the third coordinate direction (often 0)
3735: . qstart - first index in the fourth coordinate direction (often 0)
3736: - a - location of pointer to array obtained from VecGetArray4d()
3738: Level: beginner
3740: Notes:
3741: For regular PETSc vectors this routine does not involve any copies. For
3742: any special vectors that do not store local vector data in a contiguous
3743: array, this routine will copy the data back into the underlying
3744: vector data structure from the array obtained with VecGetArray().
3746: This routine actually zeros out the a pointer.
3748: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3749: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3750: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3751: @*/
3752: PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3753: {
3754: void *dummy;
3759: dummy = (void*)(*a + mstart);
3760: PetscFree(dummy);
3761: VecRestoreArray(x,NULL);
3762: return 0;
3763: }
3765: /*@C
3766: VecRestoreArray4dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3768: Logically Collective
3770: Input Parameters:
3771: + x - the vector
3772: . m - first dimension of four dimensional array
3773: . n - second dimension of the four dimensional array
3774: . p - third dimension of the four dimensional array
3775: . q - fourth dimension of the four dimensional array
3776: . mstart - first index you will use in first coordinate direction (often 0)
3777: . nstart - first index in the second coordinate direction (often 0)
3778: . pstart - first index in the third coordinate direction (often 0)
3779: . qstart - first index in the fourth coordinate direction (often 0)
3780: - a - location of pointer to array obtained from VecGetArray4d()
3782: Level: beginner
3784: Notes:
3785: For regular PETSc vectors this routine does not involve any copies. For
3786: any special vectors that do not store local vector data in a contiguous
3787: array, this routine will copy the data back into the underlying
3788: vector data structure from the array obtained with VecGetArray().
3790: This routine actually zeros out the a pointer.
3792: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3793: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3794: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3795: @*/
3796: PetscErrorCode VecRestoreArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3797: {
3798: void *dummy;
3803: dummy = (void*)(*a + mstart);
3804: PetscFree(dummy);
3805: VecRestoreArrayWrite(x,NULL);
3806: return 0;
3807: }
3809: /*@C
3810: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3811: processor's portion of the vector data. You MUST call VecRestoreArray2dRead()
3812: when you no longer need access to the array.
3814: Logically Collective
3816: Input Parameters:
3817: + x - the vector
3818: . m - first dimension of two dimensional array
3819: . n - second dimension of two dimensional array
3820: . mstart - first index you will use in first coordinate direction (often 0)
3821: - nstart - first index in the second coordinate direction (often 0)
3823: Output Parameter:
3824: . a - location to put pointer to the array
3826: Level: developer
3828: Notes:
3829: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3830: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3831: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3832: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3834: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3836: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3837: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3838: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3839: @*/
3840: PetscErrorCode VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3841: {
3842: PetscInt i,N;
3843: const PetscScalar *aa;
3848: VecGetLocalSize(x,&N);
3850: VecGetArrayRead(x,&aa);
3852: PetscMalloc1(m,a);
3853: for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
3854: *a -= mstart;
3855: return 0;
3856: }
3858: /*@C
3859: VecRestoreArray2dRead - Restores a vector after VecGetArray2dRead() has been called.
3861: Logically Collective
3863: Input Parameters:
3864: + x - the vector
3865: . m - first dimension of two dimensional array
3866: . n - second dimension of the two dimensional array
3867: . mstart - first index you will use in first coordinate direction (often 0)
3868: . nstart - first index in the second coordinate direction (often 0)
3869: - a - location of pointer to array obtained from VecGetArray2d()
3871: Level: developer
3873: Notes:
3874: For regular PETSc vectors this routine does not involve any copies. For
3875: any special vectors that do not store local vector data in a contiguous
3876: array, this routine will copy the data back into the underlying
3877: vector data structure from the array obtained with VecGetArray().
3879: This routine actually zeros out the a pointer.
3881: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3882: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3883: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3884: @*/
3885: PetscErrorCode VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3886: {
3887: void *dummy;
3892: dummy = (void*)(*a + mstart);
3893: PetscFree(dummy);
3894: VecRestoreArrayRead(x,NULL);
3895: return 0;
3896: }
3898: /*@C
3899: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3900: processor's portion of the vector data. You MUST call VecRestoreArray1dRead()
3901: when you no longer need access to the array.
3903: Logically Collective
3905: Input Parameters:
3906: + x - the vector
3907: . m - first dimension of two dimensional array
3908: - mstart - first index you will use in first coordinate direction (often 0)
3910: Output Parameter:
3911: . a - location to put pointer to the array
3913: Level: developer
3915: Notes:
3916: For a vector obtained from DMCreateLocalVector() mstart are likely
3917: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3918: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3920: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3922: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3923: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3924: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3925: @*/
3926: PetscErrorCode VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3927: {
3928: PetscInt N;
3933: VecGetLocalSize(x,&N);
3935: VecGetArrayRead(x,(const PetscScalar**)a);
3936: *a -= mstart;
3937: return 0;
3938: }
3940: /*@C
3941: VecRestoreArray1dRead - Restores a vector after VecGetArray1dRead() has been called.
3943: Logically Collective
3945: Input Parameters:
3946: + x - the vector
3947: . m - first dimension of two dimensional array
3948: . mstart - first index you will use in first coordinate direction (often 0)
3949: - a - location of pointer to array obtained from VecGetArray21()
3951: Level: developer
3953: Notes:
3954: For regular PETSc vectors this routine does not involve any copies. For
3955: any special vectors that do not store local vector data in a contiguous
3956: array, this routine will copy the data back into the underlying
3957: vector data structure from the array obtained with VecGetArray1dRead().
3959: This routine actually zeros out the a pointer.
3961: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3962: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3963: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3964: @*/
3965: PetscErrorCode VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3966: {
3969: VecRestoreArrayRead(x,NULL);
3970: return 0;
3971: }
3973: /*@C
3974: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3975: processor's portion of the vector data. You MUST call VecRestoreArray3dRead()
3976: when you no longer need access to the array.
3978: Logically Collective
3980: Input Parameters:
3981: + x - the vector
3982: . m - first dimension of three dimensional array
3983: . n - second dimension of three dimensional array
3984: . p - third dimension of three dimensional array
3985: . mstart - first index you will use in first coordinate direction (often 0)
3986: . nstart - first index in the second coordinate direction (often 0)
3987: - pstart - first index in the third coordinate direction (often 0)
3989: Output Parameter:
3990: . a - location to put pointer to the array
3992: Level: developer
3994: Notes:
3995: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3996: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3997: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3998: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3dRead().
4000: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4002: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
4003: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
4004: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
4005: @*/
4006: PetscErrorCode VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
4007: {
4008: PetscInt i,N,j;
4009: const PetscScalar *aa;
4010: PetscScalar **b;
4015: VecGetLocalSize(x,&N);
4017: VecGetArrayRead(x,&aa);
4019: PetscMalloc(m*sizeof(PetscScalar**)+m*n*sizeof(PetscScalar*),a);
4020: b = (PetscScalar**)((*a) + m);
4021: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
4022: for (i=0; i<m; i++)
4023: for (j=0; j<n; j++)
4024: b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;
4025: *a -= mstart;
4026: return 0;
4027: }
4029: /*@C
4030: VecRestoreArray3dRead - Restores a vector after VecGetArray3dRead() has been called.
4032: Logically Collective
4034: Input Parameters:
4035: + x - the vector
4036: . m - first dimension of three dimensional array
4037: . n - second dimension of the three dimensional array
4038: . p - third dimension of the three dimensional array
4039: . mstart - first index you will use in first coordinate direction (often 0)
4040: . nstart - first index in the second coordinate direction (often 0)
4041: . pstart - first index in the third coordinate direction (often 0)
4042: - a - location of pointer to array obtained from VecGetArray3dRead()
4044: Level: developer
4046: Notes:
4047: For regular PETSc vectors this routine does not involve any copies. For
4048: any special vectors that do not store local vector data in a contiguous
4049: array, this routine will copy the data back into the underlying
4050: vector data structure from the array obtained with VecGetArray().
4052: This routine actually zeros out the a pointer.
4054: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
4055: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
4056: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
4057: @*/
4058: PetscErrorCode VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
4059: {
4060: void *dummy;
4065: dummy = (void*)(*a + mstart);
4066: PetscFree(dummy);
4067: VecRestoreArrayRead(x,NULL);
4068: return 0;
4069: }
4071: /*@C
4072: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
4073: processor's portion of the vector data. You MUST call VecRestoreArray4dRead()
4074: when you no longer need access to the array.
4076: Logically Collective
4078: Input Parameters:
4079: + x - the vector
4080: . m - first dimension of four dimensional array
4081: . n - second dimension of four dimensional array
4082: . p - third dimension of four dimensional array
4083: . q - fourth dimension of four dimensional array
4084: . mstart - first index you will use in first coordinate direction (often 0)
4085: . nstart - first index in the second coordinate direction (often 0)
4086: . pstart - first index in the third coordinate direction (often 0)
4087: - qstart - first index in the fourth coordinate direction (often 0)
4089: Output Parameter:
4090: . a - location to put pointer to the array
4092: Level: beginner
4094: Notes:
4095: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
4096: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
4097: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
4098: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
4100: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
4102: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
4103: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
4104: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
4105: @*/
4106: PetscErrorCode VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
4107: {
4108: PetscInt i,N,j,k;
4109: const PetscScalar *aa;
4110: PetscScalar ***b,**c;
4115: VecGetLocalSize(x,&N);
4117: VecGetArrayRead(x,&aa);
4119: PetscMalloc(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p*sizeof(PetscScalar*),a);
4120: b = (PetscScalar***)((*a) + m);
4121: c = (PetscScalar**)(b + m*n);
4122: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
4123: for (i=0; i<m; i++)
4124: for (j=0; j<n; j++)
4125: b[i*n+j] = c + i*n*p + j*p - pstart;
4126: for (i=0; i<m; i++)
4127: for (j=0; j<n; j++)
4128: for (k=0; k<p; k++)
4129: c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
4130: *a -= mstart;
4131: return 0;
4132: }
4134: /*@C
4135: VecRestoreArray4dRead - Restores a vector after VecGetArray3d() has been called.
4137: Logically Collective
4139: Input Parameters:
4140: + x - the vector
4141: . m - first dimension of four dimensional array
4142: . n - second dimension of the four dimensional array
4143: . p - third dimension of the four dimensional array
4144: . q - fourth dimension of the four dimensional array
4145: . mstart - first index you will use in first coordinate direction (often 0)
4146: . nstart - first index in the second coordinate direction (often 0)
4147: . pstart - first index in the third coordinate direction (often 0)
4148: . qstart - first index in the fourth coordinate direction (often 0)
4149: - a - location of pointer to array obtained from VecGetArray4dRead()
4151: Level: beginner
4153: Notes:
4154: For regular PETSc vectors this routine does not involve any copies. For
4155: any special vectors that do not store local vector data in a contiguous
4156: array, this routine will copy the data back into the underlying
4157: vector data structure from the array obtained with VecGetArray().
4159: This routine actually zeros out the a pointer.
4161: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
4162: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
4163: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
4164: @*/
4165: PetscErrorCode VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
4166: {
4167: void *dummy;
4172: dummy = (void*)(*a + mstart);
4173: PetscFree(dummy);
4174: VecRestoreArrayRead(x,NULL);
4175: return 0;
4176: }
4178: #if defined(PETSC_USE_DEBUG)
4180: /*@
4181: VecLockGet - Gets the current lock status of a vector
4183: Logically Collective on Vec
4185: Input Parameter:
4186: . x - the vector
4188: Output Parameter:
4189: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
4190: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
4192: Level: beginner
4194: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop()
4195: @*/
4196: PetscErrorCode VecLockGet(Vec x,PetscInt *state)
4197: {
4199: *state = x->lock;
4200: return 0;
4201: }
4203: /*@
4204: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from writing
4206: Logically Collective on Vec
4208: Input Parameter:
4209: . x - the vector
4211: Notes:
4212: If this is set then calls to VecGetArray() or VecSetValues() or any other routines that change the vectors values will fail.
4214: The call can be nested, i.e., called multiple times on the same vector, but each VecLockReadPush(x) has to have one matching
4215: VecLockReadPop(x), which removes the latest read-only lock.
4217: Level: beginner
4219: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPop(), VecLockGet()
4220: @*/
4221: PetscErrorCode VecLockReadPush(Vec x)
4222: {
4225: x->lock++;
4226: return 0;
4227: }
4229: /*@
4230: VecLockReadPop - Pops a read-only lock from a vector
4232: Logically Collective on Vec
4234: Input Parameter:
4235: . x - the vector
4237: Level: beginner
4239: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockGet()
4240: @*/
4241: PetscErrorCode VecLockReadPop(Vec x)
4242: {
4244: x->lock--;
4246: return 0;
4247: }
4249: /*@C
4250: VecLockWriteSet_Private - Lock or unlock a vector for exclusive read/write access
4252: Logically Collective on Vec
4254: Input Parameters:
4255: + x - the vector
4256: - flg - PETSC_TRUE to lock the vector for writing; PETSC_FALSE to unlock it.
4258: Notes:
4259: The function is usefull in split-phase computations, which usually have a begin phase and an end phase.
4260: One can call VecLockWriteSet_Private(x,PETSC_TRUE) in the begin phase to lock a vector for exclusive
4261: access, and call VecLockWriteSet_Private(x,PETSC_FALSE) in the end phase to unlock the vector from exclusive
4262: access. In this way, one is ensured no other operations can access the vector in between. The code may like
4264: VecGetArray(x,&xdata); // begin phase
4265: VecLockWriteSet_Private(v,PETSC_TRUE);
4267: Other operations, which can not acceess x anymore (they can access xdata, of course)
4269: VecRestoreArray(x,&vdata); // end phase
4270: VecLockWriteSet_Private(v,PETSC_FALSE);
4272: The call can not be nested on the same vector, in other words, one can not call VecLockWriteSet_Private(x,PETSC_TRUE)
4273: again before calling VecLockWriteSet_Private(v,PETSC_FALSE).
4275: Level: beginner
4277: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop(), VecLockGet()
4278: @*/
4279: PetscErrorCode VecLockWriteSet_Private(Vec x,PetscBool flg)
4280: {
4282: if (flg) {
4285: else x->lock = -1;
4286: } else {
4288: x->lock = 0;
4289: }
4290: return 0;
4291: }
4293: /*@
4294: VecLockPush - Pushes a read-only lock on a vector to prevent it from writing
4296: Level: deprecated
4298: .seealso: VecLockReadPush()
4299: @*/
4300: PetscErrorCode VecLockPush(Vec x)
4301: {
4302: VecLockReadPush(x);
4303: return 0;
4304: }
4306: /*@
4307: VecLockPop - Pops a read-only lock from a vector
4309: Level: deprecated
4311: .seealso: VecLockReadPop()
4312: @*/
4313: PetscErrorCode VecLockPop(Vec x)
4314: {
4315: VecLockReadPop(x);
4316: return 0;
4317: }
4319: #endif