Actual source code: vecimpl.h

  2: /* $Id: vecimpl.h,v 1.89 2001/09/19 16:07:46 bsmith Exp $ */

  4: /* 
  5:    This private file should not be included in users' code.
  6:    Defines the fields shared by all vector implementations.
  7: */

  9: #ifndef __VECIMPL_H

 12:  #include petscvec.h

 14: struct _PetscMapOps {
 15:   int (*setfromoptions)(PetscMap),
 16:       (*destroy)(PetscMap);
 17: };

 19: struct _p_PetscMap {
 20:   PETSCHEADER(struct _PetscMapOps)
 21:   int  n,N;         /* local, global vector size */
 22:   int  rstart,rend; /* local start, local end + 1 */
 23:   int *range;       /* the offset of each processor */
 24: };

 26: /* ----------------------------------------------------------------------------*/

 28: typedef struct _VecOps *VecOps;
 29: struct _VecOps {
 30:   int  (*duplicate)(Vec,Vec*),              /* get single vector */
 31:        (*duplicatevecs)(Vec,int,Vec**),     /* get array of vectors */
 32:        (*destroyvecs)(const Vec[],int),     /* free array of vectors */
 33:        (*dot)(Vec,Vec,PetscScalar*),             /* z = x^H * y */
 34:        (*mdot)(int,Vec,const Vec[],PetscScalar*), /* z[j] = x dot y[j] */
 35:        (*norm)(Vec,NormType,PetscReal*),        /* z = sqrt(x^H * x) */
 36:        (*tdot)(Vec,Vec,PetscScalar*),             /* x'*y */
 37:        (*mtdot)(int,Vec,const Vec[],PetscScalar*),/* z[j] = x dot y[j] */
 38:        (*scale)(const PetscScalar*,Vec),          /* x = alpha * x   */
 39:        (*copy)(Vec,Vec),                     /* y = x */
 40:        (*set)(const PetscScalar*,Vec),            /* y = alpha  */
 41:        (*swap)(Vec,Vec),                     /* exchange x and y */
 42:        (*axpy)(const PetscScalar*,Vec,Vec),       /* y = y + alpha * x */
 43:        (*axpby)(const PetscScalar*,const PetscScalar*,Vec,Vec), /* y = y + alpha * x + beta * y*/
 44:        (*maxpy)(int,const PetscScalar*,Vec,Vec*), /* y = y + alpha[j] x[j] */
 45:        (*aypx)(const PetscScalar*,Vec,Vec),       /* y = x + alpha * y */
 46:        (*waxpy)(const PetscScalar*,Vec,Vec,Vec),  /* w = y + alpha * x */
 47:        (*pointwisemult)(Vec,Vec,Vec),        /* w = x .* y */
 48:        (*pointwisedivide)(Vec,Vec,Vec),      /* w = x ./ y */
 49:        (*setvalues)(Vec,int,const int[],const PetscScalar[],InsertMode),
 50:        (*assemblybegin)(Vec),                /* start global assembly */
 51:        (*assemblyend)(Vec),                  /* end global assembly */
 52:        (*getarray)(Vec,PetscScalar**),            /* get data array */
 53:        (*getsize)(Vec,int*),
 54:        (*getlocalsize)(Vec,int*),
 55:        (*restorearray)(Vec,PetscScalar**),        /* restore data array */
 56:        (*max)(Vec,int*,PetscReal*),      /* z = max(x); idx=index of max(x) */
 57:        (*min)(Vec,int*,PetscReal*),      /* z = min(x); idx=index of min(x) */
 58:        (*setrandom)(PetscRandom,Vec),        /* set y[j] = random numbers */
 59:        (*setoption)(Vec,VecOption),
 60:        (*setvaluesblocked)(Vec,int,const int[],const PetscScalar[],InsertMode),
 61:        (*destroy)(Vec),
 62:        (*view)(Vec,PetscViewer),
 63:        (*placearray)(Vec,const PetscScalar*),     /* place data array */
 64:        (*replacearray)(Vec,const PetscScalar*),     /* replace data array */
 65:        (*dot_local)(Vec,Vec,PetscScalar*),
 66:        (*tdot_local)(Vec,Vec,PetscScalar*),
 67:        (*norm_local)(Vec,NormType,PetscReal*),
 68:        (*loadintovector)(PetscViewer,Vec),
 69:        (*reciprocal)(Vec),
 70:        (*viewnative)(Vec,PetscViewer),
 71:        (*conjugate)(Vec),
 72:        (*setlocaltoglobalmapping)(Vec,ISLocalToGlobalMapping),
 73:        (*setvalueslocal)(Vec,int,const int *,const PetscScalar *,InsertMode),
 74:        (*resetarray)(Vec),      /* vector points to its original array, i.e. undoes any VecPlaceArray() */
 75:        (*setfromoptions)(Vec),
 76:        (*maxpointwisedivide)(Vec,Vec,PetscReal*);      /* m = max abs(x ./ y) */
 77: };

 79: /* 
 80:     The stash is used to temporarily store inserted vec values that 
 81:   belong to another processor. During the assembly phase the stashed 
 82:   values are moved to the correct processor and 
 83: */

 85: typedef struct {
 86:   int           nmax;                   /* maximum stash size */
 87:   int           umax;                   /* max stash size user wants */
 88:   int           oldnmax;                /* the nmax value used previously */
 89:   int           n;                      /* stash size */
 90:   int           bs;                     /* block size of the stash */
 91:   int           reallocs;               /* preserve the no of mallocs invoked */
 92:   int           *idx;                   /* global row numbers in stash */
 93:   PetscScalar   *array;                 /* array to hold stashed values */
 94:   /* The following variables are used for communication */
 95:   MPI_Comm      comm;
 96:   int           size,rank;
 97:   int           tag1,tag2;
 98:   MPI_Request   *send_waits;            /* array of send requests */
 99:   MPI_Request   *recv_waits;            /* array of receive requests */
100:   MPI_Status    *send_status;           /* array of send status */
101:   int           nsends,nrecvs;          /* numbers of sends and receives */
102:   PetscScalar   *svalues,*rvalues;      /* sending and receiving data */
103:   int           rmax;                   /* maximum message length */
104:   int           *nprocs;                /* tmp data used both duiring scatterbegin and end */
105:   int           nprocessed;             /* number of messages already processed */
106:   PetscTruth    donotstash;
107:   InsertMode    insertmode;
108:   int           *bowners;
109: } VecStash;

111: struct _p_Vec {
112:   PETSCHEADER(struct _VecOps)
113:   PetscMap               map;
114:   void                   *data;     /* implementation-specific data */
115:   int                    N,n;      /* global, local vector size */
116:   int                    bs;
117:   ISLocalToGlobalMapping mapping;   /* mapping used in VecSetValuesLocal() */
118:   ISLocalToGlobalMapping bmapping;  /* mapping used in VecSetValuesBlockedLocal() */
119:   PetscTruth             array_gotten;
120:   VecStash               stash,bstash; /* used for storing off-proc values during assembly */
121:   PetscTruth             petscnative;  /* means the ->data starts with VECHEADER and can use VecGetArrayFast()*/
122:   PetscReal              normcurrent;  /* contains the current 2 norm of the vector, if normvalid is true */
123:   PetscTruth             normvalid;    /* flag indicating that normcurrent is correct */
124:   void                   *esivec;      /* ESI wrapper of vector */
125: };

127: #define VecGetArrayFast(x,a)     ((x)->petscnative ? (*(a) = *((PetscScalar **)(x)->data),0) : VecGetArray((x),(a)))
128: #define VecRestoreArrayFast(x,a) ((x)->petscnative ? (x->normvalid = PETSC_FALSE) : VecRestoreArray((x),(a)))

130: /*
131:      Common header shared by array based vectors, 
132:    currently Vec_Seq and Vec_MPI
133: */
134: #define VECHEADER                         \
135:   PetscScalar *array;                          \
136:   PetscScalar *array_allocated;            

138: /* Default obtain and release vectors; can be used by any implementation */
139: EXTERN int VecDuplicateVecs_Default(Vec,int,Vec *[]);
140: EXTERN int VecDestroyVecs_Default(const Vec [],int);

142: EXTERN int VecLoadIntoVector_Default(PetscViewer,Vec);

144: /* --------------------------------------------------------------------*/
145: /*                                                                     */
146: /* Defines the data structures used in the Vec Scatter operations      */

148: typedef enum { VEC_SCATTER_SEQ_GENERAL,VEC_SCATTER_SEQ_STRIDE,
149:                VEC_SCATTER_MPI_GENERAL,VEC_SCATTER_MPI_TOALL,
150:                VEC_SCATTER_MPI_TOONE} VecScatterType;

152: /* 
153:    These scatters are for the purely local case.
154: */
155: typedef struct {
156:   VecScatterType type;
157:   int            n;                    /* number of components to scatter */
158:   int            *slots;               /* locations of components */
159:   /*
160:        The next three fields are used in parallel scatters, they contain 
161:        optimization in the special case that the "to" vector and the "from" 
162:        vector are the same, so one only needs copy components that truly 
163:        copies instead of just y[idx[i]] = y[jdx[i]] where idx[i] == jdx[i].
164:   */
165:   PetscTruth     nonmatching_computed;
166:   int            n_nonmatching;        /* number of "from"s  != "to"s */
167:   int            *slots_nonmatching;   /* locations of "from"s  != "to"s */
168:   PetscTruth     is_copy;
169:   int            copy_start;   /* local scatter is a copy starting at copy_start */
170:   int            copy_length;
171: } VecScatter_Seq_General;

173: typedef struct {
174:   VecScatterType type;
175:   int            n;
176:   int            first;
177:   int            step;
178: } VecScatter_Seq_Stride;

180: /*
181:    This scatter is for a global vector copied (completely) to each processor (or all to one)
182: */
183: typedef struct {
184:   VecScatterType type;
185:   int            *count;        /* elements of vector on each processor */
186:   PetscScalar    *work1;
187:   PetscScalar    *work2;
188: } VecScatter_MPI_ToAll;

190: /*
191:    This is the general parallel scatter
192: */
193: typedef struct {
194:   VecScatterType         type;
195:   int                    n;        /* number of processors to send/receive */
196:   int                    *starts;  /* starting point in indices and values for each proc*/
197:   int                    *indices; /* list of all components sent or received */
198:   int                    *procs;   /* processors we are communicating with in scatter */
199:   MPI_Request            *requests,*rev_requests;
200:   PetscScalar            *values;  /* buffer for all sends or receives */
201:   VecScatter_Seq_General local;    /* any part that happens to be local */
202:   MPI_Status             *sstatus,*rstatus;
203:   PetscTruth             use_readyreceiver;
204:   int                    bs;
205:   PetscTruth             sendfirst;
206: } VecScatter_MPI_General;

208: struct _p_VecScatter {
209:   PETSCHEADER(int)
210:   int        to_n,from_n;
211:   PetscTruth inuse;   /* prevents corruption from mixing two scatters */
212:   PetscTruth beginandendtogether;         /* indicates that the scatter begin and end
213:                                           function are called together, VecScatterEnd()
214:                                           is then treated as a nop */
215:   PetscTruth packtogether; /* packs all the messages before sending, same with receive */
216:   int        (*postrecvs)(Vec,Vec,InsertMode,ScatterMode,VecScatter);
217:   int        (*begin)(Vec,Vec,InsertMode,ScatterMode,VecScatter);
218:   int        (*end)(Vec,Vec,InsertMode,ScatterMode,VecScatter);
219:   int        (*copy)(VecScatter,VecScatter);
220:   int        (*destroy)(VecScatter);
221:   int        (*view)(VecScatter,PetscViewer);
222:   void       *fromdata,*todata;
223: };

225: EXTERN int VecStashCreate_Private(MPI_Comm,int,VecStash*);
226: EXTERN int VecStashDestroy_Private(VecStash*);
227: EXTERN int VecStashExpand_Private(VecStash*,int);
228: EXTERN int VecStashScatterEnd_Private(VecStash*);
229: EXTERN int VecStashSetInitialSize_Private(VecStash*,int);
230: EXTERN int VecStashGetInfo_Private(VecStash*,int*,int*);
231: EXTERN int VecStashScatterBegin_Private(VecStash*,int*);
232: EXTERN int VecStashScatterGetMesg_Private(VecStash*,int*,int**,PetscScalar**,int*);

234: /* 
235:    The following are implemented as macros to avoid the function
236:    call overhead.

238:    extern int VecStashValue_Private(VecStash*,int,PetscScalar);
239:    extern int VecStashValuesBlocked_Private(VecStash*,int,PetscScalar*);
240: */

242: /*
243:   VecStashValue_Private - inserts a single values into the stash.

245:   Input Parameters:
246:   stash  - the stash
247:   idx    - the global of the inserted value
248:   values - the value inserted
249: */
250: #define VecStashValue_Private(stash,row,value) \
251: {  \
252:   /* Check and see if we have sufficient memory */ \
253:   if (((stash)->n + 1) > (stash)->nmax) { \
254:     VecStashExpand_Private(stash,1); \
255:   } \
256:   (stash)->idx[(stash)->n]   = row; \
257:   (stash)->array[(stash)->n] = value; \
258:   (stash)->n++; \
259: }

261: /*
262:   VecStashValuesBlocked_Private - inserts 1 block of values into the stash. 

264:   Input Parameters:
265:   stash  - the stash
266:   idx    - the global block index
267:   values - the values inserted
268: */
269: #define VecStashValuesBlocked_Private(stash,row,values) \
270: { \
271:   int    jj,stash_bs=(stash)->bs; \
272:   PetscScalar *array; \
273:   if (((stash)->n+1) > (stash)->nmax) { \
274:     VecStashExpand_Private(stash,1); \
275:   } \
276:   array = (stash)->array + stash_bs*(stash)->n; \
277:   (stash)->idx[(stash)->n]   = row; \
278:   for (jj=0; jj<stash_bs; jj++) { array[jj] = values[jj];} \
279:   (stash)->n++; \
280: }

282: EXTERN int VecReciprocal_Default(Vec);

284: #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE)
285: EXTERN_C_BEGIN
286: EXTERN int VecMatlabEnginePut_Default(PetscObject,void*);
287: EXTERN int VecMatlabEngineGet_Default(PetscObject,void*);
288: EXTERN_C_END
289: #endif


292: #endif