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:   void                   *esivec;      /* ESI wrapper of vector */
123: };

125: #define VecGetArrayFast(x,a)     ((x)->petscnative ? (*(a) = *((PetscScalar **)(x)->data),0) : VecGetArray((x),(a)))
126: #define VecRestoreArrayFast(x,a) ((x)->petscnative ? 0 : VecRestoreArray((x),(a)))

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

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

140: EXTERN int VecLoadIntoVector_Default(PetscViewer,Vec);

142: /* --------------------------------------------------------------------*/
143: /*                                                                     */
144: /* Defines the data structures used in the Vec Scatter operations      */

146: typedef enum { VEC_SCATTER_SEQ_GENERAL,VEC_SCATTER_SEQ_STRIDE,
147:                VEC_SCATTER_MPI_GENERAL,VEC_SCATTER_MPI_TOALL,
148:                VEC_SCATTER_MPI_TOONE} VecScatterType;

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

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

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

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

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

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

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

236:    extern int VecStashValue_Private(VecStash*,int,PetscScalar);
237:    extern int VecStashValuesBlocked_Private(VecStash*,int,PetscScalar*);
238: */

240: /*
241:   VecStashValue_Private - inserts a single values into the stash.

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

259: /*
260:   VecStashValuesBlocked_Private - inserts 1 block of values into the stash. 

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

280: EXTERN int VecReciprocal_Default(Vec);

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


290: #endif