Actual source code: vecimpl.h
2: /*
3: This private file should not be included in users' code.
4: Defines the fields shared by all vector implementations.
6: It is in the public include directories so that VecGetArray() (which is public) can be defined
7: */
9: #ifndef __VECIMPL_H
12: #include petscvec.h
14: struct _PetscMapOps {
15: PetscErrorCode (*setfromoptions)(PetscMap);
16: PetscErrorCode (*destroy)(PetscMap);
17: };
19: struct _p_PetscMap {
20: PETSCHEADER(struct _PetscMapOps);
21: PetscInt n,N; /* local, global vector size */
22: PetscInt rstart,rend; /* local start, local end + 1 */
23: PetscInt *range; /* the offset of each processor */
24: PetscInt bs; /* number of elements in each block (generally for multi-component problems */
25: };
27: /* ----------------------------------------------------------------------------*/
29: typedef struct _VecOps *VecOps;
30: struct _VecOps {
31: PetscErrorCode (*duplicate)(Vec,Vec*); /* get single vector */
32: PetscErrorCode (*duplicatevecs)(Vec,PetscInt,Vec**); /* get array of vectors */
33: PetscErrorCode (*destroyvecs)(Vec[],PetscInt); /* free array of vectors */
34: PetscErrorCode (*dot)(Vec,Vec,PetscScalar*); /* z = x^H * y */
35: PetscErrorCode (*mdot)(PetscInt,Vec,const Vec[],PetscScalar*); /* z[j] = x dot y[j] */
36: PetscErrorCode (*norm)(Vec,NormType,PetscReal*); /* z = sqrt(x^H * x) */
37: PetscErrorCode (*tdot)(Vec,Vec,PetscScalar*); /* x'*y */
38: PetscErrorCode (*mtdot)(PetscInt,Vec,const Vec[],PetscScalar*);/* z[j] = x dot y[j] */
39: PetscErrorCode (*scale)(Vec,PetscScalar); /* x = alpha * x */
40: PetscErrorCode (*copy)(Vec,Vec); /* y = x */
41: PetscErrorCode (*set)(Vec,PetscScalar); /* y = alpha */
42: PetscErrorCode (*swap)(Vec,Vec); /* exchange x and y */
43: PetscErrorCode (*axpy)(Vec,PetscScalar,Vec); /* y = y + alpha * x */
44: PetscErrorCode (*axpby)(Vec,PetscScalar,PetscScalar,Vec); /* y = y + alpha * x + beta * y*/
45: PetscErrorCode (*maxpy)(Vec,PetscInt,const PetscScalar*,Vec*); /* y = y + alpha[j] x[j] */
46: PetscErrorCode (*aypx)(Vec,PetscScalar,Vec); /* y = x + alpha * y */
47: PetscErrorCode (*waxpy)(Vec,PetscScalar,Vec,Vec); /* w = y + alpha * x */
48: PetscErrorCode (*pointwisemult)(Vec,Vec,Vec); /* w = x .* y */
49: PetscErrorCode (*pointwisedivide)(Vec,Vec,Vec); /* w = x ./ y */
50: PetscErrorCode (*setvalues)(Vec,PetscInt,const PetscInt[],const PetscScalar[],InsertMode);
51: PetscErrorCode (*assemblybegin)(Vec); /* start global assembly */
52: PetscErrorCode (*assemblyend)(Vec); /* end global assembly */
53: PetscErrorCode (*getarray)(Vec,PetscScalar**); /* get data array */
54: PetscErrorCode (*getsize)(Vec,PetscInt*);
55: PetscErrorCode (*getlocalsize)(Vec,PetscInt*);
56: PetscErrorCode (*restorearray)(Vec,PetscScalar**); /* restore data array */
57: PetscErrorCode (*max)(Vec,PetscInt*,PetscReal*); /* z = max(x); idx=index of max(x) */
58: PetscErrorCode (*min)(Vec,PetscInt*,PetscReal*); /* z = min(x); idx=index of min(x) */
59: PetscErrorCode (*setrandom)(Vec,PetscRandom); /* set y[j] = random numbers */
60: PetscErrorCode (*setoption)(Vec,VecOption);
61: PetscErrorCode (*setvaluesblocked)(Vec,PetscInt,const PetscInt[],const PetscScalar[],InsertMode);
62: PetscErrorCode (*destroy)(Vec);
63: PetscErrorCode (*view)(Vec,PetscViewer);
64: PetscErrorCode (*placearray)(Vec,const PetscScalar*); /* place data array */
65: PetscErrorCode (*replacearray)(Vec,const PetscScalar*); /* replace data array */
66: PetscErrorCode (*dot_local)(Vec,Vec,PetscScalar*);
67: PetscErrorCode (*tdot_local)(Vec,Vec,PetscScalar*);
68: PetscErrorCode (*norm_local)(Vec,NormType,PetscReal*);
69: PetscErrorCode (*loadintovector)(PetscViewer,Vec);
70: PetscErrorCode (*reciprocal)(Vec);
71: PetscErrorCode (*viewnative)(Vec,PetscViewer);
72: PetscErrorCode (*conjugate)(Vec);
73: PetscErrorCode (*setlocaltoglobalmapping)(Vec,ISLocalToGlobalMapping);
74: PetscErrorCode (*setvalueslocal)(Vec,PetscInt,const PetscInt *,const PetscScalar *,InsertMode);
75: PetscErrorCode (*resetarray)(Vec); /* vector points to its original array, i.e. undoes any VecPlaceArray() */
76: PetscErrorCode (*setfromoptions)(Vec);
77: PetscErrorCode (*maxpointwisedivide)(Vec,Vec,PetscReal*); /* m = max abs(x ./ y) */
78: PetscErrorCode (*load)(PetscViewer,VecType,Vec*);
79: PetscErrorCode (*pointwisemax)(Vec,Vec,Vec);
80: PetscErrorCode (*pointwisemaxabs)(Vec,Vec,Vec);
81: PetscErrorCode (*pointwisemin)(Vec,Vec,Vec);
82: PetscErrorCode (*getvalues)(Vec,PetscInt,const PetscInt[],PetscScalar[]);
83: };
85: /*
86: The stash is used to temporarily store inserted vec values that
87: belong to another processor. During the assembly phase the stashed
88: values are moved to the correct processor and
89: */
91: typedef struct {
92: PetscInt nmax; /* maximum stash size */
93: PetscInt umax; /* max stash size user wants */
94: PetscInt oldnmax; /* the nmax value used previously */
95: PetscInt n; /* stash size */
96: PetscInt bs; /* block size of the stash */
97: PetscInt reallocs; /* preserve the no of mallocs invoked */
98: PetscInt *idx; /* global row numbers in stash */
99: PetscScalar *array; /* array to hold stashed values */
100: /* The following variables are used for communication */
101: MPI_Comm comm;
102: PetscMPIInt size,rank;
103: PetscMPIInt tag1,tag2;
104: MPI_Request *send_waits; /* array of send requests */
105: MPI_Request *recv_waits; /* array of receive requests */
106: MPI_Status *send_status; /* array of send status */
107: PetscInt nsends,nrecvs; /* numbers of sends and receives */
108: PetscScalar *svalues,*rvalues; /* sending and receiving data */
109: PetscInt rmax; /* maximum message length */
110: PetscInt *nprocs; /* tmp data used both during scatterbegin and end */
111: PetscInt nprocessed; /* number of messages already processed */
112: PetscTruth donotstash;
113: InsertMode insertmode;
114: PetscInt *bowners;
115: } VecStash;
117: struct _p_Vec {
118: PETSCHEADER(struct _VecOps);
119: PetscMap map;
120: void *data; /* implementation-specific data */
121: PetscInt N,n; /* global, local vector size */
122: PetscInt bs;
123: ISLocalToGlobalMapping mapping; /* mapping used in VecSetValuesLocal() */
124: ISLocalToGlobalMapping bmapping; /* mapping used in VecSetValuesBlockedLocal() */
125: PetscTruth array_gotten;
126: VecStash stash,bstash; /* used for storing off-proc values during assembly */
127: PetscTruth petscnative; /* means the ->data starts with VECHEADER and can use VecGetArrayFast()*/
128: };
130: #define VecGetArray(x,a) ((x)->petscnative ? (*(a) = *((PetscScalar **)(x)->data),0) : VecGetArray_Private((x),(a)))
131: #define VecRestoreArray(x,a) ((x)->petscnative ? PetscObjectStateIncrease((PetscObject)x) : VecRestoreArray_Private((x),(a)))
133: /*
134: Common header shared by array based vectors,
135: currently Vec_Seq and Vec_MPI
136: */
137: #define VECHEADER \
138: PetscScalar *array; \
139: PetscScalar *array_allocated; /* if the array was allocated by PETSc this is its pointer */ \
140: PetscScalar *unplacedarray; /* if one called VecPlaceArray(), this is where it stashed the original */
142: /* Default obtain and release vectors; can be used by any implementation */
143: EXTERN PetscErrorCode VecDuplicateVecs_Default(Vec,PetscInt,Vec *[]);
144: EXTERN PetscErrorCode VecDestroyVecs_Default(Vec [],PetscInt);
145: EXTERN PetscErrorCode VecLoadIntoVector_Default(PetscViewer,Vec);
147: /* --------------------------------------------------------------------*/
148: /* */
149: /* Defines the data structures used in the Vec Scatter operations */
151: typedef enum { VEC_SCATTER_SEQ_GENERAL,VEC_SCATTER_SEQ_STRIDE,
152: VEC_SCATTER_MPI_GENERAL,VEC_SCATTER_MPI_TOALL,
153: VEC_SCATTER_MPI_TOONE} VecScatterType;
155: /*
156: These scatters are for the purely local case.
157: */
158: typedef struct {
159: VecScatterType type;
160: PetscInt n; /* number of components to scatter */
161: PetscInt *vslots; /* locations of components */
162: /*
163: The next three fields are used in parallel scatters, they contain
164: optimization in the special case that the "to" vector and the "from"
165: vector are the same, so one only needs copy components that truly
166: copies instead of just y[idx[i]] = y[jdx[i]] where idx[i] == jdx[i].
167: */
168: PetscTruth nonmatching_computed;
169: PetscInt n_nonmatching; /* number of "from"s != "to"s */
170: PetscInt *slots_nonmatching; /* locations of "from"s != "to"s */
171: PetscTruth is_copy;
172: PetscInt copy_start; /* local scatter is a copy starting at copy_start */
173: PetscInt copy_length;
174: } VecScatter_Seq_General;
176: typedef struct {
177: VecScatterType type;
178: PetscInt n;
179: PetscInt first;
180: PetscInt step;
181: } VecScatter_Seq_Stride;
183: /*
184: This scatter is for a global vector copied (completely) to each processor (or all to one)
185: */
186: typedef struct {
187: VecScatterType type;
188: PetscMPIInt *count; /* elements of vector on each processor */
189: PetscScalar *work1;
190: PetscScalar *work2;
191: } VecScatter_MPI_ToAll;
193: /*
194: This is the general parallel scatter
195: */
196: typedef struct {
197: VecScatterType type;
198: PetscInt n; /* number of processors to send/receive */
199: PetscInt *starts; /* starting point in indices and values for each proc*/
200: PetscInt *indices; /* list of all components sent or received */
201: PetscMPIInt *procs; /* processors we are communicating with in scatter */
202: MPI_Request *requests,*rev_requests;
203: PetscScalar *values; /* buffer for all sends or receives */
204: VecScatter_Seq_General local; /* any part that happens to be local */
205: MPI_Status *sstatus,*rstatus;
206: PetscTruth use_readyreceiver;
207: PetscInt bs;
208: PetscTruth sendfirst;
209: } VecScatter_MPI_General;
211: struct _p_VecScatter {
212: PETSCHEADER(int);
213: PetscInt to_n,from_n;
214: PetscTruth inuse; /* prevents corruption from mixing two scatters */
215: PetscTruth beginandendtogether; /* indicates that the scatter begin and end
216: function are called together, VecScatterEnd()
217: is then treated as a nop */
218: PetscTruth packtogether; /* packs all the messages before sending, same with receive */
219: PetscErrorCode (*postrecvs)(Vec,Vec,InsertMode,ScatterMode,VecScatter);
220: PetscErrorCode (*begin)(Vec,Vec,InsertMode,ScatterMode,VecScatter);
221: PetscErrorCode (*end)(Vec,Vec,InsertMode,ScatterMode,VecScatter);
222: PetscErrorCode (*copy)(VecScatter,VecScatter);
223: PetscErrorCode (*destroy)(VecScatter);
224: PetscErrorCode (*view)(VecScatter,PetscViewer);
225: void *fromdata,*todata;
226: };
228: EXTERN PetscErrorCode VecStashCreate_Private(MPI_Comm,PetscInt,VecStash*);
229: EXTERN PetscErrorCode VecStashDestroy_Private(VecStash*);
230: EXTERN PetscErrorCode VecStashExpand_Private(VecStash*,PetscInt);
231: EXTERN PetscErrorCode VecStashScatterEnd_Private(VecStash*);
232: EXTERN PetscErrorCode VecStashSetInitialSize_Private(VecStash*,PetscInt);
233: EXTERN PetscErrorCode VecStashGetInfo_Private(VecStash*,PetscInt*,PetscInt*);
234: EXTERN PetscErrorCode VecStashScatterBegin_Private(VecStash*,PetscInt*);
235: EXTERN PetscErrorCode VecStashScatterGetMesg_Private(VecStash*,PetscMPIInt*,PetscInt**,PetscScalar**,PetscInt*);
237: /*
238: The following are implemented as macros to avoid the function
239: call overhead.
243: */
245: /*
246: VecStashValue_Private - inserts a single value into the stash.
248: Input Parameters:
249: stash - the stash
250: idx - the global of the inserted value
251: values - the value inserted
252: */
253: #define VecStashValue_Private(stash,row,value) \
254: { \
255: /* Check and see if we have sufficient memory */ \
256: if (((stash)->n + 1) > (stash)->nmax) { \
257: VecStashExpand_Private(stash,1); \
258: } \
259: (stash)->idx[(stash)->n] = row; \
260: (stash)->array[(stash)->n] = value; \
261: (stash)->n++; \
262: }
264: /*
265: VecStashValuesBlocked_Private - inserts 1 block of values into the stash.
267: Input Parameters:
268: stash - the stash
269: idx - the global block index
270: values - the values inserted
271: */
272: #define VecStashValuesBlocked_Private(stash,row,values) \
273: { \
274: PetscInt jj,stash_bs=(stash)->bs; \
275: PetscScalar *array; \
276: if (((stash)->n+1) > (stash)->nmax) { \
277: VecStashExpand_Private(stash,1); \
278: } \
279: array = (stash)->array + stash_bs*(stash)->n; \
280: (stash)->idx[(stash)->n] = row; \
281: for (jj=0; jj<stash_bs; jj++) { array[jj] = values[jj];} \
282: (stash)->n++; \
283: }
285: EXTERN PetscErrorCode VecReciprocal_Default(Vec);
287: #if defined(PETSC_HAVE_MATLAB)
289: EXTERN PetscErrorCode VecMatlabEnginePut_Default(PetscObject,void*);
290: EXTERN PetscErrorCode VecMatlabEngineGet_Default(PetscObject,void*);
292: #endif
295: #endif