Actual source code: rvector.c
petsc-3.12.0 2019-09-29
2: /*
3: Provides the interface functions for vector operations that have PetscScalar/PetscReal in the signature
4: These are the vector functions the user calls.
5: */
6: #include <petsc/private/vecimpl.h>
7: #if defined(PETSC_HAVE_CUDA)
8: #include <../src/vec/vec/impls/dvecimpl.h>
9: #include <../src/vec/vec/impls/seq/seqcuda/cudavecimpl.h>
10: #endif
11: static PetscInt VecGetSubVectorSavedStateId = -1;
13: PETSC_EXTERN PetscErrorCode VecValidValues(Vec vec,PetscInt argnum,PetscBool begin)
14: {
15: #if defined(PETSC_USE_DEBUG)
16: PetscErrorCode ierr;
17: PetscInt n,i;
18: const PetscScalar *x;
21: #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_VIENNACL)
22: if ((vec->petscnative || vec->ops->getarray) && (vec->valid_GPU_array == PETSC_OFFLOAD_CPU || vec->valid_GPU_array == PETSC_OFFLOAD_BOTH)) {
23: #else
24: if (vec->petscnative || vec->ops->getarray) {
25: #endif
26: VecGetLocalSize(vec,&n);
27: VecGetArrayRead(vec,&x);
28: for (i=0; i<n; i++) {
29: if (begin) {
30: 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);
31: } else {
32: 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);
33: }
34: }
35: VecRestoreArrayRead(vec,&x);
36: }
37: return(0);
38: #else
39: return 0;
40: #endif
41: }
43: /*@
44: VecMaxPointwiseDivide - Computes the maximum of the componentwise division max = max_i abs(x_i/y_i).
46: Logically Collective on Vec
48: Input Parameters:
49: . x, y - the vectors
51: Output Parameter:
52: . max - the result
54: Level: advanced
56: Notes:
57: x and y may be the same vector
58: if a particular y_i is zero, it is treated as 1 in the above formula
60: .seealso: VecPointwiseDivide(), VecPointwiseMult(), VecPointwiseMax(), VecPointwiseMin(), VecPointwiseMaxAbs()
61: @*/
62: PetscErrorCode VecMaxPointwiseDivide(Vec x,Vec y,PetscReal *max)
63: {
73: VecCheckSameSize(x,1,y,2);
74: (*x->ops->maxpointwisedivide)(x,y,max);
75: return(0);
76: }
78: /*@
79: VecDot - Computes the vector dot product.
81: Collective on Vec
83: Input Parameters:
84: . x, y - the vectors
86: Output Parameter:
87: . val - the dot product
89: Performance Issues:
90: $ per-processor memory bandwidth
91: $ interprocessor latency
92: $ work load inbalance that causes certain processes to arrive much earlier than others
94: Notes for Users of Complex Numbers:
95: For complex vectors, VecDot() computes
96: $ val = (x,y) = y^H x,
97: where y^H denotes the conjugate transpose of y. Note that this corresponds to the usual "mathematicians" complex
98: inner product where the SECOND argument gets the complex conjugate. Since the BLASdot() complex conjugates the first
99: first argument we call the BLASdot() with the arguments reversed.
101: Use VecTDot() for the indefinite form
102: $ val = (x,y) = y^T x,
103: where y^T denotes the transpose of y.
105: Level: intermediate
108: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDotRealPart()
109: @*/
110: PetscErrorCode VecDot(Vec x,Vec y,PetscScalar *val)
111: {
121: VecCheckSameSize(x,1,y,2);
123: PetscLogEventBegin(VEC_Dot,x,y,0,0);
124: (*x->ops->dot)(x,y,val);
125: PetscLogEventEnd(VEC_Dot,x,y,0,0);
126: return(0);
127: }
129: /*@
130: VecDotRealPart - Computes the real part of the vector dot product.
132: Collective on Vec
134: Input Parameters:
135: . x, y - the vectors
137: Output Parameter:
138: . val - the real part of the dot product;
140: Performance Issues:
141: $ per-processor memory bandwidth
142: $ interprocessor latency
143: $ work load inbalance that causes certain processes to arrive much earlier than others
145: Notes for Users of Complex Numbers:
146: See VecDot() for more details on the definition of the dot product for complex numbers
148: For real numbers this returns the same value as VecDot()
150: 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
151: the space R^{2n} (that is a vector of 2n components with the real or imaginary part of the complex numbers for components)
153: Developer Note: This is not currently optimized to compute only the real part of the dot product.
155: Level: intermediate
158: .seealso: VecMDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecDot(), VecDotNorm2()
159: @*/
160: PetscErrorCode VecDotRealPart(Vec x,Vec y,PetscReal *val)
161: {
163: PetscScalar fdot;
166: VecDot(x,y,&fdot);
167: *val = PetscRealPart(fdot);
168: return(0);
169: }
171: /*@
172: VecNorm - Computes the vector norm.
174: Collective on Vec
176: Input Parameters:
177: + x - the vector
178: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
179: NORM_1_AND_2, which computes both norms and stores them
180: in a two element array.
182: Output Parameter:
183: . val - the norm
185: Notes:
186: $ NORM_1 denotes sum_i |x_i|
187: $ NORM_2 denotes sqrt(sum_i |x_i|^2)
188: $ NORM_INFINITY denotes max_i |x_i|
190: For complex numbers NORM_1 will return the traditional 1 norm of the 2 norm of the complex numbers; that is the 1
191: norm of the absolutely values of the complex entries. In PETSc 3.6 and earlier releases it returned the 1 norm of
192: the 1 norm of the complex entries (what is returned by the BLAS routine asum()). Both are valid norms but most
193: people expect the former.
195: Level: intermediate
197: Performance Issues:
198: $ per-processor memory bandwidth
199: $ interprocessor latency
200: $ work load inbalance that causes certain processes to arrive much earlier than others
203: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNormAvailable(),
204: VecNormBegin(), VecNormEnd()
206: @*/
208: PetscErrorCode VecNorm(Vec x,NormType type,PetscReal *val)
209: {
210: PetscBool flg;
218: /*
219: * Cached data?
220: */
221: if (type!=NORM_1_AND_2) {
222: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,flg);
223: if (flg) return(0);
224: }
225: PetscLogEventBegin(VEC_Norm,x,0,0,0);
226: (*x->ops->norm)(x,type,val);
227: PetscLogEventEnd(VEC_Norm,x,0,0,0);
228: if (type!=NORM_1_AND_2) {
229: PetscObjectComposedDataSetReal((PetscObject)x,NormIds[type],*val);
230: }
231: return(0);
232: }
234: /*@
235: VecNormAvailable - Returns the vector norm if it is already known.
237: Not Collective
239: Input Parameters:
240: + x - the vector
241: - type - one of NORM_1, NORM_2, NORM_INFINITY. Also available
242: NORM_1_AND_2, which computes both norms and stores them
243: in a two element array.
245: Output Parameter:
246: + available - PETSC_TRUE if the val returned is valid
247: - val - the norm
249: Notes:
250: $ NORM_1 denotes sum_i |x_i|
251: $ NORM_2 denotes sqrt(sum_i (x_i)^2)
252: $ NORM_INFINITY denotes max_i |x_i|
254: Level: intermediate
256: Performance Issues:
257: $ per-processor memory bandwidth
258: $ interprocessor latency
259: $ work load inbalance that causes certain processes to arrive much earlier than others
261: Compile Option:
262: PETSC_HAVE_SLOW_BLAS_NORM2 will cause a C (loop unrolled) version of the norm to be used, rather
263: than the BLAS. This should probably only be used when one is using the FORTRAN BLAS routines
264: (as opposed to vendor provided) because the FORTRAN BLAS NRM2() routine is very slow.
267: .seealso: VecDot(), VecTDot(), VecNorm(), VecDotBegin(), VecDotEnd(), VecNorm()
268: VecNormBegin(), VecNormEnd()
270: @*/
271: PetscErrorCode VecNormAvailable(Vec x,NormType type,PetscBool *available,PetscReal *val)
272: {
280: *available = PETSC_FALSE;
281: if (type!=NORM_1_AND_2) {
282: PetscObjectComposedDataGetReal((PetscObject)x,NormIds[type],*val,*available);
283: }
284: return(0);
285: }
287: /*@
288: VecNormalize - Normalizes a vector by 2-norm.
290: Collective on Vec
292: Input Parameters:
293: + x - the vector
295: Output Parameter:
296: . x - the normalized vector
297: - val - the vector norm before normalization
299: Level: intermediate
302: @*/
303: PetscErrorCode VecNormalize(Vec x,PetscReal *val)
304: {
306: PetscReal norm;
311: PetscLogEventBegin(VEC_Normalize,x,0,0,0);
312: VecNorm(x,NORM_2,&norm);
313: if (norm == 0.0) {
314: PetscInfo(x,"Vector of zero norm can not be normalized; Returning only the zero norm\n");
315: } else if (norm != 1.0) {
316: PetscScalar tmp = 1.0/norm;
317: VecScale(x,tmp);
318: }
319: if (val) *val = norm;
320: PetscLogEventEnd(VEC_Normalize,x,0,0,0);
321: return(0);
322: }
324: /*@C
325: VecMax - Determines the vector component with maximum real part and its location.
327: Collective on Vec
329: Input Parameter:
330: . x - the vector
332: Output Parameters:
333: + p - the location of val (pass NULL if you don't want this)
334: - val - the maximum component
336: Notes:
337: Returns the value PETSC_MIN_REAL and p = -1 if the vector is of length 0.
339: Returns the smallest index with the maximum value
340: Level: intermediate
343: .seealso: VecNorm(), VecMin()
344: @*/
345: PetscErrorCode VecMax(Vec x,PetscInt *p,PetscReal *val)
346: {
353: PetscLogEventBegin(VEC_Max,x,0,0,0);
354: (*x->ops->max)(x,p,val);
355: PetscLogEventEnd(VEC_Max,x,0,0,0);
356: return(0);
357: }
359: /*@C
360: VecMin - Determines the vector component with minimum real part and its location.
362: Collective on Vec
364: Input Parameters:
365: . x - the vector
367: Output Parameter:
368: + p - the location of val (pass NULL if you don't want this location)
369: - val - the minimum component
371: Level: intermediate
373: Notes:
374: Returns the value PETSC_MAX_REAL and p = -1 if the vector is of length 0.
376: This returns the smallest index with the minumum value
379: .seealso: VecMax()
380: @*/
381: PetscErrorCode VecMin(Vec x,PetscInt *p,PetscReal *val)
382: {
389: PetscLogEventBegin(VEC_Min,x,0,0,0);
390: (*x->ops->min)(x,p,val);
391: PetscLogEventEnd(VEC_Min,x,0,0,0);
392: return(0);
393: }
395: /*@
396: VecTDot - Computes an indefinite vector dot product. That is, this
397: routine does NOT use the complex conjugate.
399: Collective on Vec
401: Input Parameters:
402: . x, y - the vectors
404: Output Parameter:
405: . val - the dot product
407: Notes for Users of Complex Numbers:
408: For complex vectors, VecTDot() computes the indefinite form
409: $ val = (x,y) = y^T x,
410: where y^T denotes the transpose of y.
412: Use VecDot() for the inner product
413: $ val = (x,y) = y^H x,
414: where y^H denotes the conjugate transpose of y.
416: Level: intermediate
418: .seealso: VecDot(), VecMTDot()
419: @*/
420: PetscErrorCode VecTDot(Vec x,Vec y,PetscScalar *val)
421: {
431: VecCheckSameSize(x,1,y,2);
433: PetscLogEventBegin(VEC_TDot,x,y,0,0);
434: (*x->ops->tdot)(x,y,val);
435: PetscLogEventEnd(VEC_TDot,x,y,0,0);
436: return(0);
437: }
439: /*@
440: VecScale - Scales a vector.
442: Not collective on Vec
444: Input Parameters:
445: + x - the vector
446: - alpha - the scalar
448: Output Parameter:
449: . x - the scaled vector
451: Note:
452: For a vector with n components, VecScale() computes
453: $ x[i] = alpha * x[i], for i=1,...,n.
455: Level: intermediate
458: @*/
459: PetscErrorCode VecScale(Vec x, PetscScalar alpha)
460: {
461: PetscReal norms[4] = {0.0,0.0,0.0, 0.0};
462: PetscBool flgs[4];
464: PetscInt i;
469: if (x->stash.insertmode != NOT_SET_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled vector");
470: PetscLogEventBegin(VEC_Scale,x,0,0,0);
471: if (alpha != (PetscScalar)1.0) {
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: VecSetErrorIfLocked(y,1);
596: VecLockReadPush(x);
597: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
598: (*y->ops->axpy)(y,alpha,x);
599: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
600: VecLockReadPop(x);
601: PetscObjectStateIncrease((PetscObject)y);
602: return(0);
603: }
605: /*@
606: VecAXPBY - Computes y = alpha x + beta y.
608: Logically Collective on Vec
610: Input Parameters:
611: + alpha,beta - the scalars
612: - x, y - the vectors
614: Output Parameter:
615: . y - output vector
617: Level: intermediate
619: Notes:
620: x and y MUST be different vectors
621: The implementation is optimized for alpha and/or beta values of 0.0 and 1.0
624: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ()
625: @*/
626: PetscErrorCode VecAXPBY(Vec y,PetscScalar alpha,PetscScalar beta,Vec x)
627: {
636: VecCheckSameSize(y,1,x,4);
637: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y cannot be the same vector");
640: PetscLogEventBegin(VEC_AXPY,x,y,0,0);
641: (*y->ops->axpby)(y,alpha,beta,x);
642: PetscLogEventEnd(VEC_AXPY,x,y,0,0);
643: PetscObjectStateIncrease((PetscObject)y);
644: return(0);
645: }
647: /*@
648: VecAXPBYPCZ - Computes z = alpha x + beta y + gamma z
650: Logically Collective on Vec
652: Input Parameters:
653: + alpha,beta, gamma - the scalars
654: - x, y, z - the vectors
656: Output Parameter:
657: . z - output vector
659: Level: intermediate
661: Notes:
662: x, y and z must be different vectors
663: The implementation is optimized for alpha of 1.0 and gamma of 1.0 or 0.0
666: .seealso: VecAYPX(), VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBY()
667: @*/
668: PetscErrorCode VecAXPBYPCZ(Vec z,PetscScalar alpha,PetscScalar beta,PetscScalar gamma,Vec x,Vec y)
669: {
681: VecCheckSameSize(x,1,y,5);
682: VecCheckSameSize(x,1,z,6);
683: if (x == y || x == z) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
684: if (y == z) SETERRQ(PetscObjectComm((PetscObject)y),PETSC_ERR_ARG_IDN,"x, y, and z must be different vectors");
689: PetscLogEventBegin(VEC_AXPBYPCZ,x,y,z,0);
690: (*y->ops->axpbypcz)(z,alpha,beta,gamma,x,y);
691: PetscLogEventEnd(VEC_AXPBYPCZ,x,y,z,0);
692: PetscObjectStateIncrease((PetscObject)z);
693: return(0);
694: }
696: /*@
697: VecAYPX - Computes y = x + beta y.
699: Logically Collective on Vec
701: Input Parameters:
702: + beta - the scalar
703: - x, y - the vectors
705: Output Parameter:
706: . y - output vector
708: Level: intermediate
710: Notes:
711: x and y MUST be different vectors
712: The implementation is optimized for beta of -1.0, 0.0, and 1.0
715: .seealso: VecMAXPY(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
716: @*/
717: PetscErrorCode VecAYPX(Vec y,PetscScalar beta,Vec x)
718: {
727: VecCheckSameSize(x,1,y,3);
728: if (x == y) SETERRQ(PetscObjectComm((PetscObject)x),PETSC_ERR_ARG_IDN,"x and y must be different vectors");
731: PetscLogEventBegin(VEC_AYPX,x,y,0,0);
732: (*y->ops->aypx)(y,beta,x);
733: PetscLogEventEnd(VEC_AYPX,x,y,0,0);
734: PetscObjectStateIncrease((PetscObject)y);
735: return(0);
736: }
739: /*@
740: VecWAXPY - Computes w = alpha x + y.
742: Logically Collective on Vec
744: Input Parameters:
745: + alpha - the scalar
746: - x, y - the vectors
748: Output Parameter:
749: . w - the result
751: Level: intermediate
753: Notes:
754: w cannot be either x or y, but x and y can be the same
755: The implementation is optimzed for alpha of -1.0, 0.0, and 1.0
758: .seealso: VecAXPY(), VecAYPX(), VecAXPBY(), VecMAXPY(), VecAXPBYPCZ()
759: @*/
760: PetscErrorCode VecWAXPY(Vec w,PetscScalar alpha,Vec x,Vec y)
761: {
773: VecCheckSameSize(x,3,y,4);
774: VecCheckSameSize(x,3,w,1);
775: if (w == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector y, suggest VecAXPY()");
776: if (w == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Result vector w cannot be same as input vector x, suggest VecAYPX()");
779: PetscLogEventBegin(VEC_WAXPY,x,y,w,0);
780: (*w->ops->waxpy)(w,alpha,x,y);
781: PetscLogEventEnd(VEC_WAXPY,x,y,w,0);
782: PetscObjectStateIncrease((PetscObject)w);
783: return(0);
784: }
787: /*@C
788: VecSetValues - Inserts or adds values into certain locations of a vector.
790: Not Collective
792: Input Parameters:
793: + x - vector to insert in
794: . ni - number of elements to add
795: . ix - indices where to add
796: . y - array of values
797: - iora - either INSERT_VALUES or ADD_VALUES, where
798: ADD_VALUES adds values to any existing entries, and
799: INSERT_VALUES replaces existing entries with new values
801: Notes:
802: VecSetValues() sets x[ix[i]] = y[i], for i=0,...,ni-1.
804: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
805: options cannot be mixed without intervening calls to the assembly
806: routines.
808: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
809: MUST be called after all calls to VecSetValues() have been completed.
811: VecSetValues() uses 0-based indices in Fortran as well as in C.
813: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
814: negative indices may be passed in ix. These rows are
815: simply ignored. This allows easily inserting element load matrices
816: with homogeneous Dirchlet boundary conditions that you don't want represented
817: in the vector.
819: Level: beginner
821: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesLocal(),
822: VecSetValue(), VecSetValuesBlocked(), InsertMode, INSERT_VALUES, ADD_VALUES, VecGetValues()
823: @*/
824: PetscErrorCode VecSetValues(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
825: {
830: if (!ni) return(0);
834: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
835: (*x->ops->setvalues)(x,ni,ix,y,iora);
836: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
837: PetscObjectStateIncrease((PetscObject)x);
838: return(0);
839: }
841: /*@
842: VecGetValues - Gets values from certain locations of a vector. Currently
843: can only get values on the same processor
845: Not Collective
847: Input Parameters:
848: + x - vector to get values from
849: . ni - number of elements to get
850: - ix - indices where to get them from (in global 1d numbering)
852: Output Parameter:
853: . y - array of values
855: Notes:
856: The user provides the allocated array y; it is NOT allocated in this routine
858: VecGetValues() gets y[i] = x[ix[i]], for i=0,...,ni-1.
860: VecAssemblyBegin() and VecAssemblyEnd() MUST be called before calling this
862: VecGetValues() uses 0-based indices in Fortran as well as in C.
864: If you call VecSetOption(x, VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE),
865: negative indices may be passed in ix. These rows are
866: simply ignored.
868: Level: beginner
870: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues()
871: @*/
872: PetscErrorCode VecGetValues(Vec x,PetscInt ni,const PetscInt ix[],PetscScalar y[])
873: {
878: if (!ni) return(0);
882: (*x->ops->getvalues)(x,ni,ix,y);
883: return(0);
884: }
886: /*@C
887: VecSetValuesBlocked - Inserts or adds blocks of values into certain locations of a vector.
889: Not Collective
891: Input Parameters:
892: + x - vector to insert in
893: . ni - number of blocks to add
894: . ix - indices where to add in block count, rather than element count
895: . y - array of values
896: - iora - either INSERT_VALUES or ADD_VALUES, where
897: ADD_VALUES adds values to any existing entries, and
898: INSERT_VALUES replaces existing entries with new values
900: Notes:
901: VecSetValuesBlocked() sets x[bs*ix[i]+j] = y[bs*i+j],
902: for j=0,...,bs-1, for i=0,...,ni-1. where bs was set with VecSetBlockSize().
904: Calls to VecSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
905: options cannot be mixed without intervening calls to the assembly
906: routines.
908: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
909: MUST be called after all calls to VecSetValuesBlocked() have been completed.
911: VecSetValuesBlocked() uses 0-based indices in Fortran as well as in C.
913: Negative indices may be passed in ix, these rows are
914: simply ignored. This allows easily inserting element load matrices
915: with homogeneous Dirchlet boundary conditions that you don't want represented
916: in the vector.
918: Level: intermediate
920: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValuesBlockedLocal(),
921: VecSetValues()
922: @*/
923: PetscErrorCode VecSetValuesBlocked(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
924: {
929: if (!ni) return(0);
933: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
934: (*x->ops->setvaluesblocked)(x,ni,ix,y,iora);
935: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
936: PetscObjectStateIncrease((PetscObject)x);
937: return(0);
938: }
941: /*@C
942: VecSetValuesLocal - Inserts or adds values into certain locations of a vector,
943: using a local ordering of the nodes.
945: Not Collective
947: Input Parameters:
948: + x - vector to insert in
949: . ni - number of elements to add
950: . ix - indices where to add
951: . y - array of values
952: - iora - either INSERT_VALUES or ADD_VALUES, where
953: ADD_VALUES adds values to any existing entries, and
954: INSERT_VALUES replaces existing entries with new values
956: Level: intermediate
958: Notes:
959: VecSetValuesLocal() sets x[ix[i]] = y[i], for i=0,...,ni-1.
961: Calls to VecSetValues() with the INSERT_VALUES and ADD_VALUES
962: options cannot be mixed without intervening calls to the assembly
963: routines.
965: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
966: MUST be called after all calls to VecSetValuesLocal() have been completed.
968: VecSetValuesLocal() uses 0-based indices in Fortran as well as in C.
970: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetLocalToGlobalMapping(),
971: VecSetValuesBlockedLocal()
972: @*/
973: PetscErrorCode VecSetValuesLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
974: {
976: PetscInt lixp[128],*lix = lixp;
980: if (!ni) return(0);
985: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
986: if (!x->ops->setvalueslocal) {
987: if (!x->map->mapping) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Local to global never set with VecSetLocalToGlobalMapping()");
988: if (ni > 128) {
989: PetscMalloc1(ni,&lix);
990: }
991: ISLocalToGlobalMappingApply(x->map->mapping,ni,(PetscInt*)ix,lix);
992: (*x->ops->setvalues)(x,ni,lix,y,iora);
993: if (ni > 128) {
994: PetscFree(lix);
995: }
996: } else {
997: (*x->ops->setvalueslocal)(x,ni,ix,y,iora);
998: }
999: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1000: PetscObjectStateIncrease((PetscObject)x);
1001: return(0);
1002: }
1004: /*@
1005: VecSetValuesBlockedLocal - Inserts or adds values into certain locations of a vector,
1006: using a local ordering of the nodes.
1008: Not Collective
1010: Input Parameters:
1011: + x - vector to insert in
1012: . ni - number of blocks to add
1013: . ix - indices where to add in block count, not element count
1014: . y - array of values
1015: - iora - either INSERT_VALUES or ADD_VALUES, where
1016: ADD_VALUES adds values to any existing entries, and
1017: INSERT_VALUES replaces existing entries with new values
1019: Level: intermediate
1021: Notes:
1022: VecSetValuesBlockedLocal() sets x[bs*ix[i]+j] = y[bs*i+j],
1023: for j=0,..bs-1, for i=0,...,ni-1, where bs has been set with VecSetBlockSize().
1025: Calls to VecSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
1026: options cannot be mixed without intervening calls to the assembly
1027: routines.
1029: These values may be cached, so VecAssemblyBegin() and VecAssemblyEnd()
1030: MUST be called after all calls to VecSetValuesBlockedLocal() have been completed.
1032: VecSetValuesBlockedLocal() uses 0-based indices in Fortran as well as in C.
1035: .seealso: VecAssemblyBegin(), VecAssemblyEnd(), VecSetValues(), VecSetValuesBlocked(),
1036: VecSetLocalToGlobalMapping()
1037: @*/
1038: PetscErrorCode VecSetValuesBlockedLocal(Vec x,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode iora)
1039: {
1041: PetscInt lixp[128],*lix = lixp;
1045: if (!ni) return(0);
1049: if (ni > 128) {
1050: PetscMalloc1(ni,&lix);
1051: }
1053: PetscLogEventBegin(VEC_SetValues,x,0,0,0);
1054: ISLocalToGlobalMappingApplyBlock(x->map->mapping,ni,(PetscInt*)ix,lix);
1055: (*x->ops->setvaluesblocked)(x,ni,lix,y,iora);
1056: PetscLogEventEnd(VEC_SetValues,x,0,0,0);
1057: if (ni > 128) {
1058: PetscFree(lix);
1059: }
1060: PetscObjectStateIncrease((PetscObject)x);
1061: return(0);
1062: }
1064: /*@
1065: VecMTDot - Computes indefinite vector multiple dot products.
1066: That is, it does NOT use the complex conjugate.
1068: Collective on Vec
1070: Input Parameters:
1071: + x - one vector
1072: . nv - number of vectors
1073: - y - array of vectors. Note that vectors are pointers
1075: Output Parameter:
1076: . val - array of the dot products
1078: Notes for Users of Complex Numbers:
1079: For complex vectors, VecMTDot() computes the indefinite form
1080: $ val = (x,y) = y^T x,
1081: where y^T denotes the transpose of y.
1083: Use VecMDot() for the inner product
1084: $ val = (x,y) = y^H x,
1085: where y^H denotes the conjugate transpose of y.
1087: Level: intermediate
1090: .seealso: VecMDot(), VecTDot()
1091: @*/
1092: PetscErrorCode VecMTDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1093: {
1099: if (!nv) return(0);
1106: VecCheckSameSize(x,1,*y,3);
1108: PetscLogEventBegin(VEC_MTDot,x,*y,0,0);
1109: (*x->ops->mtdot)(x,nv,y,val);
1110: PetscLogEventEnd(VEC_MTDot,x,*y,0,0);
1111: return(0);
1112: }
1114: /*@
1115: VecMDot - Computes vector multiple dot products.
1117: Collective on Vec
1119: Input Parameters:
1120: + x - one vector
1121: . nv - number of vectors
1122: - y - array of vectors.
1124: Output Parameter:
1125: . val - array of the dot products (does not allocate the array)
1127: Notes for Users of Complex Numbers:
1128: For complex vectors, VecMDot() computes
1129: $ val = (x,y) = y^H x,
1130: where y^H denotes the conjugate transpose of y.
1132: Use VecMTDot() for the indefinite form
1133: $ val = (x,y) = y^T x,
1134: where y^T denotes the transpose of y.
1136: Level: intermediate
1139: .seealso: VecMTDot(), VecDot()
1140: @*/
1141: PetscErrorCode VecMDot(Vec x,PetscInt nv,const Vec y[],PetscScalar val[])
1142: {
1148: if (!nv) return(0);
1149: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1156: VecCheckSameSize(x,1,*y,3);
1158: PetscLogEventBegin(VEC_MDot,x,*y,0,0);
1159: (*x->ops->mdot)(x,nv,y,val);
1160: PetscLogEventEnd(VEC_MDot,x,*y,0,0);
1161: return(0);
1162: }
1164: /*@
1165: VecMAXPY - Computes y = y + sum alpha[i] x[i]
1167: Logically Collective on Vec
1169: Input Parameters:
1170: + nv - number of scalars and x-vectors
1171: . alpha - array of scalars
1172: . y - one vector
1173: - x - array of vectors
1175: Level: intermediate
1177: Notes:
1178: y cannot be any of the x vectors
1180: .seealso: VecAYPX(), VecWAXPY(), VecAXPY(), VecAXPBYPCZ(), VecAXPBY()
1181: @*/
1182: PetscErrorCode VecMAXPY(Vec y,PetscInt nv,const PetscScalar alpha[],Vec x[])
1183: {
1185: PetscInt i;
1190: if (!nv) return(0);
1191: if (nv < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Number of vectors (given %D) cannot be negative",nv);
1198: VecCheckSameSize(y,1,*x,4);
1201: PetscLogEventBegin(VEC_MAXPY,*x,y,0,0);
1202: (*y->ops->maxpy)(y,nv,alpha,x);
1203: PetscLogEventEnd(VEC_MAXPY,*x,y,0,0);
1204: PetscObjectStateIncrease((PetscObject)y);
1205: return(0);
1206: }
1208: /*@
1209: VecGetSubVector - Gets a vector representing part of another vector
1211: Collective on IS
1213: Input Arguments:
1214: + X - vector from which to extract a subvector
1215: - is - index set representing portion of X to extract
1217: Output Arguments:
1218: . Y - subvector corresponding to is
1220: Level: advanced
1222: Notes:
1223: The subvector Y should be returned with VecRestoreSubVector().
1225: This function may return a subvector without making a copy, therefore it is not safe to use the original vector while
1226: modifying the subvector. Other non-overlapping subvectors can still be obtained from X using this function.
1228: .seealso: MatCreateSubMatrix()
1229: @*/
1230: PetscErrorCode VecGetSubVector(Vec X,IS is,Vec *Y)
1231: {
1232: PetscErrorCode ierr;
1233: Vec Z;
1239: if (X->ops->getsubvector) {
1240: (*X->ops->getsubvector)(X,is,&Z);
1241: } else { /* Default implementation currently does no caching */
1242: PetscInt gstart,gend,start;
1243: PetscBool contiguous,gcontiguous;
1244: VecGetOwnershipRange(X,&gstart,&gend);
1245: ISContiguousLocal(is,gstart,gend,&start,&contiguous);
1246: MPIU_Allreduce(&contiguous,&gcontiguous,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)is));
1247: if (gcontiguous) { /* We can do a no-copy implementation */
1248: PetscInt n,N,bs;
1249: PetscInt state;
1251: ISGetSize(is,&N);
1252: ISGetLocalSize(is,&n);
1253: VecGetBlockSize(X,&bs);
1254: if (n%bs || bs == 1 || !n) bs = -1; /* Do not decide block size if we do not have to */
1255: VecLockGet(X,&state);
1256: if (state) {
1257: const PetscScalar *x;
1258: VecGetArrayRead(X,&x);
1259: VecCreate(PetscObjectComm((PetscObject)X),&Z);
1260: VecSetType(Z,((PetscObject)X)->type_name);
1261: VecSetSizes(Z,n,N);
1262: VecSetBlockSize(Z,bs);
1263: VecPlaceArray(Z,(PetscScalar*)x+start);
1264: VecLockReadPush(Z);
1265: VecRestoreArrayRead(X,&x);
1266: } else {
1267: PetscScalar *x;
1268: VecGetArray(X,&x);
1269: VecCreate(PetscObjectComm((PetscObject)X),&Z);
1270: VecSetType(Z,((PetscObject)X)->type_name);
1271: VecSetSizes(Z,n,N);
1272: VecSetBlockSize(Z,bs);
1273: VecPlaceArray(Z,(PetscScalar*)x+start);
1274: VecRestoreArray(X,&x);
1275: }
1276: } else { /* Have to create a scatter and do a copy */
1277: VecScatter scatter;
1278: PetscInt n,N;
1279: ISGetLocalSize(is,&n);
1280: ISGetSize(is,&N);
1281: VecCreate(PetscObjectComm((PetscObject)is),&Z);
1282: VecSetSizes(Z,n,N);
1283: VecSetType(Z,((PetscObject)X)->type_name);
1284: VecScatterCreate(X,is,Z,NULL,&scatter);
1285: VecScatterBegin(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1286: VecScatterEnd(scatter,X,Z,INSERT_VALUES,SCATTER_FORWARD);
1287: PetscObjectCompose((PetscObject)Z,"VecGetSubVector_Scatter",(PetscObject)scatter);
1288: VecScatterDestroy(&scatter);
1289: }
1290: }
1291: /* Record the state when the subvector was gotten so we know whether its values need to be put back */
1292: if (VecGetSubVectorSavedStateId < 0) {PetscObjectComposedDataRegister(&VecGetSubVectorSavedStateId);}
1293: PetscObjectComposedDataSetInt((PetscObject)Z,VecGetSubVectorSavedStateId,1);
1294: *Y = Z;
1295: return(0);
1296: }
1298: /*@
1299: VecRestoreSubVector - Restores a subvector extracted using VecGetSubVector()
1301: Collective on IS
1303: Input Arguments:
1304: + X - vector from which subvector was obtained
1305: . is - index set representing the subset of X
1306: - Y - subvector being restored
1308: Level: advanced
1310: .seealso: VecGetSubVector()
1311: @*/
1312: PetscErrorCode VecRestoreSubVector(Vec X,IS is,Vec *Y)
1313: {
1321: if (X->ops->restoresubvector) {
1322: (*X->ops->restoresubvector)(X,is,Y);
1323: } else {
1324: PETSC_UNUSED PetscObjectState dummystate = 0;
1325: PetscBool valid;
1326: PetscObjectComposedDataGetInt((PetscObject)*Y,VecGetSubVectorSavedStateId,dummystate,valid);
1327: if (!valid) {
1328: VecScatter scatter;
1330: PetscObjectQuery((PetscObject)*Y,"VecGetSubVector_Scatter",(PetscObject*)&scatter);
1331: if (scatter) {
1332: VecScatterBegin(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1333: VecScatterEnd(scatter,*Y,X,INSERT_VALUES,SCATTER_REVERSE);
1334: }
1335: }
1336: VecDestroy(Y);
1337: }
1338: return(0);
1339: }
1341: /*@
1342: VecGetLocalVectorRead - Maps the local portion of a vector into a
1343: vector. You must call VecRestoreLocalVectorRead() when the local
1344: vector is no longer needed.
1346: Not collective.
1348: Input parameter:
1349: . v - The vector for which the local vector is desired.
1351: Output parameter:
1352: . w - Upon exit this contains the local vector.
1354: Level: beginner
1356: Notes:
1357: This function is similar to VecGetArrayRead() which maps the local
1358: portion into a raw pointer. VecGetLocalVectorRead() is usually
1359: almost as efficient as VecGetArrayRead() but in certain circumstances
1360: VecGetLocalVectorRead() can be much more efficient than
1361: VecGetArrayRead(). This is because the construction of a contiguous
1362: array representing the vector data required by VecGetArrayRead() can
1363: be an expensive operation for certain vector types. For example, for
1364: GPU vectors VecGetArrayRead() requires that the data between device
1365: and host is synchronized.
1367: Unlike VecGetLocalVector(), this routine is not collective and
1368: preserves cached information.
1370: .seealso: VecRestoreLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1371: @*/
1372: PetscErrorCode VecGetLocalVectorRead(Vec v,Vec w)
1373: {
1375: PetscScalar *a;
1380: VecCheckSameLocalSize(v,1,w,2);
1381: if (v->ops->getlocalvectorread) {
1382: (*v->ops->getlocalvectorread)(v,w);
1383: } else {
1384: VecGetArrayRead(v,(const PetscScalar**)&a);
1385: VecPlaceArray(w,a);
1386: }
1387: return(0);
1388: }
1390: /*@
1391: VecRestoreLocalVectorRead - Unmaps the local portion of a vector
1392: previously mapped into a vector using VecGetLocalVectorRead().
1394: Not collective.
1396: Input parameter:
1397: + v - The local portion of this vector was previously mapped into w using VecGetLocalVectorRead().
1398: - w - The vector into which the local portion of v was mapped.
1400: Level: beginner
1402: .seealso: VecGetLocalVectorRead(), VecGetLocalVector(), VecGetArrayRead(), VecGetArray()
1403: @*/
1404: PetscErrorCode VecRestoreLocalVectorRead(Vec v,Vec w)
1405: {
1407: PetscScalar *a;
1412: if (v->ops->restorelocalvectorread) {
1413: (*v->ops->restorelocalvectorread)(v,w);
1414: } else {
1415: VecGetArrayRead(w,(const PetscScalar**)&a);
1416: VecRestoreArrayRead(v,(const PetscScalar**)&a);
1417: VecResetArray(w);
1418: }
1419: return(0);
1420: }
1422: /*@
1423: VecGetLocalVector - Maps the local portion of a vector into a
1424: vector.
1426: Collective on v, not collective on w.
1428: Input parameter:
1429: . v - The vector for which the local vector is desired.
1431: Output parameter:
1432: . w - Upon exit this contains the local vector.
1434: Level: beginner
1436: Notes:
1437: This function is similar to VecGetArray() which maps the local
1438: portion into a raw pointer. VecGetLocalVector() is usually about as
1439: efficient as VecGetArray() but in certain circumstances
1440: VecGetLocalVector() can be much more efficient than VecGetArray().
1441: This is because the construction of a contiguous array representing
1442: the vector data required by VecGetArray() can be an expensive
1443: operation for certain vector types. For example, for GPU vectors
1444: VecGetArray() requires that the data between device and host is
1445: synchronized.
1447: .seealso: VecRestoreLocalVector(), VecGetLocalVectorRead(), VecGetArrayRead(), VecGetArray()
1448: @*/
1449: PetscErrorCode VecGetLocalVector(Vec v,Vec w)
1450: {
1452: PetscScalar *a;
1457: VecCheckSameLocalSize(v,1,w,2);
1458: if (v->ops->getlocalvector) {
1459: (*v->ops->getlocalvector)(v,w);
1460: } else {
1461: VecGetArray(v,&a);
1462: VecPlaceArray(w,a);
1463: }
1464: return(0);
1465: }
1467: /*@
1468: VecRestoreLocalVector - Unmaps the local portion of a vector
1469: previously mapped into a vector using VecGetLocalVector().
1471: Logically collective.
1473: Input parameter:
1474: + v - The local portion of this vector was previously mapped into w using VecGetLocalVector().
1475: - w - The vector into which the local portion of v was mapped.
1477: Level: beginner
1479: .seealso: VecGetLocalVector(), VecGetLocalVectorRead(), VecRestoreLocalVectorRead(), LocalVectorRead(), VecGetArrayRead(), VecGetArray()
1480: @*/
1481: PetscErrorCode VecRestoreLocalVector(Vec v,Vec w)
1482: {
1484: PetscScalar *a;
1489: if (v->ops->restorelocalvector) {
1490: (*v->ops->restorelocalvector)(v,w);
1491: } else {
1492: VecGetArray(w,&a);
1493: VecRestoreArray(v,&a);
1494: VecResetArray(w);
1495: }
1496: return(0);
1497: }
1499: /*@C
1500: VecGetArray - Returns a pointer to a contiguous array that contains this
1501: processor's portion of the vector data. For the standard PETSc
1502: vectors, VecGetArray() returns a pointer to the local data array and
1503: does not use any copies. If the underlying vector data is not stored
1504: in a contiguous array this routine will copy the data to a contiguous
1505: array and return a pointer to that. You MUST call VecRestoreArray()
1506: when you no longer need access to the array.
1508: Logically Collective on Vec
1510: Input Parameter:
1511: . x - the vector
1513: Output Parameter:
1514: . a - location to put pointer to the array
1516: Fortran Note:
1517: This routine is used differently from Fortran 77
1518: $ Vec x
1519: $ PetscScalar x_array(1)
1520: $ PetscOffset i_x
1521: $ PetscErrorCode ierr
1522: $ call VecGetArray(x,x_array,i_x,ierr)
1523: $
1524: $ Access first local entry in vector with
1525: $ value = x_array(i_x + 1)
1526: $
1527: $ ...... other code
1528: $ call VecRestoreArray(x,x_array,i_x,ierr)
1529: For Fortran 90 see VecGetArrayF90()
1531: See the Fortran chapter of the users manual and
1532: petsc/src/snes/examples/tutorials/ex5f.F for details.
1534: Level: beginner
1536: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1537: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1538: @*/
1539: PetscErrorCode VecGetArray(Vec x,PetscScalar **a)
1540: {
1542: #if defined(PETSC_HAVE_VIENNACL)
1543: PetscBool is_viennacltype = PETSC_FALSE;
1544: #endif
1548: VecSetErrorIfLocked(x,1);
1549: if (x->petscnative) {
1550: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1551: if (x->valid_GPU_array == PETSC_OFFLOAD_GPU) {
1552: #if defined(PETSC_HAVE_VIENNACL)
1553: PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1554: if (is_viennacltype) {
1555: VecViennaCLCopyFromGPU(x);
1556: } else
1557: #endif
1558: {
1559: #if defined(PETSC_HAVE_CUDA)
1560: VecCUDACopyFromGPU(x);
1561: #endif
1562: }
1563: } else if (x->valid_GPU_array == PETSC_OFFLOAD_UNALLOCATED) {
1564: #if defined(PETSC_HAVE_VIENNACL)
1565: PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1566: if (is_viennacltype) {
1567: VecViennaCLAllocateCheckHost(x);
1568: } else
1569: #endif
1570: {
1571: #if defined(PETSC_HAVE_CUDA)
1572: VecCUDAAllocateCheckHost(x);
1573: #endif
1574: }
1575: }
1576: #endif
1577: *a = *((PetscScalar**)x->data);
1578: } else {
1579: if (x->ops->getarray) {
1580: (*x->ops->getarray)(x,a);
1581: } else SETERRQ1(PetscObjectComm((PetscObject)x),PETSC_ERR_SUP,"Cannot get array for vector type \"%s\"",((PetscObject)x)->type_name);
1582: }
1583: return(0);
1584: }
1586: /*@C
1587: VecGetArrayInPlace - Like VecGetArray(), but if this is a CUDA vector and it is currently offloaded to GPU,
1588: the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1589: vector data. Otherwise, it functions as VecGetArray().
1591: Logically Collective on Vec
1593: Input Parameter:
1594: . x - the vector
1596: Output Parameter:
1597: . a - location to put pointer to the array
1599: Level: beginner
1601: .seealso: VecRestoreArrayInPlace(), VecRestoreArrayInPlace(), VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(),
1602: VecPlaceArray(), VecGetArray2d(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite(), VecRestoreArrayWrite()
1603: @*/
1604: PetscErrorCode VecGetArrayInPlace(Vec x,PetscScalar **a)
1605: {
1610: VecSetErrorIfLocked(x,1);
1612: #if defined(PETSC_HAVE_CUDA)
1613: if (x->petscnative && x->valid_GPU_array == PETSC_OFFLOAD_GPU) {
1614: PetscBool is_cudatype = PETSC_FALSE;
1615: PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1616: if (is_cudatype) {
1617: VecCUDAGetArray(x,a);
1618: return(0);
1619: }
1620: }
1621: #endif
1622: VecGetArray(x,a);
1623: return(0);
1624: }
1626: /*@C
1627: VecGetArrayWrite - Returns a pointer to a contiguous array that WILL contains this
1628: processor's portion of the vector data. The values in this array are NOT valid, the routine calling this
1629: routine is responsible for putting values into the array; any values it does not set will be invalid
1631: Logically Collective on Vec
1633: Input Parameter:
1634: . x - the vector
1636: Output Parameter:
1637: . a - location to put pointer to the array
1639: Level: intermediate
1641: This is for vectors associate with GPUs, the vector is not copied up before giving access. If you need correct
1642: values in the array use VecGetArray()
1644: Concepts: vector^accessing local values
1646: .seealso: VecRestoreArray(), VecGetArrayRead(), VecGetArrays(), VecGetArrayF90(), VecGetArrayReadF90(), VecPlaceArray(), VecGetArray2d(),
1647: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArray(), VecRestoreArrayWrite()
1648: @*/
1649: PetscErrorCode VecGetArrayWrite(Vec x,PetscScalar **a)
1650: {
1655: VecSetErrorIfLocked(x,1);
1656: if (!x->ops->getarraywrite) {
1657: VecGetArray(x,a);
1658: } else {
1659: (*x->ops->getarraywrite)(x,a);
1660: }
1661: return(0);
1662: }
1664: /*@C
1665: VecGetArrayRead - Get read-only pointer to contiguous array containing this processor's portion of the vector data.
1667: Not Collective
1669: Input Parameters:
1670: . x - the vector
1672: Output Parameter:
1673: . a - the array
1675: Level: beginner
1677: Notes:
1678: The array must be returned using a matching call to VecRestoreArrayRead().
1680: Unlike VecGetArray(), this routine is not collective and preserves cached information like vector norms.
1682: Standard PETSc vectors use contiguous storage so that this routine does not perform a copy. Other vector
1683: implementations may require a copy, but must such implementations should cache the contiguous representation so that
1684: only one copy is performed when this routine is called multiple times in sequence.
1686: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1687: @*/
1688: PetscErrorCode VecGetArrayRead(Vec x,const PetscScalar **a)
1689: {
1691: #if defined(PETSC_HAVE_VIENNACL)
1692: PetscBool is_viennacltype = PETSC_FALSE;
1693: #endif
1697: if (x->petscnative) {
1698: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1699: if (x->valid_GPU_array == PETSC_OFFLOAD_GPU) {
1700: #if defined(PETSC_HAVE_VIENNACL)
1701: PetscObjectTypeCompareAny((PetscObject)x,&is_viennacltype,VECSEQVIENNACL,VECMPIVIENNACL,VECVIENNACL,"");
1702: if (is_viennacltype) {
1703: VecViennaCLCopyFromGPU(x);
1704: } else
1705: #endif
1706: {
1707: #if defined(PETSC_HAVE_CUDA)
1708: VecCUDACopyFromGPU(x);
1709: #endif
1710: }
1711: }
1712: #endif
1713: *a = *((PetscScalar **)x->data);
1714: } else if (x->ops->getarrayread) {
1715: (*x->ops->getarrayread)(x,a);
1716: } else {
1717: (*x->ops->getarray)(x,(PetscScalar**)a);
1718: }
1719: return(0);
1720: }
1722: /*@C
1723: VecGetArrayReadInPlace - Like VecGetArrayRead(), but if this is a CUDA vector and it is currently offloaded to GPU,
1724: the returned pointer will be a GPU pointer to the GPU memory that contains this processor's portion of the
1725: vector data. Otherwise, it functions as VecGetArrayRead().
1727: Not Collective
1729: Input Parameters:
1730: . x - the vector
1732: Output Parameter:
1733: . a - the array
1735: Level: beginner
1737: Notes:
1738: The array must be returned using a matching call to VecRestoreArrayReadInPlace().
1741: .seealso: VecRestoreArrayReadInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayInPlace()
1742: @*/
1743: PetscErrorCode VecGetArrayReadInPlace(Vec x,const PetscScalar **a)
1744: {
1749: #if defined(PETSC_HAVE_CUDA)
1750: if (x->petscnative && x->valid_GPU_array == PETSC_OFFLOAD_GPU) {
1751: PetscBool is_cudatype = PETSC_FALSE;
1752: PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1753: if (is_cudatype) {
1754: VecCUDAGetArrayRead(x,a);
1755: return(0);
1756: }
1757: }
1758: #endif
1759: VecGetArrayRead(x,a);
1760: return(0);
1761: }
1763: /*@C
1764: VecGetArrays - Returns a pointer to the arrays in a set of vectors
1765: that were created by a call to VecDuplicateVecs(). You MUST call
1766: VecRestoreArrays() when you no longer need access to the array.
1768: Logically Collective on Vec
1770: Input Parameter:
1771: + x - the vectors
1772: - n - the number of vectors
1774: Output Parameter:
1775: . a - location to put pointer to the array
1777: Fortran Note:
1778: This routine is not supported in Fortran.
1780: Level: intermediate
1782: .seealso: VecGetArray(), VecRestoreArrays()
1783: @*/
1784: PetscErrorCode VecGetArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1785: {
1787: PetscInt i;
1788: PetscScalar **q;
1794: if (n <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must get at least one array n = %D",n);
1795: PetscMalloc1(n,&q);
1796: for (i=0; i<n; ++i) {
1797: VecGetArray(x[i],&q[i]);
1798: }
1799: *a = q;
1800: return(0);
1801: }
1803: /*@C
1804: VecRestoreArrays - Restores a group of vectors after VecGetArrays()
1805: has been called.
1807: Logically Collective on Vec
1809: Input Parameters:
1810: + x - the vector
1811: . n - the number of vectors
1812: - a - location of pointer to arrays obtained from VecGetArrays()
1814: Notes:
1815: For regular PETSc vectors this routine does not involve any copies. For
1816: any special vectors that do not store local vector data in a contiguous
1817: array, this routine will copy the data back into the underlying
1818: vector data structure from the arrays obtained with VecGetArrays().
1820: Fortran Note:
1821: This routine is not supported in Fortran.
1823: Level: intermediate
1825: .seealso: VecGetArrays(), VecRestoreArray()
1826: @*/
1827: PetscErrorCode VecRestoreArrays(const Vec x[],PetscInt n,PetscScalar **a[])
1828: {
1830: PetscInt i;
1831: PetscScalar **q = *a;
1838: for (i=0; i<n; ++i) {
1839: VecRestoreArray(x[i],&q[i]);
1840: }
1841: PetscFree(q);
1842: return(0);
1843: }
1845: /*@C
1846: VecRestoreArray - Restores a vector after VecGetArray() has been called.
1848: Logically Collective on Vec
1850: Input Parameters:
1851: + x - the vector
1852: - a - location of pointer to array obtained from VecGetArray()
1854: Level: beginner
1856: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1857: VecGetArrayPair(), VecRestoreArrayPair()
1858: @*/
1859: PetscErrorCode VecRestoreArray(Vec x,PetscScalar **a)
1860: {
1865: if (x->petscnative) {
1866: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1867: x->valid_GPU_array = PETSC_OFFLOAD_CPU;
1868: #endif
1869: } else {
1870: (*x->ops->restorearray)(x,a);
1871: }
1872: if (a) *a = NULL;
1873: PetscObjectStateIncrease((PetscObject)x);
1874: return(0);
1875: }
1877: /*@C
1878: VecRestoreArrayInPlace - Restores a vector after VecGetArrayInPlace() has been called.
1880: Logically Collective on Vec
1882: Input Parameters:
1883: + x - the vector
1884: - a - location of pointer to array obtained from VecGetArrayInPlace()
1886: Level: beginner
1888: .seealso: VecGetArrayInPlace(), VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(),
1889: VecPlaceArray(), VecRestoreArray2d(), VecGetArrayPair(), VecRestoreArrayPair()
1890: @*/
1891: PetscErrorCode VecRestoreArrayInPlace(Vec x,PetscScalar **a)
1892: {
1897: #if defined(PETSC_HAVE_CUDA)
1898: if (x->petscnative && x->valid_GPU_array == PETSC_OFFLOAD_GPU) {
1899: PetscBool is_cudatype = PETSC_FALSE;
1900: PetscObjectTypeCompareAny((PetscObject)x,&is_cudatype,VECSEQCUDA,VECMPICUDA,VECCUDA,"");
1901: if (is_cudatype) {
1902: VecCUDARestoreArray(x,a);
1903: return(0);
1904: }
1905: }
1906: #endif
1907: VecRestoreArray(x,a);
1908: return(0);
1909: }
1912: /*@C
1913: VecRestoreArrayWrite - Restores a vector after VecGetArrayWrite() has been called.
1915: Logically Collective on Vec
1917: Input Parameters:
1918: + x - the vector
1919: - a - location of pointer to array obtained from VecGetArray()
1921: Level: beginner
1923: .seealso: VecGetArray(), VecRestoreArrayRead(), VecRestoreArrays(), VecRestoreArrayF90(), VecRestoreArrayReadF90(), VecPlaceArray(), VecRestoreArray2d(),
1924: VecGetArrayPair(), VecRestoreArrayPair(), VecGetArrayWrite()
1925: @*/
1926: PetscErrorCode VecRestoreArrayWrite(Vec x,PetscScalar **a)
1927: {
1932: if (x->petscnative) {
1933: #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA)
1934: x->valid_GPU_array = PETSC_OFFLOAD_CPU;
1935: #endif
1936: } else {
1937: if (x->ops->restorearraywrite) {
1938: (*x->ops->restorearraywrite)(x,a);
1939: } else {
1940: (*x->ops->restorearray)(x,a);
1941: }
1942: }
1943: if (a) *a = NULL;
1944: PetscObjectStateIncrease((PetscObject)x);
1945: return(0);
1946: }
1948: /*@C
1949: VecRestoreArrayRead - Restore array obtained with VecGetArrayRead()
1951: Not Collective
1953: Input Parameters:
1954: + vec - the vector
1955: - array - the array
1957: Level: beginner
1959: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1960: @*/
1961: PetscErrorCode VecRestoreArrayRead(Vec x,const PetscScalar **a)
1962: {
1967: if (x->petscnative) {
1968: /* nothing */
1969: } else if (x->ops->restorearrayread) {
1970: (*x->ops->restorearrayread)(x,a);
1971: } else {
1972: (*x->ops->restorearray)(x,(PetscScalar**)a);
1973: }
1974: if (a) *a = NULL;
1975: return(0);
1976: }
1978: /*@C
1979: VecRestoreArrayReadInPlace - Restore array obtained with VecGetArrayReadInPlace()
1981: Not Collective
1983: Input Parameters:
1984: + vec - the vector
1985: - array - the array
1987: Level: beginner
1989: .seealso: VecGetArrayReadInPlace(), VecRestoreArrayInPlace(), VecGetArray(), VecRestoreArray(), VecGetArrayPair(), VecRestoreArrayPair()
1990: @*/
1991: PetscErrorCode VecRestoreArrayReadInPlace(Vec x,const PetscScalar **a)
1992: {
1996: VecRestoreArrayRead(x,a);
1997: return(0);
1998: }
2000: /*@
2001: VecPlaceArray - Allows one to replace the array in a vector with an
2002: array provided by the user. This is useful to avoid copying an array
2003: into a vector.
2005: Not Collective
2007: Input Parameters:
2008: + vec - the vector
2009: - array - the array
2011: Notes:
2012: You can return to the original array with a call to VecResetArray()
2014: Level: developer
2016: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray()
2018: @*/
2019: PetscErrorCode VecPlaceArray(Vec vec,const PetscScalar array[])
2020: {
2027: if (vec->ops->placearray) {
2028: (*vec->ops->placearray)(vec,array);
2029: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot place array in this type of vector");
2030: PetscObjectStateIncrease((PetscObject)vec);
2031: return(0);
2032: }
2034: /*@C
2035: VecReplaceArray - Allows one to replace the array in a vector with an
2036: array provided by the user. This is useful to avoid copying an array
2037: into a vector.
2039: Not Collective
2041: Input Parameters:
2042: + vec - the vector
2043: - array - the array
2045: Notes:
2046: This permanently replaces the array and frees the memory associated
2047: with the old array.
2049: The memory passed in MUST be obtained with PetscMalloc() and CANNOT be
2050: freed by the user. It will be freed when the vector is destroy.
2052: Not supported from Fortran
2054: Level: developer
2056: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray()
2058: @*/
2059: PetscErrorCode VecReplaceArray(Vec vec,const PetscScalar array[])
2060: {
2066: if (vec->ops->replacearray) {
2067: (*vec->ops->replacearray)(vec,array);
2068: } else SETERRQ(PetscObjectComm((PetscObject)vec),PETSC_ERR_SUP,"Cannot replace array in this type of vector");
2069: PetscObjectStateIncrease((PetscObject)vec);
2070: return(0);
2071: }
2074: /*@C
2075: VecCUDAGetArray - Provides access to the CUDA buffer inside a vector.
2077: This function has semantics similar to VecGetArray(): the pointer
2078: returned by this function points to a consistent view of the vector
2079: data. This may involve a copy operation of data from the host to the
2080: device if the data on the device is out of date. If the device
2081: memory hasn't been allocated previously it will be allocated as part
2082: of this function call. VecCUDAGetArray() assumes that
2083: the user will modify the vector data. This is similar to
2084: intent(inout) in fortran.
2086: The CUDA device pointer has to be released by calling
2087: VecCUDARestoreArray(). Upon restoring the vector data
2088: the data on the host will be marked as out of date. A subsequent
2089: access of the host data will thus incur a data transfer from the
2090: device to the host.
2093: Input Parameter:
2094: . v - the vector
2096: Output Parameter:
2097: . a - the CUDA device pointer
2099: Fortran note:
2100: This function is not currently available from Fortran.
2102: Level: intermediate
2104: .seealso: VecCUDARestoreArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2105: @*/
2106: PETSC_EXTERN PetscErrorCode VecCUDAGetArray(Vec v, PetscScalar **a)
2107: {
2108: #if defined(PETSC_HAVE_CUDA)
2110: #endif
2114: #if defined(PETSC_HAVE_CUDA)
2115: *a = 0;
2116: VecCUDACopyToGPU(v);
2117: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2118: #endif
2119: return(0);
2120: }
2122: /*@C
2123: VecCUDARestoreArray - Restore a CUDA device pointer previously acquired with VecCUDAGetArray().
2125: This marks the host data as out of date. Subsequent access to the
2126: vector data on the host side with for instance VecGetArray() incurs a
2127: data transfer.
2129: Input Parameter:
2130: + v - the vector
2131: - a - the CUDA device pointer. This pointer is invalid after
2132: VecCUDARestoreArray() returns.
2134: Fortran note:
2135: This function is not currently available from Fortran.
2137: Level: intermediate
2139: .seealso: VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2140: @*/
2141: PETSC_EXTERN PetscErrorCode VecCUDARestoreArray(Vec v, PetscScalar **a)
2142: {
2147: #if defined(PETSC_HAVE_CUDA)
2148: v->valid_GPU_array = PETSC_OFFLOAD_GPU;
2149: #endif
2151: PetscObjectStateIncrease((PetscObject)v);
2152: return(0);
2153: }
2155: /*@C
2156: VecCUDAGetArrayRead - Provides read access to the CUDA buffer inside a vector.
2158: This function is analogous to VecGetArrayRead(): The pointer
2159: returned by this function points to a consistent view of the vector
2160: data. This may involve a copy operation of data from the host to the
2161: device if the data on the device is out of date. If the device
2162: memory hasn't been allocated previously it will be allocated as part
2163: of this function call. VecCUDAGetArrayRead() assumes that the
2164: user will not modify the vector data. This is analgogous to
2165: intent(in) in Fortran.
2167: The CUDA device pointer has to be released by calling
2168: VecCUDARestoreArrayRead(). If the data on the host side was
2169: previously up to date it will remain so, i.e. data on both the device
2170: and the host is up to date. Accessing data on the host side does not
2171: incur a device to host data transfer.
2173: Input Parameter:
2174: . v - the vector
2176: Output Parameter:
2177: . a - the CUDA pointer.
2179: Fortran note:
2180: This function is not currently available from Fortran.
2182: Level: intermediate
2184: .seealso: VecCUDARestoreArrayRead(), VecCUDAGetArray(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2185: @*/
2186: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayRead(Vec v, const PetscScalar **a)
2187: {
2188: #if defined(PETSC_HAVE_CUDA)
2190: #endif
2194: #if defined(PETSC_HAVE_CUDA)
2195: *a = 0;
2196: VecCUDACopyToGPU(v);
2197: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2198: #endif
2199: return(0);
2200: }
2202: /*@C
2203: VecCUDARestoreArrayRead - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayRead().
2205: If the data on the host side was previously up to date it will remain
2206: so, i.e. data on both the device and the host is up to date.
2207: Accessing data on the host side e.g. with VecGetArray() does not
2208: incur a device to host data transfer.
2210: Input Parameter:
2211: + v - the vector
2212: - a - the CUDA device pointer. This pointer is invalid after
2213: VecCUDARestoreArrayRead() returns.
2215: Fortran note:
2216: This function is not currently available from Fortran.
2218: Level: intermediate
2220: .seealso: VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2221: @*/
2222: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayRead(Vec v, const PetscScalar **a)
2223: {
2226: *a = NULL;
2227: return(0);
2228: }
2230: /*@C
2231: VecCUDAGetArrayWrite - Provides write access to the CUDA buffer inside a vector.
2233: The data pointed to by the device pointer is uninitialized. The user
2234: may not read from this data. Furthermore, the entire array needs to
2235: be filled by the user to obtain well-defined behaviour. The device
2236: memory will be allocated by this function if it hasn't been allocated
2237: previously. This is analogous to intent(out) in Fortran.
2239: The device pointer needs to be released with
2240: VecCUDARestoreArrayWrite(). When the pointer is released the
2241: host data of the vector is marked as out of data. Subsequent access
2242: of the host data with e.g. VecGetArray() incurs a device to host data
2243: transfer.
2246: Input Parameter:
2247: . v - the vector
2249: Output Parameter:
2250: . a - the CUDA pointer
2252: Fortran note:
2253: This function is not currently available from Fortran.
2255: Level: advanced
2257: .seealso: VecCUDARestoreArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecGetArrayRead()
2258: @*/
2259: PETSC_EXTERN PetscErrorCode VecCUDAGetArrayWrite(Vec v, PetscScalar **a)
2260: {
2261: #if defined(PETSC_HAVE_CUDA)
2263: #endif
2267: #if defined(PETSC_HAVE_CUDA)
2268: *a = 0;
2269: VecCUDAAllocateCheck(v);
2270: *a = ((Vec_CUDA*)v->spptr)->GPUarray;
2271: #endif
2272: return(0);
2273: }
2275: /*@C
2276: VecCUDARestoreArrayWrite - Restore a CUDA device pointer previously acquired with VecCUDAGetArrayWrite().
2278: Data on the host will be marked as out of date. Subsequent access of
2279: the data on the host side e.g. with VecGetArray() will incur a device
2280: to host data transfer.
2282: Input Parameter:
2283: + v - the vector
2284: - a - the CUDA device pointer. This pointer is invalid after
2285: VecCUDARestoreArrayWrite() returns.
2287: Fortran note:
2288: This function is not currently available from Fortran.
2290: Level: intermediate
2292: .seealso: VecCUDAGetArrayWrite(), VecCUDAGetArray(), VecCUDAGetArrayRead(), VecCUDAGetArrayWrite(), VecGetArray(), VecRestoreArray(), VecGetArrayRead()
2293: @*/
2294: PETSC_EXTERN PetscErrorCode VecCUDARestoreArrayWrite(Vec v, PetscScalar **a)
2295: {
2300: #if defined(PETSC_HAVE_CUDA)
2301: v->valid_GPU_array = PETSC_OFFLOAD_GPU;
2302: #endif
2304: PetscObjectStateIncrease((PetscObject)v);
2305: return(0);
2306: }
2308: /*@C
2309: VecCUDAPlaceArray - Allows one to replace the GPU array in a vector with a
2310: GPU array provided by the user. This is useful to avoid copying an
2311: array into a vector.
2313: Not Collective
2315: Input Parameters:
2316: + vec - the vector
2317: - array - the GPU array
2319: Notes:
2320: You can return to the original GPU array with a call to VecCUDAResetArray()
2321: It is not possible to use VecCUDAPlaceArray() and VecPlaceArray() at the
2322: same time on the same vector.
2324: Level: developer
2326: .seealso: VecPlaceArray(), VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAReplaceArray()
2328: @*/
2329: PetscErrorCode VecCUDAPlaceArray(Vec vin,PetscScalar *a)
2330: {
2335: #if defined(PETSC_HAVE_CUDA)
2336: VecCUDACopyToGPU(vin);
2337: 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()");
2338: ((Vec_Seq*)vin->data)->unplacedarray = (PetscScalar *) ((Vec_CUDA*)vin->spptr)->GPUarray; /* save previous GPU array so reset can bring it back */
2339: ((Vec_CUDA*)vin->spptr)->GPUarray = a;
2340: vin->valid_GPU_array = PETSC_OFFLOAD_GPU;
2341: #endif
2342: PetscObjectStateIncrease((PetscObject)vin);
2343: return(0);
2344: }
2346: /*@C
2347: VecCUDAReplaceArray - Allows one to replace the GPU array in a vector
2348: with a GPU array provided by the user. This is useful to avoid copying
2349: a GPU array into a vector.
2351: Not Collective
2353: Input Parameters:
2354: + vec - the vector
2355: - array - the GPU array
2357: Notes:
2358: This permanently replaces the GPU array and frees the memory associated
2359: with the old GPU array.
2361: The memory passed in CANNOT be freed by the user. It will be freed
2362: when the vector is destroyed.
2364: Not supported from Fortran
2366: Level: developer
2368: .seealso: VecGetArray(), VecRestoreArray(), VecPlaceArray(), VecResetArray(), VecCUDAResetArray(), VecCUDAPlaceArray(), VecReplaceArray()
2370: @*/
2371: PetscErrorCode VecCUDAReplaceArray(Vec vin,PetscScalar *a)
2372: {
2373: #if defined(PETSC_HAVE_CUDA)
2374: cudaError_t err;
2375: #endif
2380: #if defined(PETSC_HAVE_CUDA)
2381: err = cudaFree(((Vec_CUDA*)vin->spptr)->GPUarray);CHKERRCUDA(err);
2382: ((Vec_CUDA*)vin->spptr)->GPUarray = a;
2383: vin->valid_GPU_array = PETSC_OFFLOAD_GPU;
2384: #endif
2385: PetscObjectStateIncrease((PetscObject)vin);
2386: return(0);
2387: }
2389: /*@C
2390: VecCUDAResetArray - Resets a vector to use its default memory. Call this
2391: after the use of VecCUDAPlaceArray().
2393: Not Collective
2395: Input Parameters:
2396: . vec - the vector
2398: Level: developer
2400: .seealso: VecGetArray(), VecRestoreArray(), VecReplaceArray(), VecPlaceArray(), VecResetArray(), VecCUDAPlaceArray(), VecCUDAReplaceArray()
2402: @*/
2403: PetscErrorCode VecCUDAResetArray(Vec vin)
2404: {
2409: #if defined(PETSC_HAVE_CUDA)
2410: VecCUDACopyToGPU(vin);
2411: ((Vec_CUDA*)vin->spptr)->GPUarray = (PetscScalar *) ((Vec_Seq*)vin->data)->unplacedarray;
2412: ((Vec_Seq*)vin->data)->unplacedarray = 0;
2413: vin->valid_GPU_array = PETSC_OFFLOAD_GPU;
2414: #endif
2415: PetscObjectStateIncrease((PetscObject)vin);
2416: return(0);
2417: }
2422: /*MC
2423: VecDuplicateVecsF90 - Creates several vectors of the same type as an existing vector
2424: and makes them accessible via a Fortran90 pointer.
2426: Synopsis:
2427: VecDuplicateVecsF90(Vec x,PetscInt n,{Vec, pointer :: y(:)},integer ierr)
2429: Collective on Vec
2431: Input Parameters:
2432: + x - a vector to mimic
2433: - n - the number of vectors to obtain
2435: Output Parameters:
2436: + y - Fortran90 pointer to the array of vectors
2437: - ierr - error code
2439: Example of Usage:
2440: .vb
2441: #include <petsc/finclude/petscvec.h>
2442: use petscvec
2444: Vec x
2445: Vec, pointer :: y(:)
2446: ....
2447: call VecDuplicateVecsF90(x,2,y,ierr)
2448: call VecSet(y(2),alpha,ierr)
2449: call VecSet(y(2),alpha,ierr)
2450: ....
2451: call VecDestroyVecsF90(2,y,ierr)
2452: .ve
2454: Notes:
2455: Not yet supported for all F90 compilers
2457: Use VecDestroyVecsF90() to free the space.
2459: Level: beginner
2461: .seealso: VecDestroyVecsF90(), VecDuplicateVecs()
2463: M*/
2465: /*MC
2466: VecRestoreArrayF90 - Restores a vector to a usable state after a call to
2467: VecGetArrayF90().
2469: Synopsis:
2470: VecRestoreArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2472: Logically Collective on Vec
2474: Input Parameters:
2475: + x - vector
2476: - xx_v - the Fortran90 pointer to the array
2478: Output Parameter:
2479: . ierr - error code
2481: Example of Usage:
2482: .vb
2483: #include <petsc/finclude/petscvec.h>
2484: use petscvec
2486: PetscScalar, pointer :: xx_v(:)
2487: ....
2488: call VecGetArrayF90(x,xx_v,ierr)
2489: xx_v(3) = a
2490: call VecRestoreArrayF90(x,xx_v,ierr)
2491: .ve
2493: Level: beginner
2495: .seealso: VecGetArrayF90(), VecGetArray(), VecRestoreArray(), UsingFortran, VecRestoreArrayReadF90()
2497: M*/
2499: /*MC
2500: VecDestroyVecsF90 - Frees a block of vectors obtained with VecDuplicateVecsF90().
2502: Synopsis:
2503: VecDestroyVecsF90(PetscInt n,{Vec, pointer :: x(:)},PetscErrorCode ierr)
2505: Collective on Vec
2507: Input Parameters:
2508: + n - the number of vectors previously obtained
2509: - x - pointer to array of vector pointers
2511: Output Parameter:
2512: . ierr - error code
2514: Notes:
2515: Not yet supported for all F90 compilers
2517: Level: beginner
2519: .seealso: VecDestroyVecs(), VecDuplicateVecsF90()
2521: M*/
2523: /*MC
2524: VecGetArrayF90 - Accesses a vector array from Fortran90. For default PETSc
2525: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2526: this routine is implementation dependent. You MUST call VecRestoreArrayF90()
2527: when you no longer need access to the array.
2529: Synopsis:
2530: VecGetArrayF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2532: Logically Collective on Vec
2534: Input Parameter:
2535: . x - vector
2537: Output Parameters:
2538: + xx_v - the Fortran90 pointer to the array
2539: - ierr - error code
2541: Example of Usage:
2542: .vb
2543: #include <petsc/finclude/petscvec.h>
2544: use petscvec
2546: PetscScalar, pointer :: xx_v(:)
2547: ....
2548: call VecGetArrayF90(x,xx_v,ierr)
2549: xx_v(3) = a
2550: call VecRestoreArrayF90(x,xx_v,ierr)
2551: .ve
2553: If you ONLY intend to read entries from the array and not change any entries you should use VecGetArrayReadF90().
2555: Level: beginner
2557: .seealso: VecRestoreArrayF90(), VecGetArray(), VecRestoreArray(), VecGetArrayReadF90(), UsingFortran
2559: M*/
2561: /*MC
2562: VecGetArrayReadF90 - Accesses a read only array from Fortran90. For default PETSc
2563: vectors, VecGetArrayF90() returns a pointer to the local data array. Otherwise,
2564: this routine is implementation dependent. You MUST call VecRestoreArrayReadF90()
2565: when you no longer need access to the array.
2567: Synopsis:
2568: VecGetArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2570: Logically Collective on Vec
2572: Input Parameter:
2573: . x - vector
2575: Output Parameters:
2576: + xx_v - the Fortran90 pointer to the array
2577: - ierr - error code
2579: Example of Usage:
2580: .vb
2581: #include <petsc/finclude/petscvec.h>
2582: use petscvec
2584: PetscScalar, pointer :: xx_v(:)
2585: ....
2586: call VecGetArrayReadF90(x,xx_v,ierr)
2587: a = xx_v(3)
2588: call VecRestoreArrayReadF90(x,xx_v,ierr)
2589: .ve
2591: If you intend to write entries into the array you must use VecGetArrayF90().
2593: Level: beginner
2595: .seealso: VecRestoreArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(), VecGetArrayF90(), UsingFortran
2597: M*/
2599: /*MC
2600: VecRestoreArrayReadF90 - Restores a readonly vector to a usable state after a call to
2601: VecGetArrayReadF90().
2603: Synopsis:
2604: VecRestoreArrayReadF90(Vec x,{Scalar, pointer :: xx_v(:)},integer ierr)
2606: Logically Collective on Vec
2608: Input Parameters:
2609: + x - vector
2610: - xx_v - the Fortran90 pointer to the array
2612: Output Parameter:
2613: . ierr - error code
2615: Example of Usage:
2616: .vb
2617: #include <petsc/finclude/petscvec.h>
2618: use petscvec
2620: PetscScalar, pointer :: xx_v(:)
2621: ....
2622: call VecGetArrayReadF90(x,xx_v,ierr)
2623: a = xx_v(3)
2624: call VecRestoreArrayReadF90(x,xx_v,ierr)
2625: .ve
2627: Level: beginner
2629: .seealso: VecGetArrayReadF90(), VecGetArray(), VecRestoreArray(), VecGetArrayRead(), VecRestoreArrayRead(),UsingFortran, VecRestoreArrayF90()
2631: M*/
2633: /*@C
2634: VecGetArray2d - Returns a pointer to a 2d contiguous array that contains this
2635: processor's portion of the vector data. You MUST call VecRestoreArray2d()
2636: when you no longer need access to the array.
2638: Logically Collective
2640: Input Parameter:
2641: + x - the vector
2642: . m - first dimension of two dimensional array
2643: . n - second dimension of two dimensional array
2644: . mstart - first index you will use in first coordinate direction (often 0)
2645: - nstart - first index in the second coordinate direction (often 0)
2647: Output Parameter:
2648: . a - location to put pointer to the array
2650: Level: developer
2652: Notes:
2653: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2654: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2655: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2656: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
2658: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2660: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2661: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2662: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2663: @*/
2664: PetscErrorCode VecGetArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2665: {
2667: PetscInt i,N;
2668: PetscScalar *aa;
2674: VecGetLocalSize(x,&N);
2675: 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);
2676: VecGetArray(x,&aa);
2678: PetscMalloc1(m,a);
2679: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2680: *a -= mstart;
2681: return(0);
2682: }
2684: /*@C
2685: VecGetArray2dWrite - Returns a pointer to a 2d contiguous array that will contain this
2686: processor's portion of the vector data. You MUST call VecRestoreArray2dWrite()
2687: when you no longer need access to the array.
2689: Logically Collective
2691: Input Parameter:
2692: + x - the vector
2693: . m - first dimension of two dimensional array
2694: . n - second dimension of two dimensional array
2695: . mstart - first index you will use in first coordinate direction (often 0)
2696: - nstart - first index in the second coordinate direction (often 0)
2698: Output Parameter:
2699: . a - location to put pointer to the array
2701: Level: developer
2703: Notes:
2704: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
2705: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2706: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
2707: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
2709: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2711: Concepts: vector^accessing local values as 2d array
2713: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2714: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2715: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2716: @*/
2717: PetscErrorCode VecGetArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2718: {
2720: PetscInt i,N;
2721: PetscScalar *aa;
2727: VecGetLocalSize(x,&N);
2728: 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);
2729: VecGetArrayWrite(x,&aa);
2731: PetscMalloc1(m,a);
2732: for (i=0; i<m; i++) (*a)[i] = aa + i*n - nstart;
2733: *a -= mstart;
2734: return(0);
2735: }
2737: /*@C
2738: VecRestoreArray2d - Restores a vector after VecGetArray2d() has been called.
2740: Logically Collective
2742: Input Parameters:
2743: + x - the vector
2744: . m - first dimension of two dimensional array
2745: . n - second dimension of the two dimensional array
2746: . mstart - first index you will use in first coordinate direction (often 0)
2747: . nstart - first index in the second coordinate direction (often 0)
2748: - a - location of pointer to array obtained from VecGetArray2d()
2750: Level: developer
2752: Notes:
2753: For regular PETSc vectors this routine does not involve any copies. For
2754: any special vectors that do not store local vector data in a contiguous
2755: array, this routine will copy the data back into the underlying
2756: vector data structure from the array obtained with VecGetArray().
2758: This routine actually zeros out the a pointer.
2760: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2761: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2762: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2763: @*/
2764: PetscErrorCode VecRestoreArray2d(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2765: {
2767: void *dummy;
2773: dummy = (void*)(*a + mstart);
2774: PetscFree(dummy);
2775: VecRestoreArray(x,NULL);
2776: return(0);
2777: }
2779: /*@C
2780: VecRestoreArray2dWrite - Restores a vector after VecGetArray2dWrite() has been called.
2782: Logically Collective
2784: Input Parameters:
2785: + x - the vector
2786: . m - first dimension of two dimensional array
2787: . n - second dimension of the two dimensional array
2788: . mstart - first index you will use in first coordinate direction (often 0)
2789: . nstart - first index in the second coordinate direction (often 0)
2790: - a - location of pointer to array obtained from VecGetArray2d()
2792: Level: developer
2794: Notes:
2795: For regular PETSc vectors this routine does not involve any copies. For
2796: any special vectors that do not store local vector data in a contiguous
2797: array, this routine will copy the data back into the underlying
2798: vector data structure from the array obtained with VecGetArray().
2800: This routine actually zeros out the a pointer.
2802: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2803: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2804: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2805: @*/
2806: PetscErrorCode VecRestoreArray2dWrite(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
2807: {
2809: void *dummy;
2815: dummy = (void*)(*a + mstart);
2816: PetscFree(dummy);
2817: VecRestoreArrayWrite(x,NULL);
2818: return(0);
2819: }
2821: /*@C
2822: VecGetArray1d - Returns a pointer to a 1d contiguous array that contains this
2823: processor's portion of the vector data. You MUST call VecRestoreArray1d()
2824: when you no longer need access to the array.
2826: Logically Collective
2828: Input Parameter:
2829: + x - the vector
2830: . m - first dimension of two dimensional array
2831: - mstart - first index you will use in first coordinate direction (often 0)
2833: Output Parameter:
2834: . a - location to put pointer to the array
2836: Level: developer
2838: Notes:
2839: For a vector obtained from DMCreateLocalVector() mstart are likely
2840: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2841: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
2843: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2845: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2846: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2847: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2848: @*/
2849: PetscErrorCode VecGetArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2850: {
2852: PetscInt N;
2858: VecGetLocalSize(x,&N);
2859: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2860: VecGetArray(x,a);
2861: *a -= mstart;
2862: return(0);
2863: }
2865: /*@C
2866: VecGetArray1dWrite - Returns a pointer to a 1d contiguous array that will contain this
2867: processor's portion of the vector data. You MUST call VecRestoreArray1dWrite()
2868: when you no longer need access to the array.
2870: Logically Collective
2872: Input Parameter:
2873: + x - the vector
2874: . m - first dimension of two dimensional array
2875: - mstart - first index you will use in first coordinate direction (often 0)
2877: Output Parameter:
2878: . a - location to put pointer to the array
2880: Level: developer
2882: Notes:
2883: For a vector obtained from DMCreateLocalVector() mstart are likely
2884: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
2885: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
2887: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
2889: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
2890: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
2891: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
2892: @*/
2893: PetscErrorCode VecGetArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2894: {
2896: PetscInt N;
2902: VecGetLocalSize(x,&N);
2903: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
2904: VecGetArrayWrite(x,a);
2905: *a -= mstart;
2906: return(0);
2907: }
2909: /*@C
2910: VecRestoreArray1d - Restores a vector after VecGetArray1d() has been called.
2912: Logically Collective
2914: Input Parameters:
2915: + x - the vector
2916: . m - first dimension of two dimensional array
2917: . mstart - first index you will use in first coordinate direction (often 0)
2918: - a - location of pointer to array obtained from VecGetArray21()
2920: Level: developer
2922: Notes:
2923: For regular PETSc vectors this routine does not involve any copies. For
2924: any special vectors that do not store local vector data in a contiguous
2925: array, this routine will copy the data back into the underlying
2926: vector data structure from the array obtained with VecGetArray1d().
2928: This routine actually zeros out the a pointer.
2930: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2931: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2932: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2933: @*/
2934: PetscErrorCode VecRestoreArray1d(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2935: {
2941: VecRestoreArray(x,NULL);
2942: return(0);
2943: }
2945: /*@C
2946: VecRestoreArray1dWrite - Restores a vector after VecGetArray1dWrite() has been called.
2948: Logically Collective
2950: Input Parameters:
2951: + x - the vector
2952: . m - first dimension of two dimensional array
2953: . mstart - first index you will use in first coordinate direction (often 0)
2954: - a - location of pointer to array obtained from VecGetArray21()
2956: Level: developer
2958: Notes:
2959: For regular PETSc vectors this routine does not involve any copies. For
2960: any special vectors that do not store local vector data in a contiguous
2961: array, this routine will copy the data back into the underlying
2962: vector data structure from the array obtained with VecGetArray1d().
2964: This routine actually zeros out the a pointer.
2966: Concepts: vector^accessing local values as 1d array
2968: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
2969: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
2970: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
2971: @*/
2972: PetscErrorCode VecRestoreArray1dWrite(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
2973: {
2979: VecRestoreArrayWrite(x,NULL);
2980: return(0);
2981: }
2983: /*@C
2984: VecGetArray3d - Returns a pointer to a 3d contiguous array that contains this
2985: processor's portion of the vector data. You MUST call VecRestoreArray3d()
2986: when you no longer need access to the array.
2988: Logically Collective
2990: Input Parameter:
2991: + x - the vector
2992: . m - first dimension of three dimensional array
2993: . n - second dimension of three dimensional array
2994: . p - third dimension of three dimensional array
2995: . mstart - first index you will use in first coordinate direction (often 0)
2996: . nstart - first index in the second coordinate direction (often 0)
2997: - pstart - first index in the third coordinate direction (often 0)
2999: Output Parameter:
3000: . a - location to put pointer to the array
3002: Level: developer
3004: Notes:
3005: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3006: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3007: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3008: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3010: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3012: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3013: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3014: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3015: @*/
3016: PetscErrorCode VecGetArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3017: {
3019: PetscInt i,N,j;
3020: PetscScalar *aa,**b;
3026: VecGetLocalSize(x,&N);
3027: 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);
3028: VecGetArray(x,&aa);
3030: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3031: b = (PetscScalar**)((*a) + m);
3032: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3033: for (i=0; i<m; i++)
3034: for (j=0; j<n; j++)
3035: b[i*n+j] = aa + i*n*p + j*p - pstart;
3037: *a -= mstart;
3038: return(0);
3039: }
3041: /*@C
3042: VecGetArray3dWrite - Returns a pointer to a 3d contiguous array that will contain this
3043: processor's portion of the vector data. You MUST call VecRestoreArray3dWrite()
3044: when you no longer need access to the array.
3046: Logically Collective
3048: Input Parameter:
3049: + x - the vector
3050: . m - first dimension of three dimensional array
3051: . n - second dimension of three dimensional array
3052: . p - third dimension of three dimensional array
3053: . mstart - first index you will use in first coordinate direction (often 0)
3054: . nstart - first index in the second coordinate direction (often 0)
3055: - pstart - first index in the third coordinate direction (often 0)
3057: Output Parameter:
3058: . a - location to put pointer to the array
3060: Level: developer
3062: Notes:
3063: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3064: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3065: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3066: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3068: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3070: Concepts: vector^accessing local values as 3d array
3072: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3073: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3074: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3075: @*/
3076: PetscErrorCode VecGetArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3077: {
3079: PetscInt i,N,j;
3080: PetscScalar *aa,**b;
3086: VecGetLocalSize(x,&N);
3087: 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);
3088: VecGetArrayWrite(x,&aa);
3090: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3091: b = (PetscScalar**)((*a) + m);
3092: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3093: for (i=0; i<m; i++)
3094: for (j=0; j<n; j++)
3095: b[i*n+j] = aa + i*n*p + j*p - pstart;
3097: *a -= mstart;
3098: return(0);
3099: }
3101: /*@C
3102: VecRestoreArray3d - Restores a vector after VecGetArray3d() has been called.
3104: Logically Collective
3106: Input Parameters:
3107: + x - the vector
3108: . m - first dimension of three dimensional array
3109: . n - second dimension of the three dimensional array
3110: . p - third dimension of the three dimensional array
3111: . mstart - first index you will use in first coordinate direction (often 0)
3112: . nstart - first index in the second coordinate direction (often 0)
3113: . pstart - first index in the third coordinate direction (often 0)
3114: - a - location of pointer to array obtained from VecGetArray3d()
3116: Level: developer
3118: Notes:
3119: For regular PETSc vectors this routine does not involve any copies. For
3120: any special vectors that do not store local vector data in a contiguous
3121: array, this routine will copy the data back into the underlying
3122: vector data structure from the array obtained with VecGetArray().
3124: This routine actually zeros out the a pointer.
3126: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3127: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3128: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3129: @*/
3130: PetscErrorCode VecRestoreArray3d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3131: {
3133: void *dummy;
3139: dummy = (void*)(*a + mstart);
3140: PetscFree(dummy);
3141: VecRestoreArray(x,NULL);
3142: return(0);
3143: }
3145: /*@C
3146: VecRestoreArray3dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3148: Logically Collective
3150: Input Parameters:
3151: + x - the vector
3152: . m - first dimension of three dimensional array
3153: . n - second dimension of the three dimensional array
3154: . p - third dimension of the three dimensional array
3155: . mstart - first index you will use in first coordinate direction (often 0)
3156: . nstart - first index in the second coordinate direction (often 0)
3157: . pstart - first index in the third coordinate direction (often 0)
3158: - a - location of pointer to array obtained from VecGetArray3d()
3160: Level: developer
3162: Notes:
3163: For regular PETSc vectors this routine does not involve any copies. For
3164: any special vectors that do not store local vector data in a contiguous
3165: array, this routine will copy the data back into the underlying
3166: vector data structure from the array obtained with VecGetArray().
3168: This routine actually zeros out the a pointer.
3170: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3171: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3172: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3173: @*/
3174: PetscErrorCode VecRestoreArray3dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3175: {
3177: void *dummy;
3183: dummy = (void*)(*a + mstart);
3184: PetscFree(dummy);
3185: VecRestoreArrayWrite(x,NULL);
3186: return(0);
3187: }
3189: /*@C
3190: VecGetArray4d - Returns a pointer to a 4d contiguous array that contains this
3191: processor's portion of the vector data. You MUST call VecRestoreArray4d()
3192: when you no longer need access to the array.
3194: Logically Collective
3196: Input Parameter:
3197: + x - the vector
3198: . m - first dimension of four dimensional array
3199: . n - second dimension of four dimensional array
3200: . p - third dimension of four dimensional array
3201: . q - fourth dimension of four dimensional array
3202: . mstart - first index you will use in first coordinate direction (often 0)
3203: . nstart - first index in the second coordinate direction (often 0)
3204: . pstart - first index in the third coordinate direction (often 0)
3205: - qstart - first index in the fourth coordinate direction (often 0)
3207: Output Parameter:
3208: . a - location to put pointer to the array
3210: Level: beginner
3212: Notes:
3213: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3214: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3215: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3216: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3218: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3220: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3221: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3222: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3223: @*/
3224: PetscErrorCode VecGetArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3225: {
3227: PetscInt i,N,j,k;
3228: PetscScalar *aa,***b,**c;
3234: VecGetLocalSize(x,&N);
3235: 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);
3236: VecGetArray(x,&aa);
3238: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3239: b = (PetscScalar***)((*a) + m);
3240: c = (PetscScalar**)(b + m*n);
3241: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3242: for (i=0; i<m; i++)
3243: for (j=0; j<n; j++)
3244: b[i*n+j] = c + i*n*p + j*p - pstart;
3245: for (i=0; i<m; i++)
3246: for (j=0; j<n; j++)
3247: for (k=0; k<p; k++)
3248: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3249: *a -= mstart;
3250: return(0);
3251: }
3253: /*@C
3254: VecGetArray4dWrite - Returns a pointer to a 4d contiguous array that will contain this
3255: processor's portion of the vector data. You MUST call VecRestoreArray4dWrite()
3256: when you no longer need access to the array.
3258: Logically Collective
3260: Input Parameter:
3261: + x - the vector
3262: . m - first dimension of four dimensional array
3263: . n - second dimension of four dimensional array
3264: . p - third dimension of four dimensional array
3265: . q - fourth dimension of four dimensional array
3266: . mstart - first index you will use in first coordinate direction (often 0)
3267: . nstart - first index in the second coordinate direction (often 0)
3268: . pstart - first index in the third coordinate direction (often 0)
3269: - qstart - first index in the fourth coordinate direction (often 0)
3271: Output Parameter:
3272: . a - location to put pointer to the array
3274: Level: beginner
3276: Notes:
3277: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3278: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3279: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3280: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3282: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3284: Concepts: vector^accessing local values as 3d array
3286: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3287: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3288: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3289: @*/
3290: PetscErrorCode VecGetArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3291: {
3293: PetscInt i,N,j,k;
3294: PetscScalar *aa,***b,**c;
3300: VecGetLocalSize(x,&N);
3301: 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);
3302: VecGetArrayWrite(x,&aa);
3304: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3305: b = (PetscScalar***)((*a) + m);
3306: c = (PetscScalar**)(b + m*n);
3307: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3308: for (i=0; i<m; i++)
3309: for (j=0; j<n; j++)
3310: b[i*n+j] = c + i*n*p + j*p - pstart;
3311: for (i=0; i<m; i++)
3312: for (j=0; j<n; j++)
3313: for (k=0; k<p; k++)
3314: c[i*n*p+j*p+k] = aa + i*n*p*q + j*p*q + k*q - qstart;
3315: *a -= mstart;
3316: return(0);
3317: }
3319: /*@C
3320: VecRestoreArray4d - Restores a vector after VecGetArray3d() has been called.
3322: Logically Collective
3324: Input Parameters:
3325: + x - the vector
3326: . m - first dimension of four dimensional array
3327: . n - second dimension of the four dimensional array
3328: . p - third dimension of the four dimensional array
3329: . q - fourth dimension of the four dimensional array
3330: . mstart - first index you will use in first coordinate direction (often 0)
3331: . nstart - first index in the second coordinate direction (often 0)
3332: . pstart - first index in the third coordinate direction (often 0)
3333: . qstart - first index in the fourth coordinate direction (often 0)
3334: - a - location of pointer to array obtained from VecGetArray4d()
3336: Level: beginner
3338: Notes:
3339: For regular PETSc vectors this routine does not involve any copies. For
3340: any special vectors that do not store local vector data in a contiguous
3341: array, this routine will copy the data back into the underlying
3342: vector data structure from the array obtained with VecGetArray().
3344: This routine actually zeros out the a pointer.
3346: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3347: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3348: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3349: @*/
3350: PetscErrorCode VecRestoreArray4d(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3351: {
3353: void *dummy;
3359: dummy = (void*)(*a + mstart);
3360: PetscFree(dummy);
3361: VecRestoreArray(x,NULL);
3362: return(0);
3363: }
3365: /*@C
3366: VecRestoreArray4dWrite - Restores a vector after VecGetArray3dWrite() has been called.
3368: Logically Collective
3370: Input Parameters:
3371: + x - the vector
3372: . m - first dimension of four dimensional array
3373: . n - second dimension of the four dimensional array
3374: . p - third dimension of the four dimensional array
3375: . q - fourth dimension of the four dimensional array
3376: . mstart - first index you will use in first coordinate direction (often 0)
3377: . nstart - first index in the second coordinate direction (often 0)
3378: . pstart - first index in the third coordinate direction (often 0)
3379: . qstart - first index in the fourth coordinate direction (often 0)
3380: - a - location of pointer to array obtained from VecGetArray4d()
3382: Level: beginner
3384: Notes:
3385: For regular PETSc vectors this routine does not involve any copies. For
3386: any special vectors that do not store local vector data in a contiguous
3387: array, this routine will copy the data back into the underlying
3388: vector data structure from the array obtained with VecGetArray().
3390: This routine actually zeros out the a pointer.
3392: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3393: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3394: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3395: @*/
3396: PetscErrorCode VecRestoreArray4dWrite(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3397: {
3399: void *dummy;
3405: dummy = (void*)(*a + mstart);
3406: PetscFree(dummy);
3407: VecRestoreArrayWrite(x,NULL);
3408: return(0);
3409: }
3411: /*@C
3412: VecGetArray2dRead - Returns a pointer to a 2d contiguous array that contains this
3413: processor's portion of the vector data. You MUST call VecRestoreArray2dRead()
3414: when you no longer need access to the array.
3416: Logically Collective
3418: Input Parameter:
3419: + x - the vector
3420: . m - first dimension of two dimensional array
3421: . n - second dimension of two dimensional array
3422: . mstart - first index you will use in first coordinate direction (often 0)
3423: - nstart - first index in the second coordinate direction (often 0)
3425: Output Parameter:
3426: . a - location to put pointer to the array
3428: Level: developer
3430: Notes:
3431: For a vector obtained from DMCreateLocalVector() mstart and nstart are likely
3432: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3433: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3434: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray2d().
3436: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3438: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3439: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3440: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3441: @*/
3442: PetscErrorCode VecGetArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3443: {
3444: PetscErrorCode ierr;
3445: PetscInt i,N;
3446: const PetscScalar *aa;
3452: VecGetLocalSize(x,&N);
3453: 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);
3454: VecGetArrayRead(x,&aa);
3456: PetscMalloc1(m,a);
3457: for (i=0; i<m; i++) (*a)[i] = (PetscScalar*) aa + i*n - nstart;
3458: *a -= mstart;
3459: return(0);
3460: }
3462: /*@C
3463: VecRestoreArray2dRead - Restores a vector after VecGetArray2dRead() has been called.
3465: Logically Collective
3467: Input Parameters:
3468: + x - the vector
3469: . m - first dimension of two dimensional array
3470: . n - second dimension of the two dimensional array
3471: . mstart - first index you will use in first coordinate direction (often 0)
3472: . nstart - first index in the second coordinate direction (often 0)
3473: - a - location of pointer to array obtained from VecGetArray2d()
3475: Level: developer
3477: Notes:
3478: For regular PETSc vectors this routine does not involve any copies. For
3479: any special vectors that do not store local vector data in a contiguous
3480: array, this routine will copy the data back into the underlying
3481: vector data structure from the array obtained with VecGetArray().
3483: This routine actually zeros out the a pointer.
3485: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3486: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3487: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3488: @*/
3489: PetscErrorCode VecRestoreArray2dRead(Vec x,PetscInt m,PetscInt n,PetscInt mstart,PetscInt nstart,PetscScalar **a[])
3490: {
3492: void *dummy;
3498: dummy = (void*)(*a + mstart);
3499: PetscFree(dummy);
3500: VecRestoreArrayRead(x,NULL);
3501: return(0);
3502: }
3504: /*@C
3505: VecGetArray1dRead - Returns a pointer to a 1d contiguous array that contains this
3506: processor's portion of the vector data. You MUST call VecRestoreArray1dRead()
3507: when you no longer need access to the array.
3509: Logically Collective
3511: Input Parameter:
3512: + x - the vector
3513: . m - first dimension of two dimensional array
3514: - mstart - first index you will use in first coordinate direction (often 0)
3516: Output Parameter:
3517: . a - location to put pointer to the array
3519: Level: developer
3521: Notes:
3522: For a vector obtained from DMCreateLocalVector() mstart are likely
3523: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3524: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners().
3526: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3528: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3529: VecRestoreArray2d(), DMDAVecGetArray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3530: VecGetArray2d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3531: @*/
3532: PetscErrorCode VecGetArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3533: {
3535: PetscInt N;
3541: VecGetLocalSize(x,&N);
3542: if (m != N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Local array size %D does not match 1d array dimensions %D",N,m);
3543: VecGetArrayRead(x,(const PetscScalar**)a);
3544: *a -= mstart;
3545: return(0);
3546: }
3548: /*@C
3549: VecRestoreArray1dRead - Restores a vector after VecGetArray1dRead() has been called.
3551: Logically Collective
3553: Input Parameters:
3554: + x - the vector
3555: . m - first dimension of two dimensional array
3556: . mstart - first index you will use in first coordinate direction (often 0)
3557: - a - location of pointer to array obtained from VecGetArray21()
3559: Level: developer
3561: Notes:
3562: For regular PETSc vectors this routine does not involve any copies. For
3563: any special vectors that do not store local vector data in a contiguous
3564: array, this routine will copy the data back into the underlying
3565: vector data structure from the array obtained with VecGetArray1dRead().
3567: This routine actually zeros out the a pointer.
3569: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3570: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3571: VecGetArray1d(), VecRestoreArray2d(), VecGetArray4d(), VecRestoreArray4d()
3572: @*/
3573: PetscErrorCode VecRestoreArray1dRead(Vec x,PetscInt m,PetscInt mstart,PetscScalar *a[])
3574: {
3580: VecRestoreArrayRead(x,NULL);
3581: return(0);
3582: }
3585: /*@C
3586: VecGetArray3dRead - Returns a pointer to a 3d contiguous array that contains this
3587: processor's portion of the vector data. You MUST call VecRestoreArray3dRead()
3588: when you no longer need access to the array.
3590: Logically Collective
3592: Input Parameter:
3593: + x - the vector
3594: . m - first dimension of three dimensional array
3595: . n - second dimension of three dimensional array
3596: . p - third dimension of three dimensional array
3597: . mstart - first index you will use in first coordinate direction (often 0)
3598: . nstart - first index in the second coordinate direction (often 0)
3599: - pstart - first index in the third coordinate direction (often 0)
3601: Output Parameter:
3602: . a - location to put pointer to the array
3604: Level: developer
3606: Notes:
3607: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3608: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3609: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3610: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3dRead().
3612: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3614: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3615: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3616: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3617: @*/
3618: PetscErrorCode VecGetArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3619: {
3620: PetscErrorCode ierr;
3621: PetscInt i,N,j;
3622: const PetscScalar *aa;
3623: PetscScalar **b;
3629: VecGetLocalSize(x,&N);
3630: 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);
3631: VecGetArrayRead(x,&aa);
3633: PetscMalloc1(m*sizeof(PetscScalar**)+m*n,a);
3634: b = (PetscScalar**)((*a) + m);
3635: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3636: for (i=0; i<m; i++)
3637: for (j=0; j<n; j++)
3638: b[i*n+j] = (PetscScalar *)aa + i*n*p + j*p - pstart;
3640: *a -= mstart;
3641: return(0);
3642: }
3644: /*@C
3645: VecRestoreArray3dRead - Restores a vector after VecGetArray3dRead() has been called.
3647: Logically Collective
3649: Input Parameters:
3650: + x - the vector
3651: . m - first dimension of three dimensional array
3652: . n - second dimension of the three dimensional array
3653: . p - third dimension of the three dimensional array
3654: . mstart - first index you will use in first coordinate direction (often 0)
3655: . nstart - first index in the second coordinate direction (often 0)
3656: . pstart - first index in the third coordinate direction (often 0)
3657: - a - location of pointer to array obtained from VecGetArray3dRead()
3659: Level: developer
3661: Notes:
3662: For regular PETSc vectors this routine does not involve any copies. For
3663: any special vectors that do not store local vector data in a contiguous
3664: array, this routine will copy the data back into the underlying
3665: vector data structure from the array obtained with VecGetArray().
3667: This routine actually zeros out the a pointer.
3669: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3670: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3671: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3672: @*/
3673: PetscErrorCode VecRestoreArray3dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscScalar ***a[])
3674: {
3676: void *dummy;
3682: dummy = (void*)(*a + mstart);
3683: PetscFree(dummy);
3684: VecRestoreArrayRead(x,NULL);
3685: return(0);
3686: }
3688: /*@C
3689: VecGetArray4dRead - Returns a pointer to a 4d contiguous array that contains this
3690: processor's portion of the vector data. You MUST call VecRestoreArray4dRead()
3691: when you no longer need access to the array.
3693: Logically Collective
3695: Input Parameter:
3696: + x - the vector
3697: . m - first dimension of four dimensional array
3698: . n - second dimension of four dimensional array
3699: . p - third dimension of four dimensional array
3700: . q - fourth dimension of four dimensional array
3701: . mstart - first index you will use in first coordinate direction (often 0)
3702: . nstart - first index in the second coordinate direction (often 0)
3703: . pstart - first index in the third coordinate direction (often 0)
3704: - qstart - first index in the fourth coordinate direction (often 0)
3706: Output Parameter:
3707: . a - location to put pointer to the array
3709: Level: beginner
3711: Notes:
3712: For a vector obtained from DMCreateLocalVector() mstart, nstart, and pstart are likely
3713: obtained from the corner indices obtained from DMDAGetGhostCorners() while for
3714: DMCreateGlobalVector() they are the corner indices from DMDAGetCorners(). In both cases
3715: the arguments from DMDAGet[Ghost]Corners() are reversed in the call to VecGetArray3d().
3717: For standard PETSc vectors this is an inexpensive call; it does not copy the vector values.
3719: .seealso: VecGetArray(), VecRestoreArray(), VecGetArrays(), VecGetArrayF90(), VecPlaceArray(),
3720: VecRestoreArray2d(), DMDAVecGetarray(), DMDAVecRestoreArray(), VecGetArray3d(), VecRestoreArray3d(),
3721: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d()
3722: @*/
3723: PetscErrorCode VecGetArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3724: {
3725: PetscErrorCode ierr;
3726: PetscInt i,N,j,k;
3727: const PetscScalar *aa;
3728: PetscScalar ***b,**c;
3734: VecGetLocalSize(x,&N);
3735: 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);
3736: VecGetArrayRead(x,&aa);
3738: PetscMalloc1(m*sizeof(PetscScalar***)+m*n*sizeof(PetscScalar**)+m*n*p,a);
3739: b = (PetscScalar***)((*a) + m);
3740: c = (PetscScalar**)(b + m*n);
3741: for (i=0; i<m; i++) (*a)[i] = b + i*n - nstart;
3742: for (i=0; i<m; i++)
3743: for (j=0; j<n; j++)
3744: b[i*n+j] = c + i*n*p + j*p - pstart;
3745: for (i=0; i<m; i++)
3746: for (j=0; j<n; j++)
3747: for (k=0; k<p; k++)
3748: c[i*n*p+j*p+k] = (PetscScalar*) aa + i*n*p*q + j*p*q + k*q - qstart;
3749: *a -= mstart;
3750: return(0);
3751: }
3753: /*@C
3754: VecRestoreArray4dRead - Restores a vector after VecGetArray3d() has been called.
3756: Logically Collective
3758: Input Parameters:
3759: + x - the vector
3760: . m - first dimension of four dimensional array
3761: . n - second dimension of the four dimensional array
3762: . p - third dimension of the four dimensional array
3763: . q - fourth dimension of the four dimensional array
3764: . mstart - first index you will use in first coordinate direction (often 0)
3765: . nstart - first index in the second coordinate direction (often 0)
3766: . pstart - first index in the third coordinate direction (often 0)
3767: . qstart - first index in the fourth coordinate direction (often 0)
3768: - a - location of pointer to array obtained from VecGetArray4dRead()
3770: Level: beginner
3772: Notes:
3773: For regular PETSc vectors this routine does not involve any copies. For
3774: any special vectors that do not store local vector data in a contiguous
3775: array, this routine will copy the data back into the underlying
3776: vector data structure from the array obtained with VecGetArray().
3778: This routine actually zeros out the a pointer.
3780: .seealso: VecGetArray(), VecRestoreArray(), VecRestoreArrays(), VecRestoreArrayF90(), VecPlaceArray(),
3781: VecGetArray2d(), VecGetArray3d(), VecRestoreArray3d(), DMDAVecGetArray(), DMDAVecRestoreArray()
3782: VecGetArray1d(), VecRestoreArray1d(), VecGetArray4d(), VecRestoreArray4d(), VecGet
3783: @*/
3784: PetscErrorCode VecRestoreArray4dRead(Vec x,PetscInt m,PetscInt n,PetscInt p,PetscInt q,PetscInt mstart,PetscInt nstart,PetscInt pstart,PetscInt qstart,PetscScalar ****a[])
3785: {
3787: void *dummy;
3793: dummy = (void*)(*a + mstart);
3794: PetscFree(dummy);
3795: VecRestoreArrayRead(x,NULL);
3796: return(0);
3797: }
3799: #if defined(PETSC_USE_DEBUG)
3801: /*@
3802: VecLockGet - Gets the current lock status of a vector
3804: Logically Collective on Vec
3806: Input Parameter:
3807: . x - the vector
3809: Output Parameter:
3810: . state - greater than zero indicates the vector is locked for read; less then zero indicates the vector is
3811: locked for write; equal to zero means the vector is unlocked, that is, it is free to read or write.
3813: Level: beginner
3815: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop()
3816: @*/
3817: PetscErrorCode VecLockGet(Vec x,PetscInt *state)
3818: {
3821: *state = x->lock;
3822: return(0);
3823: }
3825: /*@
3826: VecLockReadPush - Pushes a read-only lock on a vector to prevent it from writing
3828: Logically Collective on Vec
3830: Input Parameter:
3831: . x - the vector
3833: Notes:
3834: If this is set then calls to VecGetArray() or VecSetValues() or any other routines that change the vectors values will fail.
3836: The call can be nested, i.e., called multiple times on the same vector, but each VecLockReadPush(x) has to have one matching
3837: VecLockReadPop(x), which removes the latest read-only lock.
3839: Level: beginner
3841: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPop(), VecLockGet()
3842: @*/
3843: PetscErrorCode VecLockReadPush(Vec x)
3844: {
3847: 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");
3848: x->lock++;
3849: return(0);
3850: }
3852: /*@
3853: VecLockReadPop - Pops a read-only lock from a vector
3855: Logically Collective on Vec
3857: Input Parameter:
3858: . x - the vector
3860: Level: beginner
3862: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockGet()
3863: @*/
3864: PetscErrorCode VecLockReadPop(Vec x)
3865: {
3868: x->lock--;
3869: if (x->lock < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Vector has been unlocked from read-only access too many times");
3870: return(0);
3871: }
3873: /*@C
3874: VecLockWriteSet_Private - Lock or unlock a vector for exclusive read/write access
3876: Logically Collective on Vec
3878: Input Parameter:
3879: + x - the vector
3880: - flg - PETSC_TRUE to lock the vector for writing; PETSC_FALSE to unlock it.
3882: Notes:
3883: The function is usefull in split-phase computations, which usually have a begin phase and an end phase.
3884: One can call VecLockWriteSet_Private(x,PETSC_TRUE) in the begin phase to lock a vector for exclusive
3885: access, and call VecLockWriteSet_Private(x,PETSC_FALSE) in the end phase to unlock the vector from exclusive
3886: access. In this way, one is ensured no other operations can access the vector in between. The code may like
3889: VecGetArray(x,&xdata); // begin phase
3890: VecLockWriteSet_Private(v,PETSC_TRUE);
3892: Other operations, which can not acceess x anymore (they can access xdata, of course)
3894: VecRestoreArray(x,&vdata); // end phase
3895: VecLockWriteSet_Private(v,PETSC_FALSE);
3897: The call can not be nested on the same vector, in other words, one can not call VecLockWriteSet_Private(x,PETSC_TRUE)
3898: again before calling VecLockWriteSet_Private(v,PETSC_FALSE).
3900: Level: beginner
3902: .seealso: VecRestoreArray(), VecGetArrayRead(), VecLockReadPush(), VecLockReadPop(), VecLockGet()
3903: @*/
3904: PetscErrorCode VecLockWriteSet_Private(Vec x,PetscBool flg)
3905: {
3908: if (flg) {
3909: 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");
3910: 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");
3911: else x->lock = -1;
3912: } else {
3913: 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");
3914: x->lock = 0;
3915: }
3916: return(0);
3917: }
3919: /*@
3920: VecLockPush - Pushes a read-only lock on a vector to prevent it from writing
3922: Level: deprecated
3924: .seealso: VecLockReadPush()
3925: @*/
3926: PetscErrorCode VecLockPush(Vec x)
3927: {
3930: VecLockReadPush(x);
3931: return(0);
3932: }
3934: /*@
3935: VecLockPop - Pops a read-only lock from a vector
3937: Level: deprecated
3939: .seealso: VecLockReadPop()
3940: @*/
3941: PetscErrorCode VecLockPop(Vec x)
3942: {
3945: VecLockReadPop(x);
3946: return(0);
3947: }
3949: #endif