Actual source code: rvector.c
petsc-3.13.6 2020-09-29
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/vecimpl.h>
6: #if defined(PETSC_HAVE_CUDA)
7: #include <../src/vec/vec/impls/dvecimpl.h>
8: #include <petsc/private/cudavecimpl.h>
9: #endif
10: static PetscInt VecGetSubVectorSavedStateId = -1;
12: PETSC_EXTERN PetscErrorCode VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)
13: {
14: #if defined(PETSC_USE_DEBUG)
15: PetscErrorCode ierr;
16: PetscInt n,i;
17: const PetscScalar *x;
20: #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL)
21: if ((vec->petscnative || vec->ops->getarray) && (vec->offloadmask & PETSC_OFFLOAD_CPU)) {
22: #else
23: if (vec->petscnative || vec->ops->getarray) {
24: #endif
25: VecGetLocalSize(vec,&n);
26: VecGetArrayRead(vec,&x);
27: for (i=0; i<n; i++) {
28: if (begin) {
29: if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at beginning of function: Parameter number %D",i,argnum);
30: } else {
31: if (PetscIsInfOrNanScalar(x[i])) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FP,"Vec entry at local location %D is not-a-number or infinite at end of function: Parameter number %D",i,argnum);
32: }
33: }
34: VecRestoreArrayRead(vec,&x);
35: }
36: return(0);
37: #else
38: return 0;
39: #endif
40: }
42: /*@
43: VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
45: Logically Collective on Vec
47: Input Parameters:
48: . x, y - the vectors
50: Output Parameter:
51: . max - the result
53: Level: advanced
55: Notes:
56: x and y may be the same vector
57: if a particular y_i is zero, it is treated as 1 in the above formula
59: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
60: @*/
61: PetscErrorCode VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
62: {
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 inbalance 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
107: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDotRealPart()
108: @*/
109: PetscErrorCode VecDot(Vec x,Vec y,PetscScalar *val)
110: {
120: VecCheckSameSize(x,1,y,2);
122: PetscLogEventBegin(VEC_Dot,x,y,0,0);
123: (*x->ops->dot)(x,y,val);
124: PetscLogEventEnd(VEC_Dot,x,y,0,0);
125: return(0);
126: }
128: /*@
129: VecDotRealPart - Computes the real part of the vector dot product.
131: Collective on Vec
133: Input Parameters:
134: . x, y - the vectors
136: Output Parameter:
137: . val - the real part of the dot product;
139: Performance Issues:
140: $ per-processor memory bandwidth
141: $ interprocessor latency
142: $ work load inbalance that causes certain processes to arrive much earlier than others
144: Notes for Users of Complex Numbers:
145: See VecDot() for more details on the definition of the dot product for complex numbers
147: For real numbers this returns the same value as VecDot()
149: 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
150: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
152: Developer Note: This is not currently optimized to compute only the real part of the dot product.
154: Level: intermediate
157: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDot(), VecDotNorm2()
158: @*/
159: PetscErrorCode VecDotRealPart(Vec x,Vec y,PetscReal *val)
160: {
162: PetscScalar fdot;
165: VecDot(x,y,&fdot);
166: *val = PetscRealPart(fdot);
167: return(0);
168: }
170: /*@
171: VecNorm - Computes the vector norm.
173: Collective on Vec
175: Input Parameters:
176: + x - the vector
177: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
178: NORM_1_AND_2, which computes both norms and stores them
179: in a two element array.
181: Output Parameter:
182: . val - the norm
184: Notes:
185: $ NORM_1 denotes sum_i |x_i|
186: $ NORM_2 denotes sqrt(sum_i |x_i|^2)
187: $ NORM_INFINITY denotes max_i |x_i|
189: For complex numbers NORM_1 will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
190: norm of the absolutely values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
191: the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
192: people expect the former.
194: Level: intermediate
196: Performance Issues:
197: $ per-processor memory bandwidth
198: $ interprocessor latency
199: $ work load inbalance that causes certain processes to arrive much earlier than others
202: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
203: VecNormBegin(), VecNormEnd()
205: @*/
207: PetscErrorCode VecNorm(Vec x,NormType type,PetscReal *val)
208: {
209: PetscBool flg;
217: /*
218: * Cached data?
219: */
220: if (type!=NORM_1_AND_2) {
221: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
222: if (flg) return(0);
223: }
224: PetscLogEventBegin(VEC_Norm,x,0,0,0);
225: (*x->ops->norm)(x,type,val);
226: PetscLogEventEnd(VEC_Norm,x,0,0,0);
227: if (type!=NORM_1_AND_2) {
228: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
229: }
230: return(0);
231: }
233: /*@
234: VecNormAvailable - Returns the vector norm if it is already known.
236: Not Collective
238: Input Parameters:
239: + x - the vector
240: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
241: NORM_1_AND_2, which computes both norms and stores them
242: in a two element array.
244: Output Parameter:
245: + available - PETSC_TRUE if the val returned is valid
246: - val - the norm
248: Notes:
249: $ NORM_1 denotes sum_i |x_i|
250: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
251: $ NORM_INFINITY denotes max_i |x_i|
253: Level: intermediate
255: Performance Issues:
256: $ per-processor memory bandwidth
257: $ interprocessor latency
258: $ work load inbalance that causes certain processes to arrive much earlier than others
260: Compile Option:
261: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
262: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
263: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
266: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
267: VecNormBegin(), VecNormEnd()
269: @*/
270: PetscErrorCode VecNormAvailable(Vec x,NormType type,PetscBool *available,PetscReal *val)
271: {
279: *available = PETSC_FALSE;
280: if (type!=NORM_1_AND_2) {
281: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
282: }
283: return(0);
284: }
286: /*@
287: VecNormalize - Normalizes a vector by 2-norm.
289: Collective on Vec
291: Input Parameters:
292: + x - the vector
294: Output Parameter:
295: . x - the normalized vector
296: - val - the vector norm before normalization
298: Level: intermediate
301: @*/
302: PetscErrorCode VecNormalize(Vec x,PetscReal *val)
303: {
305: PetscReal norm;
310: PetscLogEventBegin(VEC_Normalize,x,0,0,0);
311: VecNorm(x,NORM_2,&norm);
312: if (norm == 0.0) {
313: PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
314: } else if (norm != 1.0) {
315: PetscScalar tmp = 1.0/norm;
316: VecScale(x,tmp);
317: }
318: if (val) *val = norm;
319: PetscLogEventEnd(VEC_Normalize,x,0,0,0);
320: return(0);
321: }
323: /*@C
324: VecMax - Determines the vector component with maximum real part and its location.
326: Collective on Vec
328: Input Parameter:
329: . x - the vector
331: Output Parameters:
332: + p - the location of val (pass NULL if you don't want this)
333: - val - the maximum component
335: Notes:
336: Returns the value PETSC_MIN_REAL and p = -1 if the vector is of length 0.
338: Returns the smallest index with the maximum value
339: Level: intermediate
342: .seealso: VecNorm(), VecMin()
343: @*/
344: PetscErrorCode VecMax(Vec x,PetscInt *p,PetscReal *val)
345: {
352: PetscLogEventBegin(VEC_Max,x,0,0,0);
353: (*x->ops->max)(x,p,val);
354: PetscLogEventEnd(VEC_Max,x,0,0,0);
355: return(0);
356: }
358: /*@C
359: VecMin - Determines the vector component with minimum real part and its location.
361: Collective on Vec
363: Input Parameters:
364: . x - the vector
366: Output Parameter:
367: + p - the location of val (pass NULL if you don't want this location)
368: - val - the minimum component
370: Level: intermediate
372: Notes:
373: Returns the value PETSC_MAX_REAL and p = -1 if the vector is of length 0.
375: This returns the smallest index with the minumum value
378: .seealso: VecMax()
379: @*/
380: PetscErrorCode VecMin(Vec x,PetscInt *p,PetscReal *val)
381: {
388: PetscLogEventBegin(VEC_Min,x,0,0,0);
389: (*x->ops->min)(x,p,val);
390: PetscLogEventEnd(VEC_Min,x,0,0,0);
391: return(0);
392: }
394: /*@
395: VecTDot - Computes an indefinite vector dot product. That is, this
396: routine does NOT use the complex conjugate.
398: Collective on Vec
400: Input Parameters:
401: . x, y - the vectors
403: Output Parameter:
404: . val - the dot product
406: Notes for Users of Complex Numbers:
407: For complex vectors, VecTDot() computes the indefinite form
408: $ val = (x,y) = y^T x,
409: where y^T denotes the transpose of y.
411: Use VecDot() for the inner product
412: $ val = (x,y) = y^H x,
413: where y^H denotes the conjugate transpose of y.
415: Level: intermediate
417: .seealso: VecDot(), VecMTDot()
418: @*/
419: PetscErrorCode VecTDot(Vec x,Vec y,PetscScalar *val)
420: {
430: VecCheckSameSize(x,1,y,2);
432: PetscLogEventBegin(VEC_TDot,x,y,0,0);
433: (*x->ops->tdot)(x,y,val);
434: PetscLogEventEnd(VEC_TDot,x,y,0,0);
435: return(0);
436: }
438: /*@
439: VecScale - Scales a vector.
441: Not collective on Vec
443: Input Parameters:
444: + x - the vector
445: - alpha - the scalar
447: Output Parameter:
448: . x - the scaled vector
450: Note:
451: For a vector with n components, VecScale() computes
452: $ x[i] = alpha * x[i], for i=1,...,n.
454: Level: intermediate
457: @*/
458: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
459: {
460: PetscReal norms[4] = {0.0,0.0,0.0, 0.0};
461: PetscBool flgs[4];
463: PetscInt i;
468: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
469: PetscLogEventBegin(VEC_Scale,x,0,0,0);
470: if (alpha != (PetscScalar)1.0) {
471: VecSetErrorIfLocked(x,1);
472: /* get current stashed norms */
473: for (i=0; i<4; i++) {
474: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[i],norms[i],flgs[i]);
475: }
476: (*x->ops->scale)(x,alpha);
477: PetscObjectStateIncrease((PetscObject)x);
478: /* put the scaled stashed norms back into the Vec */
479: for (i=0; i<4; i++) {
480: if (flgs[i]) {
481: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[i],PetscAbsScalar(alpha)*norms[i]);
482: }
483: }
484: }
485: PetscLogEventEnd(VEC_Scale,x,0,0,0);
486: return(0);
487: }
489: /*@
490: VecSet - Sets all components of a vector to a single scalar value.
492: Logically Collective on Vec
494: Input Parameters:
495: + x - the vector
496: - alpha - the scalar
498: Output Parameter:
499: . x - the vector
501: Note:
502: For a vector of dimension n, VecSet() computes
503: $ x[i] = alpha, for i=1,...,n,
504: so that all vector entries then equal the identical
505: scalar value, alpha. Use the more general routine
506: VecSetValues() to set different vector entries.
508: You CANNOT call this after you have called VecSetValues() but before you call
509: VecAssemblyBegin/End().
511: Level: beginner
513: .seealso VecSetValues(), VecSetValuesBlocked(), VecSetRandom()
515: @*/
516: PetscErrorCode VecSet(Vec x,PetscScalar alpha)
517: {
518: PetscReal val;
524: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"You cannot call this after you have called VecSetValues() but\n before you have called VecAssemblyBegin/End()");
526: VecSetErrorIfLocked(x,1);
528: PetscLogEventBegin(VEC_Set,x,0,0,0);
529: (*x->ops->set)(x,alpha);
530: PetscLogEventEnd(VEC_Set,x,0,0,0);
531: PetscObjectStateIncrease((PetscObject)x);
533: /* norms can be simply set (if |alpha|*N not too large) */
534: val = PetscAbsScalar(alpha);
535: if (x->map->N == 0) {
536: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],0.0l);
537: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],0.0);
538: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],0.0);
539: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],0.0);
540: } else if (val > PETSC_MAX_REAL/x->map->N) {
541: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
542: } else {
543: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_1],x->map->N * val);
544: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_INFINITY],val);
545: val = PetscSqrtReal((PetscReal)x->map->N) * val;
546: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_2],val);
547: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[NORM_FROBENIUS],val);
548: }
549: return(0);
550: }
553: /*@
554: VecAXPY - Computes y = alpha x + y.
556: Logically Collective on Vec
558: Input Parameters:
559: + alpha - the scalar
560: - x, y - the vectors
562: Output Parameter:
563: . y - output vector
565: Level: intermediate
567: Notes:
568: x and y MUST be different vectors
569: This routine is optimized for alpha of 0.0, otherwise it calls the BLAS routine
571: $ VecAXPY(y,alpha,x) y = alpha x + y
572: $ VecAYPX(y,beta,x) y = x + beta y
573: $ VecAXPBY(y,alpha,beta,x) y = alpha x + beta y
574: $ VecWAXPY(w,alpha,x,y) w = alpha x + y
575: $ VecAXPBYPCZ(w,alpha,beta,gamma,x,y) z = alpha x + beta y + gamma z
576: $ VecMAXPY(y,nv,alpha[],x[]) y = sum alpha[i] x[i] + y
579: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPBYPCZ(), VecAXPBY()
580: @*/
581: PetscErrorCode VecAXPY(Vec y,PetscScalar alpha,Vec x)
582: {
591: VecCheckSameSize(x,1,y,3);
592: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
594: if (alpha == (PetscScalar)0.0) return(0);
595: VecSetErrorIfLocked(y,1);
597: VecLockReadPush(x);
598: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
599: (*y->ops->axpy)(y,alpha,x);
600: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
601: VecLockReadPop(x);
602: PetscObjectStateIncrease((PetscObject)y);
603: return(0);
604: }
606: /*@
607: VecAXPBY - Computes y = alpha x + beta y.
609: Logically Collective on Vec
611: Input Parameters:
612: + alpha,beta - the scalars
613: - x, y - the vectors
615: Output Parameter:
616: . y - output vector
618: Level: intermediate
620: Notes:
621: x and y MUST be different vectors
622: The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
625: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ()
626: @*/
627: PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
628: {
637: VecCheckSameSize(y,1,x,4);
638: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
641: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)1.0) return(0);
642: VecSetErrorIfLocked(y,1);
643: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
644: (*y->ops->axpby)(y,alpha,beta,x);
645: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
646: PetscObjectStateIncrease((PetscObject)y);
647: return(0);
648: }
650: /*@
651: VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
653: Logically Collective on Vec
655: Input Parameters:
656: + alpha,beta, gamma - the scalars
657: - x, y, z - the vectors
659: Output Parameter:
660: . z - output vector
662: Level: intermediate
664: Notes:
665: x, y and z must be different vectors
666: The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
669: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBY()
670: @*/
671: PetscErrorCode VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
672: {
684: VecCheckSameSize(x,1,y,5);
685: VecCheckSameSize(x,1,z,6);
686: if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
687: if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
691: if (alpha == (PetscScalar)0.0 && beta == (PetscScalar)0.0 && gamma == (PetscScalar)1.0) return(0);
692: VecSetErrorIfLocked(z,1);
694: PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
695: (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
696: PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
697: PetscObjectStateIncrease((PetscObject)z);
698: return(0);
699: }
701: /*@
702: VecAYPX - Computes y = x + beta y.
704: Logically Collective on Vec
706: Input Parameters:
707: + beta - the scalar
708: - x, y - the vectors
710: Output Parameter:
711: . y - output vector
713: Level: intermediate
715: Notes:
716: x and y MUST be different vectors
717: The implementation is optimized for beta of -1.0, 0.0, and 1.0
720: .seealso: VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
721: @*/
722: PetscErrorCode VecAYPX(Vec y,PetscScalar beta,Vec x)
723: {
732: VecCheckSameSize(x,1,y,3);
733: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
735: VecSetErrorIfLocked(y,1);
737: PetscLogEventBegin(VEC_AYPX,x,y,0,0);
738: (*y->ops->aypx)(y,beta,x);
739: PetscLogEventEnd(VEC_AYPX,x,y,0,0);
740: PetscObjectStateIncrease((PetscObject)y);
741: return(0);
742: }
745: /*@
746: VecWAXPY - Computes w = alpha x + y.
748: Logically Collective on Vec
750: Input Parameters:
751: + alpha - the scalar
752: - x, y - the vectors
754: Output Parameter:
755: . w - the result
757: Level: intermediate
759: Notes:
760: w cannot be either x or y, but x and y can be the same
761: The implementation is optimzed for alpha of -1.0, 0.0, and 1.0
764: .seealso: VecAXPY(), VecAYPX(), VecAXPBY(), VecMAXPY(), VecAXPBYPCZ()
765: @*/
766: PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
767: {
779: VecCheckSameSize(x,3,y,4);
780: VecCheckSameSize(x,3,w,1);
781: if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
782: if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");
784: VecSetErrorIfLocked(w,1);
786: PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
787: (*w->ops->waxpy)(w,alpha,x,y);
788: PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
789: PetscObjectStateIncrease((PetscObject)w);
790: return(0);
791: }
794: /*@C
795: VecSetValues - Inserts or adds values into certain locations of a vector.
797: Not Collective
799: Input Parameters:
800: + x - vector to insert in
801: . ni - number of elements to add
802: . ix - indices where to add
803: . y - array of values
804: - iora - either INSERT_VALUES or ADD_VALUES, where
805: ADD_VALUES adds values to any existing entries, and
806: INSERT_VALUES replaces existing entries with new values
808: Notes:
809: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
811: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
812: options cannot be mixed without intervening calls to the assembly
813: routines.
815: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
816: MUST be called after all calls to VecSetValues() have been completed.
818: VecSetValues() uses 0-based indices in Fortran as well as in C.
820: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
821: negative indices may be passed in ix. These rows are
822: simply ignored. This allows easily inserting element load matrices
823: with homogeneous Dirchlet boundary conditions that you don't want represented
824: in the vector.
826: Level: beginner
828: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
829: VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
830: @*/
831: PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
832: {
837: if (!ni) return(0);
842: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
843: (*x->ops->setvalues)(x,ni,ix,y,iora);
844: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
845: PetscObjectStateIncrease((PetscObject)x);
846: return(0);
847: }
849: /*@C
850: VecGetValues - Gets values from certain locations of a vector. Currently
851: can only get values on the same processor
853: Not Collective
855: Input Parameters:
856: + x - vector to get values from
857: . ni - number of elements to get
858: - ix - indices where to get them from (in global 1d numbering)
860: Output Parameter:
861: . y - array of values
863: Notes:
864: The user provides the allocated array y; it is NOT allocated in this routine
866: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
868: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
870: VecGetValues() uses 0-based indices in Fortran as well as in C.
872: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
873: negative indices may be passed in ix. These rows are
874: simply ignored.
876: Level: beginner
878: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues()
879: @*/
880: PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
881: {
886: if (!ni) return(0);
890: (*x->ops->getvalues)(x,ni,ix,y);
891: return(0);
892: }
894: /*@C
895: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
897: Not Collective
899: Input Parameters:
900: + x - vector to insert in
901: . ni - number of blocks to add
902: . ix - indices where to add in block count, rather than element count
903: . y - array of values
904: - iora - either INSERT_VALUES or ADD_VALUES, where
905: ADD_VALUES adds values to any existing entries, and
906: INSERT_VALUES replaces existing entries with new values
908: Notes:
909: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
910: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
912: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
913: options cannot be mixed without intervening calls to the assembly
914: routines.
916: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
917: MUST be called after all calls to VecSetValuesBlocked() have been completed.
919: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
921: Negative indices may be passed in ix, these rows are
922: simply ignored. This allows easily inserting element load matrices
923: with homogeneous Dirchlet boundary conditions that you don't want represented
924: in the vector.
926: Level: intermediate
928: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
929: VecSetValues()
930: @*/
931: PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
932: {
937: if (!ni) return(0);
942: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
943: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
944: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
945: PetscObjectStateIncrease((PetscObject)x);
946: return(0);
947: }
950: /*@C
951: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
952: using a local ordering of the nodes.
954: Not Collective
956: Input Parameters:
957: + x - vector to insert in
958: . ni - number of elements to add
959: . ix - indices where to add
960: . y - array of values
961: - iora - either INSERT_VALUES or ADD_VALUES, where
962: ADD_VALUES adds values to any existing entries, and
963: INSERT_VALUES replaces existing entries with new values
965: Level: intermediate
967: Notes:
968: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
970: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
971: options cannot be mixed without intervening calls to the assembly
972: routines.
974: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
975: MUST be called after all calls to VecSetValuesLocal() have been completed.
977: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
979: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
980: VecSetValuesBlockedLocal()
981: @*/
982: PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
983: {
985: PetscInt lixp[128],*lix = lixp;
989: if (!ni) return(0);
994: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
995: if (!x->ops->setvalueslocal) {
996: if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
997: if (ni > 128) {
998: PetscMalloc1(ni,&lix);
999: }
1000: ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
1001: (*x->ops->setvalues)(x,ni,lix,y,iora);
1002: if (ni > 128) {
1003: PetscFree(lix);
1004: }
1005: } else {
1006: (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
1007: }
1008: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1009: PetscObjectStateIncrease((PetscObject)x);
1010: return(0);
1011: }
1013: /*@
1014: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1015: using a local ordering of the nodes.
1017: Not Collective
1019: Input Parameters:
1020: + x - vector to insert in
1021: . ni - number of blocks to add
1022: . ix - indices where to add in block count, not element count
1023: . y - array of values
1024: - iora - either INSERT_VALUES or ADD_VALUES, where
1025: ADD_VALUES adds values to any existing entries, and
1026: INSERT_VALUES replaces existing entries with new values
1028: Level: intermediate
1030: Notes:
1031: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
1032: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
1034: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1035: options cannot be mixed without intervening calls to the assembly
1036: routines.
1038: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1039: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
1041: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
1044: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
1045: VecSetLocalToGlobalMapping()
1046: @*/
1047: PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1048: {
1050: PetscInt lixp[128],*lix = lixp;
1054: if (!ni) return(0);
1058: if (ni > 128) {
1059: PetscMalloc1(ni,&lix);
1060: }
1062: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1063: ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
1064: (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1065: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1066: if (ni > 128) {
1067: PetscFree(lix);
1068: }
1069: PetscObjectStateIncrease((PetscObject)x);
1070: return(0);
1071: }
1073: /*@
1074: VecMTDot - Computes indefinite vector multiple dot products.
1075: That is, it does NOT use the complex conjugate.
1077: Collective on Vec
1079: Input Parameters:
1080: + x - one vector
1081: . nv - number of vectors
1082: - y - array of vectors. Note that vectors are pointers
1084: Output Parameter:
1085: . val - array of the dot products
1087: Notes for Users of Complex Numbers:
1088: For complex vectors, VecMTDot() computes the indefinite form
1089: $ val = (x,y) = y^T x,
1090: where y^T denotes the transpose of y.
1092: Use VecMDot() for the inner product
1093: $ val = (x,y) = y^H x,
1094: where y^H denotes the conjugate transpose of y.
1096: Level: intermediate
1099: .seealso: VecMDot(), VecTDot()
1100: @*/
1101: PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1102: {
1108: if (!nv) return(0);
1115: VecCheckSameSize(x,1,*y,3);
1117: PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1118: (*x->ops->mtdot)(x,nv,y,val);
1119: PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1120: return(0);
1121: }
1123: /*@
1124: VecMDot - Computes vector multiple dot products.
1126: Collective on Vec
1128: Input Parameters:
1129: + x - one vector
1130: . nv - number of vectors
1131: - y - array of vectors.
1133: Output Parameter:
1134: . val - array of the dot products (does not allocate the array)
1136: Notes for Users of Complex Numbers:
1137: For complex vectors, VecMDot() computes
1138: $ val = (x,y) = y^H x,
1139: where y^H denotes the conjugate transpose of y.
1141: Use VecMTDot() for the indefinite form
1142: $ val = (x,y) = y^T x,
1143: where y^T denotes the transpose of y.
1145: Level: intermediate
1148: .seealso: VecMTDot(), VecDot()
1149: @*/
1150: PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1151: {
1157: if (!nv) return(0);
1158: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1165: VecCheckSameSize(x,1,*y,3);
1167: PetscLogEventBegin(VEC_MDot,x,*y,0,0);
1168: (*x->ops->mdot)(x,nv,y,val);
1169: PetscLogEventEnd(VEC_MDot,x,*y,0,0);
1170: return(0);
1171: }
1173: /*@
1174: VecMAXPY - Computes y = y + sum alpha[i] x[i]
1176: Logically Collective on Vec
1178: Input Parameters:
1179: + nv - number of scalars and x-vectors
1180: . alpha - array of scalars
1181: . y - one vector
1182: - x - array of vectors
1184: Level: intermediate
1186: Notes:
1187: y cannot be any of the x vectors
1189: .seealso: VecAYPX(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
1190: @*/
1191: PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1192: {
1194: PetscInt i;
1195: PetscBool nonzero;
1200: if (!nv) return(0);
1201: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1208: VecCheckSameSize(y,1,*x,4);
1210: for (i=0, nonzero = PETSC_FALSE; i<nv && !nonzero; i++) nonzero = (PetscBool)(nonzero || alpha[i] != (PetscScalar)0.0);
1211: if (!nonzero) return(0);
1212: VecSetErrorIfLocked(y,1);
1213: PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1214: (*y->ops->maxpy)(y,nv,alpha,x);
1215: PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1216: PetscObjectStateIncrease((PetscObject)y);
1217: return(0);
1218: }
1220: /*@
1221: VecGetSubVector - Gets a vector representing part of another vector
1223: Collective on IS
1225: Input Arguments:
1226: + X - vector from which to extract a subvector
1227: - is - index set representing portion of X to extract
1229: Output Arguments:
1230: . Y - subvector corresponding to is
1232: Level: advanced
1234: Notes:
1235: The subvector Y should be returned with VecRestoreSubVector().
1237: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1238: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1240: .seealso: MatCreateSubMatrix()
1241: @*/
1242: PetscErrorCode VecGetSubVector(Vec X,IS is,Vec *Y)
1243: {
1244: PetscErrorCode ierr;
1245: Vec Z;
1251: if (X->ops->getsubvector) {
1252: (*X->ops->getsubvector)(X,is,&Z);
1253: } else { /* Default implementation currently does no caching */
1254: PetscInt gstart,gend,start;
1255: PetscBool contiguous,gcontiguous;
1256: VecGetOwnershipRange(X,&gstart,&gend);
1257: ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1258: MPIU_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1259: if (gcontiguous) { /* We can do a no-copy implementation */
1260: PetscInt n,N,bs;
1261: PetscInt state;
1263: ISGetSize(is,&N);
1264: ISGetLocalSize(is,&n);
1265: VecGetBlockSize(X,&bs);
1267: if (n%bs || bs == 1) bs = -1; /* Do not decide block size if we do not have to */
1268: VecLockGet(X,&state);
1269: if (state) {
1270: const PetscScalar *x;
1271: VecGetArrayRead(X,&x);
1272: VecCreate(PetscObjectComm((PetscObject)X),&Z);
1273: VecSetType(Z,((PetscObject)X)->type_name);
1274: VecSetSizes(Z,n,N);
1275: VecSetBlockSize(Z,bs);
1276: VecPlaceArray(Z,(PetscScalar*)x+start);
1277: VecLockReadPush(Z);
1278: VecRestoreArrayRead(X,&x);
1279: } else {
1280: PetscScalar *x;
1281: VecGetArray(X,&x);
1282: VecCreate(PetscObjectComm((PetscObject)X),&Z);
1283: VecSetType(Z,((PetscObject)X)->type_name);
1284: VecSetSizes(Z,n,N);
1285: VecSetBlockSize(Z,bs);
1286: VecPlaceArray(Z,(PetscScalar*)x+start);
1287: VecRestoreArray(X,&x);
1288: }
1289: Z->ops->placearray = NULL;
1290: Z->ops->replacearray = NULL;
1291: } else { /* Have to create a scatter and do a copy */
1292: VecScatter scatter;
1293: PetscInt n,N;
1294: ISGetLocalSize(is,&n);
1295: ISGetSize(is,&N);
1296: VecCreate(PetscObjectComm((PetscObject)is),&Z);
1297: VecSetSizes(Z,n,N);
1298: VecSetType(Z,((PetscObject)X)->type_name);
1299: VecScatterCreate(X,is,Z,NULL,&scatter);
1300: VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1301: VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1302: PetscObjectCompose((PetscObject)Z,"VecGetSubVector_Scatter",(PetscObject)scatter);
1303: VecScatterDestroy(&scatter);
1304: }
1305: }
1306: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1307: if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
1308: PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);
1309: *Y = Z;
1310: return(0);
1311: }
1313: /*@
1314: VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1316: Collective on IS
1318: Input Arguments:
1319: + X - vector from which subvector was obtained
1320: . is - index set representing the subset of X
1321: - Y - subvector being restored
1323: Level: advanced
1325: .seealso: VecGetSubVector()
1326: @*/
1327: PetscErrorCode VecRestoreSubVector(Vec X,IS is,Vec *Y)
1328: {
1336: if (X->ops->restoresubvector) {
1337: (*X->ops->restoresubvector)(X,is,Y);
1338: } else {
1339: PETSC_UNUSED PetscObjectState dummystate = 0;
1340: PetscBool valid;
1341: PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,valid);
1342: if (!valid) {
1343: VecScatter scatter;
1345: PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);
1346: if (scatter) {
1347: VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1348: VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1349: }
1350: }
1351: VecDestroy(Y);
1352: }
1353: return(0);
1354: }
1356: /*@
1357: VecGetLocalVectorRead - Maps the local portion of a vector into a
1358: vector. You must call VecRestoreLocalVectorRead() when the local
1359: vector is no longer needed.
1361: Not collective.
1363: Input parameter:
1364: . v - The vector for which the local vector is desired.
1366: Output parameter:
1367: . w - Upon exit this contains the local vector.
1369: Level: beginner
1371: Notes:
1372: This function is similar to VecGetArrayRead() which maps the local
1373: portion into a raw pointer. VecGetLocalVectorRead() is usually
1374: almost as efficient as VecGetArrayRead() but in certain circumstances
1375: VecGetLocalVectorRead() can be much more efficient than
1376: VecGetArrayRead(). This is because the construction of a contiguous
1377: array representing the vector data required by VecGetArrayRead() can
1378: be an expensive operation for certain vector types. For example, for
1379: GPU vectors VecGetArrayRead() requires that the data between device
1380: and host is synchronized.
1382: Unlike VecGetLocalVector(), this routine is not collective and
1383: preserves cached information.
1385: .seealso: VecRestoreLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1386: @*/
1387: PetscErrorCode VecGetLocalVectorRead(Vec v,Vec w)
1388: {
1390: PetscScalar *a;
1395: VecCheckSameLocalSize(v,1,w,2);
1396: if (v->ops->getlocalvectorread) {
1397: (*v->ops->getlocalvectorread)(v,w);
1398: } else {
1399: VecGetArrayRead(v,(const PetscScalar**)&a);
1400: VecPlaceArray(w,a);
1401: }
1402: return(0);
1403: }
1405: /*@
1406: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1407: previously mapped into a vector using VecGetLocalVectorRead().
1409: Not collective.
1411: Input parameter:
1412: + v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
1413: - w - The vector into which the local portion of v was mapped.
1415: Level: beginner
1417: .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1418: @*/
1419: PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
1420: {
1422: PetscScalar *a;
1427: if (v->ops->restorelocalvectorread) {
1428: (*v->ops->restorelocalvectorread)(v,w);
1429: } else {
1430: VecGetArrayRead(w,(const PetscScalar**)&a);
1431: VecRestoreArrayRead(v,(const PetscScalar**)&a);
1432: VecResetArray(w);
1433: }
1434: return(0);
1435: }
1437: /*@
1438: VecGetLocalVector - Maps the local portion of a vector into a
1439: vector.
1441: Collective on v, not collective on w.
1443: Input parameter:
1444: . v - The vector for which the local vector is desired.
1446: Output parameter:
1447: . w - Upon exit this contains the local vector.
1449: Level: beginner
1451: Notes:
1452: This function is similar to VecGetArray() which maps the local
1453: portion into a raw pointer. VecGetLocalVector() is usually about as
1454: efficient as VecGetArray() but in certain circumstances
1455: VecGetLocalVector() can be much more efficient than VecGetArray().
1456: This is because the construction of a contiguous array representing
1457: the vector data required by VecGetArray() can be an expensive
1458: operation for certain vector types. For example, for GPU vectors
1459: VecGetArray() requires that the data between device and host is
1460: synchronized.
1462: .seealso: VecRestoreLocalVector(), VecGetLocalVectorRead(), VecGetArrayRead(), VecGetArray()
1463: @*/
1464: PetscErrorCode VecGetLocalVector(Vec v,Vec w)
1465: {
1467: PetscScalar *a;
1472: VecCheckSameLocalSize(v,1,w,2);
1473: if (v->ops->getlocalvector) {
1474: (*v->ops->getlocalvector)(v,w);
1475: } else {
1476: VecGetArray(v,&a);
1477: VecPlaceArray(w,a);
1478: }
1479: return(0);
1480: }
1482: /*@
1483: VecRestoreLocalVector - Unmaps the local portion of a vector
1484: previously mapped into a vector using VecGetLocalVector().
1486: Logically collective.
1488: Input parameter:
1489: + v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
1490: - w - The vector into which the local portion of v was mapped.
1492: Level: beginner
1494: .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
1495: @*/
1496: PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
1497: {
1499: PetscScalar *a;
1504: if (v->ops->restorelocalvector) {
1505: (*v->ops->restorelocalvector)(v,w);
1506: } else {
1507: VecGetArray(w,&a);
1508: VecRestoreArray(v,&a);
1509: VecResetArray(w);
1510: }
1511: return(0);
1512: }
1514: /*@C
1515: VecGetArray - Returns a pointer to a contiguous array that contains this
1516: processor's portion of the vector data. For the standard PETSc
1517: vectors, VecGetArray() returns a pointer to the local data array and
1518: does not use any copies. If the underlying vector data is not stored
1519: in a contiguous array this routine will copy the data to a contiguous
1520: array and return a pointer to that. You MUST call VecRestoreArray()
1521: when you no longer need access to the array.
1523: Logically Collective on Vec
1525: Input Parameter:
1526: . x - the vector
1528: Output Parameter:
1529: . a - location to put pointer to the array
1531: Fortran Note:
1532: This routine is used differently from Fortran 77
1533: $ Vec x
1534: $ PetscScalar x_array(1)
1535: $ PetscOffset i_x
1536: $ PetscErrorCode ierr
1537: $ call VecGetArray(x,x_array,i_x,ierr)
1538: $
1539: $ Access first local entry in vector with
1540: $ value = x_array(i_x + 1)
1541: $
1542: $ ...... other code
1543: $ call VecRestoreArray(x,x_array,i_x,ierr)
1544: For Fortran 90 see VecGetArrayF90()
1546: See the Fortran chapter of the users manual and
1547: petsc/src/snes/tutorials/ex5f.F for details.
1549: Level: beginner
1551: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1552: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1553: @*/
1554: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1555: {
1557: #if defined(PETSC_HAVE_VIENNACL)
1558: PetscBool is_viennacltype = PETSC_FALSE;
1559: #endif
1563: VecSetErrorIfLocked(x,1);
1564: if (x->petscnative) {
1565: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1566: if (x->offloadmask == PETSC_OFFLOAD_GPU) {
1567: #if defined(PETSC_HAVE_VIENNACL)
1568: PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1569: if (is_viennacltype) {
1570: VecViennaCLCopyFromGPU(x);
1571: } else
1572: #endif
1573: {
1574: #if defined(PETSC_HAVE_CUDA)
1575: VecCUDACopyFromGPU(x);
1576: #endif
1577: }
1578: } else if (x->offloadmask == PETSC_OFFLOAD_UNALLOCATED) {
1579: #if defined(PETSC_HAVE_VIENNACL)
1580: PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1581: if (is_viennacltype) {
1582: VecViennaCLAllocateCheckHost(x);
1583: } else
1584: #endif
1585: {
1586: #if defined(PETSC_HAVE_CUDA)
1587: VecCUDAAllocateCheckHost(x);
1588: #endif
1589: }
1590: }
1591: #endif
1592: *a = *((PetscScalar**)x->data);
1593: } else {
1594: if (x->ops->getarray) {
1595: (*x->ops->getarray)(x,a);
1596: } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
1597: }
1598: return(0);
1599: }
1601: /*@C
1602: VecGetArrayInPlace - Like VecGetArray(), but if this is a CUDA vector and it is currently offloaded to GPU,
1603: the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1604: vector data. Otherwise, it functions as VecGetArray().
1606: Logically Collective on Vec
1608: Input Parameter:
1609: . x - the vector
1611: Output Parameter:
1612: . a - location to put pointer to the array
1614: Level: beginner
1616: .seealso: VecRestoreArrayInPlace(), VecRestoreArrayInPlace(), VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(),
1617: VecPlaceArray(), VecGetArray2d(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1618: @*/
1619: PetscErrorCode VecGetArrayInPlace(Vec x,PetscScalar **a)
1620: {
1625: VecSetErrorIfLocked(x,1);
1627: #if defined(PETSC_HAVE_CUDA)
1628: if (x->petscnative && (x->offloadmask & PETSC_OFFLOAD_GPU)) { /* Prefer working on GPU when offloadmask is PETSC_OFFLOAD_BOTH */
1629: PetscBool is_cudatype = PETSC_FALSE;
1630: PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1631: if (is_cudatype) {
1632: VecCUDAGetArray(x,a);
1633: x->offloadmask = PETSC_OFFLOAD_GPU; /* Change the mask once GPU gets write access, don't wait until restore array */
1634: return(0);
1635: }
1636: }
1637: #endif
1638: VecGetArray(x,a);
1639: return(0);
1640: }
1642: /*@C
1643: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contains this
1644: processor's portion of the vector data. The values in this array are NOT valid, the routine calling this
1645: routine is responsible for putting values into the array; any values it does not set will be invalid
1647: Logically Collective on Vec
1649: Input Parameter:
1650: . x - the vector
1652: Output Parameter:
1653: . a - location to put pointer to the array
1655: Level: intermediate
1657: This is for vectors associate with GPUs, the vector is not copied up before giving access. If you need correct
1658: values in the array use VecGetArray()
1660: Concepts: vector^accessing local values
1662: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1663: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArray(), VecRestoreArrayWrite()
1664: @*/
1665: PetscErrorCode VecGetArrayWrite(Vec x,PetscScalar **a)
1666: {
1671: VecSetErrorIfLocked(x,1);
1672: if (!x->ops->getarraywrite) {
1673: VecGetArray(x,a);
1674: } else {
1675: (*x->ops->getarraywrite)(x,a);
1676: }
1677: return(0);
1678: }
1680: /*@C
1681: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1683: Not Collective
1685: Input Parameters:
1686: . x - the vector
1688: Output Parameter:
1689: . a - the array
1691: Level: beginner
1693: Notes:
1694: The array must be returned using a matching call to VecRestoreArrayRead().
1696: Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1698: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1699: implementations may require a copy, but must such implementations should cache the contiguous representation so that
1700: only one copy is performed when this routine is called multiple times in sequence.
1702: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1703: @*/
1704: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1705: {
1707: #if defined(PETSC_HAVE_VIENNACL)
1708: PetscBool is_viennacltype = PETSC_FALSE;
1709: #endif
1713: if (x->petscnative) {
1714: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1715: if (x->offloadmask == PETSC_OFFLOAD_GPU) {
1716: #if defined(PETSC_HAVE_VIENNACL)
1717: PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1718: if (is_viennacltype) {
1719: VecViennaCLCopyFromGPU(x);
1720: } else
1721: #endif
1722: {
1723: #if defined(PETSC_HAVE_CUDA)
1724: VecCUDACopyFromGPU(x);
1725: #endif
1726: }
1727: }
1728: #endif
1729: *a = *((PetscScalar **)x->data);
1730: } else if (x->ops->getarrayread) {
1731: (*x->ops->getarrayread)(x,a);
1732: } else {
1733: (*x->ops->getarray)(x,(PetscScalar**)a);
1734: }
1735: return(0);
1736: }
1738: /*@C
1739: VecGetArrayReadInPlace - Like VecGetArrayRead(), but if this is a CUDA vector and it is currently offloaded to GPU,
1740: the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1741: vector data. Otherwise, it functions as VecGetArrayRead().
1743: Not Collective
1745: Input Parameters:
1746: . x - the vector
1748: Output Parameter:
1749: . a - the array
1751: Level: beginner
1753: Notes:
1754: The array must be returned using a matching call to VecRestoreArrayReadInPlace().
1757: .seealso: VecRestoreArrayReadInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayInPlace()
1758: @*/
1759: PetscErrorCode VecGetArrayReadInPlace(Vec x,const PetscScalar **a)
1760: {
1765: #if defined(PETSC_HAVE_CUDA)
1766: if (x->petscnative && x->offloadmask & PETSC_OFFLOAD_GPU) {
1767: PetscBool is_cudatype = PETSC_FALSE;
1768: PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1769: if (is_cudatype) {
1770: VecCUDAGetArrayRead(x,a);
1771: return(0);
1772: }
1773: }
1774: #endif
1775: VecGetArrayRead(x,a);
1776: return(0);
1777: }
1779: /*@C
1780: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1781: that were created by a call to VecDuplicateVecs(). You MUST call
1782: VecRestoreArrays() when you no longer need access to the array.
1784: Logically Collective on Vec
1786: Input Parameter:
1787: + x - the vectors
1788: - n - the number of vectors
1790: Output Parameter:
1791: . a - location to put pointer to the array
1793: Fortran Note:
1794: This routine is not supported in Fortran.
1796: Level: intermediate
1798: .seealso: VecGetArray(), VecRestoreArrays()
1799: @*/
1800: PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1801: {
1803: PetscInt i;
1804: PetscScalar **q;
1810: if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1811: PetscMalloc1(n,&q);
1812: for (i=0; i<n; ++i) {
1813: VecGetArray(x[i],&q[i]);
1814: }
1815: *a = q;
1816: return(0);
1817: }
1819: /*@C
1820: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1821: has been called.
1823: Logically Collective on Vec
1825: Input Parameters:
1826: + x - the vector
1827: . n - the number of vectors
1828: - a - location of pointer to arrays obtained from VecGetArrays()
1830: Notes:
1831: For regular PETSc vectors this routine does not involve any copies. For
1832: any special vectors that do not store local vector data in a contiguous
1833: array, this routine will copy the data back into the underlying
1834: vector data structure from the arrays obtained with VecGetArrays().
1836: Fortran Note:
1837: This routine is not supported in Fortran.
1839: Level: intermediate
1841: .seealso: VecGetArrays(), VecRestoreArray()
1842: @*/
1843: PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1844: {
1846: PetscInt i;
1847: PetscScalar **q = *a;
1854: for (i=0; i<n; ++i) {
1855: VecRestoreArray(x[i],&q[i]);
1856: }
1857: PetscFree(q);
1858: return(0);
1859: }
1861: /*@C
1862: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1864: Logically Collective on Vec
1866: Input Parameters:
1867: + x - the vector
1868: - a - location of pointer to array obtained from VecGetArray()
1870: Level: beginner
1872: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1873: VecGetArrayPair(), VecRestoreArrayPair()
1874: @*/
1875: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
1876: {
1881: if (x->petscnative) {
1882: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1883: x->offloadmask = PETSC_OFFLOAD_CPU;
1884: #endif
1885: } else {
1886: (*x->ops->restorearray)(x,a);
1887: }
1888: if (a) *a = NULL;
1889: PetscObjectStateIncrease((PetscObject)x);
1890: return(0);
1891: }
1893: /*@C
1894: VecRestoreArrayInPlace - Restores a vector after VecGetArrayInPlace() has been called.
1896: Logically Collective on Vec
1898: Input Parameters:
1899: + x - the vector
1900: - a - location of pointer to array obtained from VecGetArrayInPlace()
1902: Level: beginner
1904: .seealso: VecGetArrayInPlace(), VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(),
1905: VecPlaceArray(), VecRestoreArray2d(), VecGetArrayPair(), VecRestoreArrayPair()
1906: @*/
1907: PetscErrorCode VecRestoreArrayInPlace(Vec x,PetscScalar **a)
1908: {
1913: #if defined(PETSC_HAVE_CUDA)
1914: if (x->petscnative && x->offloadmask == PETSC_OFFLOAD_GPU) {
1915: PetscBool is_cudatype = PETSC_FALSE;
1916: PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1917: if (is_cudatype) {
1918: VecCUDARestoreArray(x,a);
1919: return(0);
1920: }
1921: }
1922: #endif
1923: VecRestoreArray(x,a);
1924: return(0);
1925: }
1928: /*@C
1929: VecRestoreArrayWrite - Restores a vector after VecGetArrayWrite() has been called.
1931: Logically Collective on Vec
1933: Input Parameters:
1934: + x - the vector
1935: - a - location of pointer to array obtained from VecGetArray()
1937: Level: beginner
1939: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1940: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite()
1941: @*/
1942: PetscErrorCode VecRestoreArrayWrite(Vec x,PetscScalar **a)
1943: {
1948: if (x->petscnative) {
1949: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1950: x->offloadmask = PETSC_OFFLOAD_CPU;
1951: #endif
1952: } else {
1953: if (x->ops->restorearraywrite) {
1954: (*x->ops->restorearraywrite)(x,a);
1955: } else {
1956: (*x->ops->restorearray)(x,a);
1957: }
1958: }
1959: if (a) *a = NULL;
1960: PetscObjectStateIncrease((PetscObject)x);
1961: return(0);
1962: }
1964: /*@C
1965: VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
1967: Not Collective
1969: Input Parameters:
1970: + vec - the vector
1971: - array - the array
1973: Level: beginner
1975: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1976: @*/
1977: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
1978: {
1983: if (x->petscnative) {
1984: /* nothing */
1985: } else if (x->ops->restorearrayread) {
1986: (*x->ops->restorearrayread)(x,a);
1987: } else {
1988: (*x->ops->restorearray)(x,(PetscScalar**)a);
1989: }
1990: if (a) *a = NULL;
1991: return(0);
1992: }
1994: /*@C
1995: VecRestoreArrayReadInPlace - Restore array obtained with VecGetArrayReadInPlace()
1997: Not Collective
1999: Input Parameters:
2000: + vec - the vector
2001: - array - the array
2003: Level: beginner
2005: .seealso: VecGetArrayReadInPlace(), VecRestoreArrayInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
2006: @*/
2007: PetscErrorCode VecRestoreArrayReadInPlace(Vec x,const PetscScalar **a)
2008: {
2012: VecRestoreArrayRead(x,a);
2013: return(0);
2014: }
2016: /*@
2017: VecPlaceArray - Allows one to replace the array in a vector with an
2018: array provided by the user. This is useful to avoid copying an array
2019: into a vector.
2021: Not Collective
2023: Input Parameters:
2024: + vec - the vector
2025: - array - the array
2027: Notes:
2028: You can return to the original array with a call to VecResetArray()
2030: Level: developer
2032: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
2034: @*/
2035: PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
2036: {
2043: if (vec->ops->placearray) {
2044: (*vec->ops->placearray)(vec,array);
2045: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
2046: PetscObjectStateIncrease((PetscObject)vec);
2047: return(0);
2048: }
2050: /*@C
2051: VecReplaceArray - Allows one to replace the array in a vector with an
2052: array provided by the user. This is useful to avoid copying an array
2053: into a vector.
2055: Not Collective
2057: Input Parameters:
2058: + vec - the vector
2059: - array - the array
2061: Notes:
2062: This permanently replaces the array and frees the memory associated
2063: with the old array.
2065: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
2066: freed by the user. It will be freed when the vector is destroyed.
2068: Not supported from Fortran
2070: Level: developer
2072: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
2074: @*/
2075: PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
2076: {
2082: if (vec->ops->replacearray) {
2083: (*vec->ops->replacearray)(vec,array);
2084: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
2085: PetscObjectStateIncrease((PetscObject)vec);
2086: return(0);
2087: }
2090: /*@C
2091: VecCUDAGetArray - Provides access to the CUDA buffer inside a vector.
2093: This function has semantics similar to VecGetArray(): the pointer
2094: returned by this function points to a consistent view of the vector
2095: data. This may involve a copy operation of data from the host to the
2096: device if the data on the device is out of date. If the device
2097: memory hasn't been allocated previously it will be allocated as part
2098: of this function call. VecCUDAGetArray() assumes that
2099: the user will modify the vector data. This is similar to
2100: intent(inout) in fortran.
2102: The CUDA device pointer has to be released by calling
2103: VecCUDARestoreArray(). Upon restoring the vector data
2104: the data on the host will be marked as out of date. A subsequent
2105: access of the host data will thus incur a data transfer from the
2106: device to the host.
2109: Input Parameter:
2110: . v - the vector
2112: Output Parameter:
2113: . a - the CUDA device pointer
2115: Fortran note:
2116: This function is not currently available from Fortran.
2118: Level: intermediate
2120: .seealso: VecCUDARestoreArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2121: @*/
2122: PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
2123: {
2124: #if defined(PETSC_HAVE_CUDA)
2126: #endif
2130: #if defined(PETSC_HAVE_CUDA)
2131: *a = 0;
2132: VecCUDACopyToGPU(v);
2133: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2134: #endif
2135: return(0);
2136: }
2138: /*@C
2139: VecCUDARestoreArray - Restore a CUDA device pointer previously acquired with VecCUDAGetArray().
2141: This marks the host data as out of date. Subsequent access to the
2142: vector data on the host side with for instance VecGetArray() incurs a
2143: data transfer.
2145: Input Parameter:
2146: + v - the vector
2147: - a - the CUDA device pointer. This pointer is invalid after
2148: VecCUDARestoreArray() returns.
2150: Fortran note:
2151: This function is not currently available from Fortran.
2153: Level: intermediate
2155: .seealso: VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2156: @*/
2157: PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
2158: {
2163: #if defined(PETSC_HAVE_CUDA)
2164: v->offloadmask = PETSC_OFFLOAD_GPU;
2165: #endif
2167: PetscObjectStateIncrease((PetscObject)v);
2168: return(0);
2169: }
2171: /*@C
2172: VecCUDAGetArrayRead - Provides read access to the CUDA buffer inside a vector.
2174: This function is analogous to VecGetArrayRead(): The pointer
2175: returned by this function points to a consistent view of the vector
2176: data. This may involve a copy operation of data from the host to the
2177: device if the data on the device is out of date. If the device
2178: memory hasn't been allocated previously it will be allocated as part
2179: of this function call. VecCUDAGetArrayRead() assumes that the
2180: user will not modify the vector data. This is analgogous to
2181: intent(in) in Fortran.
2183: The CUDA device pointer has to be released by calling
2184: VecCUDARestoreArrayRead(). If the data on the host side was
2185: previously up to date it will remain so, i.e. data on both the device
2186: and the host is up to date. Accessing data on the host side does not
2187: incur a device to host data transfer.
2189: Input Parameter:
2190: . v - the vector
2192: Output Parameter:
2193: . a - the CUDA pointer.
2195: Fortran note:
2196: This function is not currently available from Fortran.
2198: Level: intermediate
2200: .seealso: VecCUDARestoreArrayRead(), VecCUDAGetArray(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2201: @*/
2202: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v, const PetscScalar **a)
2203: {
2204: #if defined(PETSC_HAVE_CUDA)
2206: #endif
2210: #if defined(PETSC_HAVE_CUDA)
2211: *a = 0;
2212: VecCUDACopyToGPU(v);
2213: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2214: #endif
2215: return(0);
2216: }
2218: /*@C
2219: VecCUDARestoreArrayRead - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayRead().
2221: If the data on the host side was previously up to date it will remain
2222: so, i.e. data on both the device and the host is up to date.
2223: Accessing data on the host side e.g. with VecGetArray() does not
2224: incur a device to host data transfer.
2226: Input Parameter:
2227: + v - the vector
2228: - a - the CUDA device pointer. This pointer is invalid after
2229: VecCUDARestoreArrayRead() returns.
2231: Fortran note:
2232: This function is not currently available from Fortran.
2234: Level: intermediate
2236: .seealso: VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2237: @*/
2238: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
2239: {
2242: *a = NULL;
2243: return(0);
2244: }
2246: /*@C
2247: VecCUDAGetArrayWrite - Provides write access to the CUDA buffer inside a vector.
2249: The data pointed to by the device pointer is uninitialized. The user
2250: may not read from this data. Furthermore, the entire array needs to
2251: be filled by the user to obtain well-defined behaviour. The device
2252: memory will be allocated by this function if it hasn't been allocated
2253: previously. This is analogous to intent(out) in Fortran.
2255: The device pointer needs to be released with
2256: VecCUDARestoreArrayWrite(). When the pointer is released the
2257: host data of the vector is marked as out of data. Subsequent access
2258: of the host data with e.g. VecGetArray() incurs a device to host data
2259: transfer.
2262: Input Parameter:
2263: . v - the vector
2265: Output Parameter:
2266: . a - the CUDA pointer
2268: Fortran note:
2269: This function is not currently available from Fortran.
2271: Level: advanced
2273: .seealso: VecCUDARestoreArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2274: @*/
2275: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
2276: {
2277: #if defined(PETSC_HAVE_CUDA)
2279: #endif
2283: #if defined(PETSC_HAVE_CUDA)
2284: *a = 0;
2285: VecCUDAAllocateCheck(v);
2286: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2287: #endif
2288: return(0);
2289: }
2291: /*@C
2292: VecCUDARestoreArrayWrite - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayWrite().
2294: Data on the host will be marked as out of date. Subsequent access of
2295: the data on the host side e.g. with VecGetArray() will incur a device
2296: to host data transfer.
2298: Input Parameter:
2299: + v - the vector
2300: - a - the CUDA device pointer. This pointer is invalid after
2301: VecCUDARestoreArrayWrite() returns.
2303: Fortran note:
2304: This function is not currently available from Fortran.
2306: Level: intermediate
2308: .seealso: VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2309: @*/
2310: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
2311: {
2316: #if defined(PETSC_HAVE_CUDA)
2317: v->offloadmask = PETSC_OFFLOAD_GPU;
2318: #endif
2320: PetscObjectStateIncrease((PetscObject)v);
2321: return(0);
2322: }
2324: /*@C
2325: VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
2326: GPU array provided by the user. This is useful to avoid copying an
2327: array into a vector.
2329: Not Collective
2331: Input Parameters:
2332: + vec - the vector
2333: - array - the GPU array
2335: Notes:
2336: You can return to the original GPU array with a call to VecCUDAResetArray()
2337: It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
2338: same time on the same vector.
2340: Level: developer
2342: .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAReplaceArray()
2344: @*/
2345: PetscErrorCode VecCUDAPlaceArray(Vec vin,PetscScalar *a)
2346: {
2351: #if defined(PETSC_HAVE_CUDA)
2352: VecCUDACopyToGPU(vin);
2353: if (((Vec_Seq*)vin->data)->unplacedarray) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"VecCUDAPlaceArray()/VecPlaceArray() was already called on this vector, without a call to VecCUDAResetArray()/VecResetArray()");
2354: ((Vec_Seq*)vin->data)->unplacedarray = (PetscScalar *) ((Vec_CUDA*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2355: ((Vec_CUDA*)vin->spptr)->GPUarray = a;
2356: vin->offloadmask = PETSC_OFFLOAD_GPU;
2357: #endif
2358: PetscObjectStateIncrease((PetscObject)vin);
2359: return(0);
2360: }
2362: /*@C
2363: VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
2364: with a GPU array provided by the user. This is useful to avoid copying
2365: a GPU array into a vector.
2367: Not Collective
2369: Input Parameters:
2370: + vec - the vector
2371: - array - the GPU array
2373: Notes:
2374: This permanently replaces the GPU array and frees the memory associated
2375: with the old GPU array.
2377: The memory passed in CANNOT be freed by the user. It will be freed
2378: when the vector is destroyed.
2380: Not supported from Fortran
2382: Level: developer
2384: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAPlaceArray(), VecReplaceArray()
2386: @*/
2387: PetscErrorCode VecCUDAReplaceArray(Vec vin,PetscScalar *a)
2388: {
2389: #if defined(PETSC_HAVE_CUDA)
2390: cudaError_t err;
2391: #endif
2396: #if defined(PETSC_HAVE_CUDA)
2397: err = cudaFree(((Vec_CUDA*)vin->spptr)->GPUarray);CHKERRCUDA(err);
2398: ((Vec_CUDA*)vin->spptr)->GPUarray = a;
2399: vin->offloadmask = PETSC_OFFLOAD_GPU;
2400: #endif
2401: PetscObjectStateIncrease((PetscObject)vin);
2402: return(0);
2403: }
2405: /*@C
2406: VecCUDAResetArray - Resets a vector to use its default memory. Call this
2407: after the use of VecCUDAPlaceArray().
2409: Not Collective
2411: Input Parameters:
2412: . vec - the vector
2414: Level: developer
2416: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecCUDAPlaceArray(), VecCUDAReplaceArray()
2418: @*/
2419: PetscErrorCode VecCUDAResetArray(Vec vin)
2420: {
2425: #if defined(PETSC_HAVE_CUDA)
2426: VecCUDACopyToGPU(vin);
2427: ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2428: ((Vec_Seq*)vin->data)->unplacedarray = 0;
2429: vin->offloadmask = PETSC_OFFLOAD_GPU;
2430: #endif
2431: PetscObjectStateIncrease((PetscObject)vin);
2432: return(0);
2433: }
2435: /*MC
2436: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2437: and makes them accessible via a Fortran90 pointer.
2439: Synopsis:
2440: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2442: Collective on Vec
2444: Input Parameters:
2445: + x - a vector to mimic
2446: - n - the number of vectors to obtain
2448: Output Parameters:
2449: + y - Fortran90 pointer to the array of vectors
2450: - ierr - error code
2452: Example of Usage:
2453: .vb
2454: #include <petsc/finclude/petscvec.h>
2455: use petscvec
2457: Vec x
2458: Vec, pointer :: y(:)
2459: ....
2460: call VecDuplicateVecsF90(x,2,y,ierr)
2461: call VecSet(y(2),alpha,ierr)
2462: call VecSet(y(2),alpha,ierr)
2463: ....
2464: call VecDestroyVecsF90(2,y,ierr)
2465: .ve
2467: Notes:
2468: Not yet supported for all F90 compilers
2470: Use VecDestroyVecsF90() to free the space.
2472: Level: beginner
2474: .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
2476: M*/
2478: /*MC
2479: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2480: VecGetArrayF90().
2482: Synopsis:
2483: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2485: Logically Collective on Vec
2487: Input Parameters:
2488: + x - vector
2489: - xx_v - the Fortran90 pointer to the array
2491: Output Parameter:
2492: . ierr - error code
2494: Example of Usage:
2495: .vb
2496: #include <petsc/finclude/petscvec.h>
2497: use petscvec
2499: PetscScalar, pointer :: xx_v(:)
2500: ....
2501: call VecGetArrayF90(x,xx_v,ierr)
2502: xx_v(3) = a
2503: call VecRestoreArrayF90(x,xx_v,ierr)
2504: .ve
2506: Level: beginner
2508: .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran, VecRestoreArrayReadF90()
2510: M*/
2512: /*MC
2513: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
2515: Synopsis:
2516: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
2518: Collective on Vec
2520: Input Parameters:
2521: + n - the number of vectors previously obtained
2522: - x - pointer to array of vector pointers
2524: Output Parameter:
2525: . ierr - error code
2527: Notes:
2528: Not yet supported for all F90 compilers
2530: Level: beginner
2532: .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
2534: M*/
2536: /*MC
2537: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
2538: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2539: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
2540: when you no longer need access to the array.
2542: Synopsis:
2543: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2545: Logically Collective on Vec
2547: Input Parameter:
2548: . x - vector
2550: Output Parameters:
2551: + xx_v - the Fortran90 pointer to the array
2552: - ierr - error code
2554: Example of Usage:
2555: .vb
2556: #include <petsc/finclude/petscvec.h>
2557: use petscvec
2559: PetscScalar, pointer :: xx_v(:)
2560: ....
2561: call VecGetArrayF90(x,xx_v,ierr)
2562: xx_v(3) = a
2563: call VecRestoreArrayF90(x,xx_v,ierr)
2564: .ve
2566: If you ONLY intend to read entries from the array and not change any entries you should use VecGetArrayReadF90().
2568: Level: beginner
2570: .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), VecGetArrayReadF90(), UsingFortran
2572: M*/
2574: /*MC
2575: VecGetArrayReadF90 - Accesses a read only array from Fortran90. For default PETSc
2576: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2577: this routine is implementation dependent. You MUST call VecRestoreArrayReadF90()
2578: when you no longer need access to the array.
2580: Synopsis:
2581: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2583: Logically Collective on Vec
2585: Input Parameter:
2586: . x - vector
2588: Output Parameters:
2589: + xx_v - the Fortran90 pointer to the array
2590: - ierr - error code
2592: Example of Usage:
2593: .vb
2594: #include <petsc/finclude/petscvec.h>
2595: use petscvec
2597: PetscScalar, pointer :: xx_v(:)
2598: ....
2599: call VecGetArrayReadF90(x,xx_v,ierr)
2600: a = xx_v(3)
2601: call VecRestoreArrayReadF90(x,xx_v,ierr)
2602: .ve
2604: If you intend to write entries into the array you must use VecGetArrayF90().
2606: Level: beginner
2608: .seealso: VecRestoreArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(), VecGetArrayF90(), UsingFortran
2610: M*/
2612: /*MC
2613: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
2614: VecGetArrayReadF90().
2616: Synopsis:
2617: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2619: Logically Collective on Vec
2621: Input Parameters:
2622: + x - vector
2623: - xx_v - the Fortran90 pointer to the array
2625: Output Parameter:
2626: . ierr - error code
2628: Example of Usage:
2629: .vb
2630: #include <petsc/finclude/petscvec.h>
2631: use petscvec
2633: PetscScalar, pointer :: xx_v(:)
2634: ....
2635: call VecGetArrayReadF90(x,xx_v,ierr)
2636: a = xx_v(3)
2637: call VecRestoreArrayReadF90(x,xx_v,ierr)
2638: .ve
2640: Level: beginner
2642: .seealso: VecGetArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(),UsingFortran, VecRestoreArrayF90()
2644: M*/
2646: /*@C
2647: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
2648: processor's portion of the vector data. You MUST call VecRestoreArray2d()
2649: when you no longer need access to the array.
2651: Logically Collective
2653: Input Parameter:
2654: + x - the vector
2655: . m - first dimension of two dimensional array
2656: . n - second dimension of two dimensional array
2657: . mstart - first index you will use in first coordinate direction (often 0)
2658: - nstart - first index in the second coordinate direction (often 0)
2660: Output Parameter:
2661: . a - location to put pointer to the array
2663: Level: developer
2665: Notes:
2666: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2667: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2668: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2669: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
2671: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2673: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2674: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2675: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2676: @*/
2677: PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2678: {
2680: PetscInt i,N;
2681: PetscScalar *aa;
2687: VecGetLocalSize(x,&N);
2688: if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
2689: VecGetArray(x,&aa);
2691: PetscMalloc1(m,a);
2692: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2693: *a -= mstart;
2694: return(0);
2695: }
2697: /*@C
2698: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
2699: processor's portion of the vector data. You MUST call VecRestoreArray2dWrite()
2700: when you no longer need access to the array.
2702: Logically Collective
2704: Input Parameter:
2705: + x - the vector
2706: . m - first dimension of two dimensional array
2707: . n - second dimension of two dimensional array
2708: . mstart - first index you will use in first coordinate direction (often 0)
2709: - nstart - first index in the second coordinate direction (often 0)
2711: Output Parameter:
2712: . a - location to put pointer to the array
2714: Level: developer
2716: Notes:
2717: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2718: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2719: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2720: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
2722: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2724: Concepts: vector^accessing local values as 2d array
2726: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2727: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2728: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2729: @*/
2730: PetscErrorCode VecGetArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2731: {
2733: PetscInt i,N;
2734: PetscScalar *aa;
2740: VecGetLocalSize(x,&N);
2741: if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
2742: VecGetArrayWrite(x,&aa);
2744: PetscMalloc1(m,a);
2745: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2746: *a -= mstart;
2747: return(0);
2748: }
2750: /*@C
2751: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
2753: Logically Collective
2755: Input Parameters:
2756: + x - the vector
2757: . m - first dimension of two dimensional array
2758: . n - second dimension of the two dimensional array
2759: . mstart - first index you will use in first coordinate direction (often 0)
2760: . nstart - first index in the second coordinate direction (often 0)
2761: - a - location of pointer to array obtained from VecGetArray2d()
2763: Level: developer
2765: Notes:
2766: For regular PETSc vectors this routine does not involve any copies. For
2767: any special vectors that do not store local vector data in a contiguous
2768: array, this routine will copy the data back into the underlying
2769: vector data structure from the array obtained with VecGetArray().
2771: This routine actually zeros out the a pointer.
2773: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2774: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2775: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2776: @*/
2777: PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2778: {
2780: void *dummy;
2786: dummy = (void*)(*a + mstart);
2787: PetscFree(dummy);
2788: VecRestoreArray(x,NULL);
2789: return(0);
2790: }
2792: /*@C
2793: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite() has been called.
2795: Logically Collective
2797: Input Parameters:
2798: + x - the vector
2799: . m - first dimension of two dimensional array
2800: . n - second dimension of the two dimensional array
2801: . mstart - first index you will use in first coordinate direction (often 0)
2802: . nstart - first index in the second coordinate direction (often 0)
2803: - a - location of pointer to array obtained from VecGetArray2d()
2805: Level: developer
2807: Notes:
2808: For regular PETSc vectors this routine does not involve any copies. For
2809: any special vectors that do not store local vector data in a contiguous
2810: array, this routine will copy the data back into the underlying
2811: vector data structure from the array obtained with VecGetArray().
2813: This routine actually zeros out the a pointer.
2815: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2816: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2817: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2818: @*/
2819: PetscErrorCode VecRestoreArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2820: {
2822: void *dummy;
2828: dummy = (void*)(*a + mstart);
2829: PetscFree(dummy);
2830: VecRestoreArrayWrite(x,NULL);
2831: return(0);
2832: }
2834: /*@C
2835: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2836: processor's portion of the vector data. You MUST call VecRestoreArray1d()
2837: when you no longer need access to the array.
2839: Logically Collective
2841: Input Parameter:
2842: + x - the vector
2843: . m - first dimension of two dimensional array
2844: - mstart - first index you will use in first coordinate direction (often 0)
2846: Output Parameter:
2847: . a - location to put pointer to the array
2849: Level: developer
2851: Notes:
2852: For a vector obtained from DMCreateLocalVector() mstart are likely
2853: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2854: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
2856: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2858: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2859: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2860: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2861: @*/
2862: PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2863: {
2865: PetscInt N;
2871: VecGetLocalSize(x,&N);
2872: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2873: VecGetArray(x,a);
2874: *a -= mstart;
2875: return(0);
2876: }
2878: /*@C
2879: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
2880: processor's portion of the vector data. You MUST call VecRestoreArray1dWrite()
2881: when you no longer need access to the array.
2883: Logically Collective
2885: Input Parameter:
2886: + x - the vector
2887: . m - first dimension of two dimensional array
2888: - mstart - first index you will use in first coordinate direction (often 0)
2890: Output Parameter:
2891: . a - location to put pointer to the array
2893: Level: developer
2895: Notes:
2896: For a vector obtained from DMCreateLocalVector() mstart are likely
2897: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2898: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
2900: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2902: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2903: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2904: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2905: @*/
2906: PetscErrorCode VecGetArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2907: {
2909: PetscInt N;
2915: VecGetLocalSize(x,&N);
2916: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2917: VecGetArrayWrite(x,a);
2918: *a -= mstart;
2919: return(0);
2920: }
2922: /*@C
2923: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
2925: Logically Collective
2927: Input Parameters:
2928: + x - the vector
2929: . m - first dimension of two dimensional array
2930: . mstart - first index you will use in first coordinate direction (often 0)
2931: - a - location of pointer to array obtained from VecGetArray21()
2933: Level: developer
2935: Notes:
2936: For regular PETSc vectors this routine does not involve any copies. For
2937: any special vectors that do not store local vector data in a contiguous
2938: array, this routine will copy the data back into the underlying
2939: vector data structure from the array obtained with VecGetArray1d().
2941: This routine actually zeros out the a pointer.
2943: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2944: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2945: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2946: @*/
2947: PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2948: {
2954: VecRestoreArray(x,NULL);
2955: return(0);
2956: }
2958: /*@C
2959: VecRestoreArray1dWrite - Restores a vector after VecGetArray1dWrite() has been called.
2961: Logically Collective
2963: Input Parameters:
2964: + x - the vector
2965: . m - first dimension of two dimensional array
2966: . mstart - first index you will use in first coordinate direction (often 0)
2967: - a - location of pointer to array obtained from VecGetArray21()
2969: Level: developer
2971: Notes:
2972: For regular PETSc vectors this routine does not involve any copies. For
2973: any special vectors that do not store local vector data in a contiguous
2974: array, this routine will copy the data back into the underlying
2975: vector data structure from the array obtained with VecGetArray1d().
2977: This routine actually zeros out the a pointer.
2979: Concepts: vector^accessing local values as 1d array
2981: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2982: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2983: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2984: @*/
2985: PetscErrorCode VecRestoreArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2986: {
2992: VecRestoreArrayWrite(x,NULL);
2993: return(0);
2994: }
2996: /*@C
2997: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
2998: processor's portion of the vector data. You MUST call VecRestoreArray3d()
2999: when you no longer need access to the array.
3001: Logically Collective
3003: Input Parameter:
3004: + x - the vector
3005: . m - first dimension of three dimensional array
3006: . n - second dimension of three dimensional array
3007: . p - third dimension of three dimensional array
3008: . mstart - first index you will use in first coordinate direction (often 0)
3009: . nstart - first index in the second coordinate direction (often 0)
3010: - pstart - first index in the third coordinate direction (often 0)
3012: Output Parameter:
3013: . a - location to put pointer to the array
3015: Level: developer
3017: Notes:
3018: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3019: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3020: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3021: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3023: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3025: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3026: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3027: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3028: @*/
3029: PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3030: {
3032: PetscInt i,N,j;
3033: PetscScalar *aa,**b;
3039: VecGetLocalSize(x,&N);
3040: if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3041: VecGetArray(x,&aa);
3043: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3044: b = (PetscScalar**)((*a) + m);
3045: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3046: for (i=0; i<m; i++)
3047: for (j=0; j<n; j++)
3048: b[i*n+j] = aa + i*n*p + j*p - pstart;
3050: *a -= mstart;
3051: return(0);
3052: }
3054: /*@C
3055: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3056: processor's portion of the vector data. You MUST call VecRestoreArray3dWrite()
3057: when you no longer need access to the array.
3059: Logically Collective
3061: Input Parameter:
3062: + x - the vector
3063: . m - first dimension of three dimensional array
3064: . n - second dimension of three dimensional array
3065: . p - third dimension of three dimensional array
3066: . mstart - first index you will use in first coordinate direction (often 0)
3067: . nstart - first index in the second coordinate direction (often 0)
3068: - pstart - first index in the third coordinate direction (often 0)
3070: Output Parameter:
3071: . a - location to put pointer to the array
3073: Level: developer
3075: Notes:
3076: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3077: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3078: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3079: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3081: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3083: Concepts: vector^accessing local values as 3d array
3085: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3086: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3087: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3088: @*/
3089: PetscErrorCode VecGetArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3090: {
3092: PetscInt i,N,j;
3093: PetscScalar *aa,**b;
3099: VecGetLocalSize(x,&N);
3100: if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3101: VecGetArrayWrite(x,&aa);
3103: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3104: b = (PetscScalar**)((*a) + m);
3105: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3106: for (i=0; i<m; i++)
3107: for (j=0; j<n; j++)
3108: b[i*n+j] = aa + i*n*p + j*p - pstart;
3110: *a -= mstart;
3111: return(0);
3112: }
3114: /*@C
3115: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
3117: Logically Collective
3119: Input Parameters:
3120: + x - the vector
3121: . m - first dimension of three dimensional array
3122: . n - second dimension of the three dimensional array
3123: . p - third dimension of the three dimensional array
3124: . mstart - first index you will use in first coordinate direction (often 0)
3125: . nstart - first index in the second coordinate direction (often 0)
3126: . pstart - first index in the third coordinate direction (often 0)
3127: - a - location of pointer to array obtained from VecGetArray3d()
3129: Level: developer
3131: Notes:
3132: For regular PETSc vectors this routine does not involve any copies. For
3133: any special vectors that do not store local vector data in a contiguous
3134: array, this routine will copy the data back into the underlying
3135: vector data structure from the array obtained with VecGetArray().
3137: This routine actually zeros out the a pointer.
3139: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3140: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3141: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3142: @*/
3143: PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3144: {
3146: void *dummy;
3152: dummy = (void*)(*a + mstart);
3153: PetscFree(dummy);
3154: VecRestoreArray(x,NULL);
3155: return(0);
3156: }
3158: /*@C
3159: VecRestoreArray3dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3161: Logically Collective
3163: Input Parameters:
3164: + x - the vector
3165: . m - first dimension of three dimensional array
3166: . n - second dimension of the three dimensional array
3167: . p - third dimension of the three dimensional array
3168: . mstart - first index you will use in first coordinate direction (often 0)
3169: . nstart - first index in the second coordinate direction (often 0)
3170: . pstart - first index in the third coordinate direction (often 0)
3171: - a - location of pointer to array obtained from VecGetArray3d()
3173: Level: developer
3175: Notes:
3176: For regular PETSc vectors this routine does not involve any copies. For
3177: any special vectors that do not store local vector data in a contiguous
3178: array, this routine will copy the data back into the underlying
3179: vector data structure from the array obtained with VecGetArray().
3181: This routine actually zeros out the a pointer.
3183: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3184: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3185: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3186: @*/
3187: PetscErrorCode VecRestoreArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3188: {
3190: void *dummy;
3196: dummy = (void*)(*a + mstart);
3197: PetscFree(dummy);
3198: VecRestoreArrayWrite(x,NULL);
3199: return(0);
3200: }
3202: /*@C
3203: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3204: processor's portion of the vector data. You MUST call VecRestoreArray4d()
3205: when you no longer need access to the array.
3207: Logically Collective
3209: Input Parameter:
3210: + x - the vector
3211: . m - first dimension of four dimensional array
3212: . n - second dimension of four dimensional array
3213: . p - third dimension of four dimensional array
3214: . q - fourth dimension of four dimensional array
3215: . mstart - first index you will use in first coordinate direction (often 0)
3216: . nstart - first index in the second coordinate direction (often 0)
3217: . pstart - first index in the third coordinate direction (often 0)
3218: - qstart - first index in the fourth coordinate direction (often 0)
3220: Output Parameter:
3221: . a - location to put pointer to the array
3223: Level: beginner
3225: Notes:
3226: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3227: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3228: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3229: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3231: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3233: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3234: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3235: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3236: @*/
3237: PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3238: {
3240: PetscInt i,N,j,k;
3241: PetscScalar *aa,***b,**c;
3247: VecGetLocalSize(x,&N);
3248: if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
3249: VecGetArray(x,&aa);
3251: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3252: b = (PetscScalar***)((*a) + m);
3253: c = (PetscScalar**)(b + m*n);
3254: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3255: for (i=0; i<m; i++)
3256: for (j=0; j<n; j++)
3257: b[i*n+j] = c + i*n*p + j*p - pstart;
3258: for (i=0; i<m; i++)
3259: for (j=0; j<n; j++)
3260: for (k=0; k<p; k++)
3261: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3262: *a -= mstart;
3263: return(0);
3264: }
3266: /*@C
3267: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3268: processor's portion of the vector data. You MUST call VecRestoreArray4dWrite()
3269: when you no longer need access to the array.
3271: Logically Collective
3273: Input Parameter:
3274: + x - the vector
3275: . m - first dimension of four dimensional array
3276: . n - second dimension of four dimensional array
3277: . p - third dimension of four dimensional array
3278: . q - fourth dimension of four dimensional array
3279: . mstart - first index you will use in first coordinate direction (often 0)
3280: . nstart - first index in the second coordinate direction (often 0)
3281: . pstart - first index in the third coordinate direction (often 0)
3282: - qstart - first index in the fourth coordinate direction (often 0)
3284: Output Parameter:
3285: . a - location to put pointer to the array
3287: Level: beginner
3289: Notes:
3290: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3291: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3292: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3293: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3295: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3297: Concepts: vector^accessing local values as 3d array
3299: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3300: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3301: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3302: @*/
3303: PetscErrorCode VecGetArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3304: {
3306: PetscInt i,N,j,k;
3307: PetscScalar *aa,***b,**c;
3313: VecGetLocalSize(x,&N);
3314: if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
3315: VecGetArrayWrite(x,&aa);
3317: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3318: b = (PetscScalar***)((*a) + m);
3319: c = (PetscScalar**)(b + m*n);
3320: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3321: for (i=0; i<m; i++)
3322: for (j=0; j<n; j++)
3323: b[i*n+j] = c + i*n*p + j*p - pstart;
3324: for (i=0; i<m; i++)
3325: for (j=0; j<n; j++)
3326: for (k=0; k<p; k++)
3327: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3328: *a -= mstart;
3329: return(0);
3330: }
3332: /*@C
3333: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
3335: Logically Collective
3337: Input Parameters:
3338: + x - the vector
3339: . m - first dimension of four dimensional array
3340: . n - second dimension of the four dimensional array
3341: . p - third dimension of the four dimensional array
3342: . q - fourth dimension of the four dimensional array
3343: . mstart - first index you will use in first coordinate direction (often 0)
3344: . nstart - first index in the second coordinate direction (often 0)
3345: . pstart - first index in the third coordinate direction (often 0)
3346: . qstart - first index in the fourth coordinate direction (often 0)
3347: - a - location of pointer to array obtained from VecGetArray4d()
3349: Level: beginner
3351: Notes:
3352: For regular PETSc vectors this routine does not involve any copies. For
3353: any special vectors that do not store local vector data in a contiguous
3354: array, this routine will copy the data back into the underlying
3355: vector data structure from the array obtained with VecGetArray().
3357: This routine actually zeros out the a pointer.
3359: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3360: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3361: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3362: @*/
3363: PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3364: {
3366: void *dummy;
3372: dummy = (void*)(*a + mstart);
3373: PetscFree(dummy);
3374: VecRestoreArray(x,NULL);
3375: return(0);
3376: }
3378: /*@C
3379: VecRestoreArray4dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3381: Logically Collective
3383: Input Parameters:
3384: + x - the vector
3385: . m - first dimension of four dimensional array
3386: . n - second dimension of the four dimensional array
3387: . p - third dimension of the four dimensional array
3388: . q - fourth dimension of the four dimensional array
3389: . mstart - first index you will use in first coordinate direction (often 0)
3390: . nstart - first index in the second coordinate direction (often 0)
3391: . pstart - first index in the third coordinate direction (often 0)
3392: . qstart - first index in the fourth coordinate direction (often 0)
3393: - a - location of pointer to array obtained from VecGetArray4d()
3395: Level: beginner
3397: Notes:
3398: For regular PETSc vectors this routine does not involve any copies. For
3399: any special vectors that do not store local vector data in a contiguous
3400: array, this routine will copy the data back into the underlying
3401: vector data structure from the array obtained with VecGetArray().
3403: This routine actually zeros out the a pointer.
3405: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3406: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3407: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3408: @*/
3409: PetscErrorCode VecRestoreArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3410: {
3412: void *dummy;
3418: dummy = (void*)(*a + mstart);
3419: PetscFree(dummy);
3420: VecRestoreArrayWrite(x,NULL);
3421: return(0);
3422: }
3424: /*@C
3425: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3426: processor's portion of the vector data. You MUST call VecRestoreArray2dRead()
3427: when you no longer need access to the array.
3429: Logically Collective
3431: Input Parameter:
3432: + x - the vector
3433: . m - first dimension of two dimensional array
3434: . n - second dimension of two dimensional array
3435: . mstart - first index you will use in first coordinate direction (often 0)
3436: - nstart - first index in the second coordinate direction (often 0)
3438: Output Parameter:
3439: . a - location to put pointer to the array
3441: Level: developer
3443: Notes:
3444: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3445: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3446: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3447: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3449: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3451: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3452: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3453: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3454: @*/
3455: PetscErrorCode VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3456: {
3457: PetscErrorCode ierr;
3458: PetscInt i,N;
3459: const PetscScalar *aa;
3465: VecGetLocalSize(x,&N);
3466: if (m*n != N) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 2d array dimensions %D by %D",N,m,n);
3467: VecGetArrayRead(x,&aa);
3469: PetscMalloc1(m,a);
3470: for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
3471: *a -= mstart;
3472: return(0);
3473: }
3475: /*@C
3476: VecRestoreArray2dRead - Restores a vector after VecGetArray2dRead() has been called.
3478: Logically Collective
3480: Input Parameters:
3481: + x - the vector
3482: . m - first dimension of two dimensional array
3483: . n - second dimension of the two dimensional array
3484: . mstart - first index you will use in first coordinate direction (often 0)
3485: . nstart - first index in the second coordinate direction (often 0)
3486: - a - location of pointer to array obtained from VecGetArray2d()
3488: Level: developer
3490: Notes:
3491: For regular PETSc vectors this routine does not involve any copies. For
3492: any special vectors that do not store local vector data in a contiguous
3493: array, this routine will copy the data back into the underlying
3494: vector data structure from the array obtained with VecGetArray().
3496: This routine actually zeros out the a pointer.
3498: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3499: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3500: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3501: @*/
3502: PetscErrorCode VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3503: {
3505: void *dummy;
3511: dummy = (void*)(*a + mstart);
3512: PetscFree(dummy);
3513: VecRestoreArrayRead(x,NULL);
3514: return(0);
3515: }
3517: /*@C
3518: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3519: processor's portion of the vector data. You MUST call VecRestoreArray1dRead()
3520: when you no longer need access to the array.
3522: Logically Collective
3524: Input Parameter:
3525: + x - the vector
3526: . m - first dimension of two dimensional array
3527: - mstart - first index you will use in first coordinate direction (often 0)
3529: Output Parameter:
3530: . a - location to put pointer to the array
3532: Level: developer
3534: Notes:
3535: For a vector obtained from DMCreateLocalVector() mstart are likely
3536: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3537: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3539: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3541: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3542: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3543: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3544: @*/
3545: PetscErrorCode VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3546: {
3548: PetscInt N;
3554: VecGetLocalSize(x,&N);
3555: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3556: VecGetArrayRead(x,(const PetscScalar**)a);
3557: *a -= mstart;
3558: return(0);
3559: }
3561: /*@C
3562: VecRestoreArray1dRead - Restores a vector after VecGetArray1dRead() has been called.
3564: Logically Collective
3566: Input Parameters:
3567: + x - the vector
3568: . m - first dimension of two dimensional array
3569: . mstart - first index you will use in first coordinate direction (often 0)
3570: - a - location of pointer to array obtained from VecGetArray21()
3572: Level: developer
3574: Notes:
3575: For regular PETSc vectors this routine does not involve any copies. For
3576: any special vectors that do not store local vector data in a contiguous
3577: array, this routine will copy the data back into the underlying
3578: vector data structure from the array obtained with VecGetArray1dRead().
3580: This routine actually zeros out the a pointer.
3582: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3583: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3584: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3585: @*/
3586: PetscErrorCode VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3587: {
3593: VecRestoreArrayRead(x,NULL);
3594: return(0);
3595: }
3598: /*@C
3599: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3600: processor's portion of the vector data. You MUST call VecRestoreArray3dRead()
3601: when you no longer need access to the array.
3603: Logically Collective
3605: Input Parameter:
3606: + x - the vector
3607: . m - first dimension of three dimensional array
3608: . n - second dimension of three dimensional array
3609: . p - third dimension of three 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)
3614: Output Parameter:
3615: . a - location to put pointer to the array
3617: Level: developer
3619: Notes:
3620: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3621: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3622: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3623: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3dRead().
3625: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3627: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3628: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3629: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3630: @*/
3631: PetscErrorCode VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3632: {
3633: PetscErrorCode ierr;
3634: PetscInt i,N,j;
3635: const PetscScalar *aa;
3636: PetscScalar **b;
3642: VecGetLocalSize(x,&N);
3643: if (m*n*p != N) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 3d array dimensions %D by %D by %D",N,m,n,p);
3644: VecGetArrayRead(x,&aa);
3646: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3647: b = (PetscScalar**)((*a) + m);
3648: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3649: for (i=0; i<m; i++)
3650: for (j=0; j<n; j++)
3651: b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;
3653: *a -= mstart;
3654: return(0);
3655: }
3657: /*@C
3658: VecRestoreArray3dRead - Restores a vector after VecGetArray3dRead() has been called.
3660: Logically Collective
3662: Input Parameters:
3663: + x - the vector
3664: . m - first dimension of three dimensional array
3665: . n - second dimension of the three dimensional array
3666: . p - third dimension of the three dimensional array
3667: . mstart - first index you will use in first coordinate direction (often 0)
3668: . nstart - first index in the second coordinate direction (often 0)
3669: . pstart - first index in the third coordinate direction (often 0)
3670: - a - location of pointer to array obtained from VecGetArray3dRead()
3672: Level: developer
3674: Notes:
3675: For regular PETSc vectors this routine does not involve any copies. For
3676: any special vectors that do not store local vector data in a contiguous
3677: array, this routine will copy the data back into the underlying
3678: vector data structure from the array obtained with VecGetArray().
3680: This routine actually zeros out the a pointer.
3682: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3683: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3684: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3685: @*/
3686: PetscErrorCode VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3687: {
3689: void *dummy;
3695: dummy = (void*)(*a + mstart);
3696: PetscFree(dummy);
3697: VecRestoreArrayRead(x,NULL);
3698: return(0);
3699: }
3701: /*@C
3702: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
3703: processor's portion of the vector data. You MUST call VecRestoreArray4dRead()
3704: when you no longer need access to the array.
3706: Logically Collective
3708: Input Parameter:
3709: + x - the vector
3710: . m - first dimension of four dimensional array
3711: . n - second dimension of four dimensional array
3712: . p - third dimension of four dimensional array
3713: . q - fourth dimension of four dimensional array
3714: . mstart - first index you will use in first coordinate direction (often 0)
3715: . nstart - first index in the second coordinate direction (often 0)
3716: . pstart - first index in the third coordinate direction (often 0)
3717: - qstart - first index in the fourth coordinate direction (often 0)
3719: Output Parameter:
3720: . a - location to put pointer to the array
3722: Level: beginner
3724: Notes:
3725: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3726: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3727: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3728: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3730: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3732: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3733: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3734: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3735: @*/
3736: PetscErrorCode VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3737: {
3738: PetscErrorCode ierr;
3739: PetscInt i,N,j,k;
3740: const PetscScalar *aa;
3741: PetscScalar ***b,**c;
3747: VecGetLocalSize(x,&N);
3748: if (m*n*p*q != N) SETERRQ5(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Local array size %D does not match 4d array dimensions %D by %D by %D by %D",N,m,n,p,q);
3749: VecGetArrayRead(x,&aa);
3751: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3752: b = (PetscScalar***)((*a) + m);
3753: c = (PetscScalar**)(b + m*n);
3754: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3755: for (i=0; i<m; i++)
3756: for (j=0; j<n; j++)
3757: b[i*n+j] = c + i*n*p + j*p - pstart;
3758: for (i=0; i<m; i++)
3759: for (j=0; j<n; j++)
3760: for (k=0; k<p; k++)
3761: c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
3762: *a -= mstart;
3763: return(0);
3764: }
3766: /*@C
3767: VecRestoreArray4dRead - Restores a vector after VecGetArray3d() has been called.
3769: Logically Collective
3771: Input Parameters:
3772: + x - the vector
3773: . m - first dimension of four dimensional array
3774: . n - second dimension of the four dimensional array
3775: . p - third dimension of the four dimensional array
3776: . q - fourth dimension of the four dimensional array
3777: . mstart - first index you will use in first coordinate direction (often 0)
3778: . nstart - first index in the second coordinate direction (often 0)
3779: . pstart - first index in the third coordinate direction (often 0)
3780: . qstart - first index in the fourth coordinate direction (often 0)
3781: - a - location of pointer to array obtained from VecGetArray4dRead()
3783: Level: beginner
3785: Notes:
3786: For regular PETSc vectors this routine does not involve any copies. For
3787: any special vectors that do not store local vector data in a contiguous
3788: array, this routine will copy the data back into the underlying
3789: vector data structure from the array obtained with VecGetArray().
3791: This routine actually zeros out the a pointer.
3793: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3794: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3795: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3796: @*/
3797: PetscErrorCode VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3798: {
3800: void *dummy;
3806: dummy = (void*)(*a + mstart);
3807: PetscFree(dummy);
3808: VecRestoreArrayRead(x,NULL);
3809: return(0);
3810: }
3812: #if defined(PETSC_USE_DEBUG)
3814: /*@
3815: VecLockGet - Gets the current lock status of a vector
3817: Logically Collective on Vec
3819: Input Parameter:
3820: . x - the vector
3822: Output Parameter:
3823: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
3824: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
3826: Level: beginner
3828: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop()
3829: @*/
3830: PetscErrorCode VecLockGet(Vec x,PetscInt *state)
3831: {
3834: *state = x->lock;
3835: return(0);
3836: }
3838: /*@
3839: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from writing
3841: Logically Collective on Vec
3843: Input Parameter:
3844: . x - the vector
3846: Notes:
3847: If this is set then calls to VecGetArray() or VecSetValues() or any other routines that change the vectors values will fail.
3849: The call can be nested, i.e., called multiple times on the same vector, but each VecLockReadPush(x) has to have one matching
3850: VecLockReadPop(x), which removes the latest read-only lock.
3852: Level: beginner
3854: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPop(), VecLockGet()
3855: @*/
3856: PetscErrorCode VecLockReadPush(Vec x)
3857: {
3860: if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to read it");
3861: x->lock++;
3862: return(0);
3863: }
3865: /*@
3866: VecLockReadPop - Pops a read-only lock from a vector
3868: Logically Collective on Vec
3870: Input Parameter:
3871: . x - the vector
3873: Level: beginner
3875: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockGet()
3876: @*/
3877: PetscErrorCode VecLockReadPop(Vec x)
3878: {
3881: x->lock--;
3882: if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector has been unlocked from read-only access too many times");
3883: return(0);
3884: }
3886: /*@C
3887: VecLockWriteSet_Private - Lock or unlock a vector for exclusive read/write access
3889: Logically Collective on Vec
3891: Input Parameter:
3892: + x - the vector
3893: - flg - PETSC_TRUE to lock the vector for writing; PETSC_FALSE to unlock it.
3895: Notes:
3896: The function is usefull in split-phase computations, which usually have a begin phase and an end phase.
3897: One can call VecLockWriteSet_Private(x,PETSC_TRUE) in the begin phase to lock a vector for exclusive
3898: access, and call VecLockWriteSet_Private(x,PETSC_FALSE) in the end phase to unlock the vector from exclusive
3899: access. In this way, one is ensured no other operations can access the vector in between. The code may like
3902: VecGetArray(x,&xdata); // begin phase
3903: VecLockWriteSet_Private(v,PETSC_TRUE);
3905: Other operations, which can not acceess x anymore (they can access xdata, of course)
3907: VecRestoreArray(x,&vdata); // end phase
3908: VecLockWriteSet_Private(v,PETSC_FALSE);
3910: The call can not be nested on the same vector, in other words, one can not call VecLockWriteSet_Private(x,PETSC_TRUE)
3911: again before calling VecLockWriteSet_Private(v,PETSC_FALSE).
3913: Level: beginner
3915: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop(), VecLockGet()
3916: @*/
3917: PetscErrorCode VecLockWriteSet_Private(Vec x,PetscBool flg)
3918: {
3921: if (flg) {
3922: if (x->lock > 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for read-only access but you want to write it");
3923: else if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is already locked for exclusive write access but you want to write it");
3924: else x->lock = -1;
3925: } else {
3926: if (x->lock != -1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector is not locked for exclusive write access but you want to unlock it from that");
3927: x->lock = 0;
3928: }
3929: return(0);
3930: }
3932: /*@
3933: VecLockPush - Pushes a read-only lock on a vector to prevent it from writing
3935: Level: deprecated
3937: .seealso: VecLockReadPush()
3938: @*/
3939: PetscErrorCode VecLockPush(Vec x)
3940: {
3943: VecLockReadPush(x);
3944: return(0);
3945: }
3947: /*@
3948: VecLockPop - Pops a read-only lock from a vector
3950: Level: deprecated
3952: .seealso: VecLockReadPop()
3953: @*/
3954: PetscErrorCode VecLockPop(Vec x)
3955: {
3958: VecLockReadPop(x);
3959: return(0);
3960: }
3962: #endif