Actual source code: vecimpl.h

  2: /* $Id: vecimpl.h,v 1.83 2001/03/22 20:29:16 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
 11:  #include petscvec.h

 13: struct _MapOps {
 14:   int  (*getlocalsize)(Map,int*),
 15:        (*getglobalsize)(Map,int*),
 16:        (*getlocalrange)(Map,int*,int*),
 17:        (*getglobalrange)(Map,int**),
 18:        (*destroy)(Map);
 19: };

 21: struct _p_Map {
 22:   PETSCHEADER(struct _MapOps)
 23:   int                    rstart,rend;       /* local start, local end + 1 */
 24:   int                    N,n;              /* global, local vector size */
 25:   int                    *range;
 26: };

 28: /* ----------------------------------------------------------------------------*/

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

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

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

110: struct _p_Vec {
111:   PETSCHEADER(struct _VecOps)
112:   Map                    map;
113:   void                   *data;     /* implementation-specific data */
114:   int                    N,n;      /* global, local vector size */
115:   int                    bs;
116:   ISLocalToGlobalMapping mapping;   /* mapping used in VecSetValuesLocal() */
117:   ISLocalToGlobalMapping bmapping;  /* mapping used in VecSetValuesBlockedLocal() */
118:   PetscTruth             array_gotten;
119:   VecStash               stash,bstash; /* used for storing off-proc values during assembly */
120: };

122: /*
123:      Common header shared by array based vectors, 
124:    currently Vec_Seq and Vec_MPI
125: */
126: #define VECHEADER                         
127:   Scalar *array;                          
128:   Scalar *array_allocated;            

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

134: EXTERN int VecLoadIntoVector_Default(PetscViewer,Vec);

136: /* --------------------------------------------------------------------*/
137: /*                                                                     */
138: /* Defines the data structures used in the Vec Scatter operations      */

140: typedef enum { VEC_SCATTER_SEQ_GENERAL,VEC_SCATTER_SEQ_STRIDE,
141:                VEC_SCATTER_MPI_GENERAL,VEC_SCATTER_MPI_TOALL,
142:                VEC_SCATTER_MPI_TOONE} VecScatterType;

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

165: typedef struct {
166:   VecScatterType type;
167:   int            n;
168:   int            first;
169:   int            step;
170: } VecScatter_Seq_Stride;

172: /*
173:    This scatter is for a global vector copied (completely) to each processor (or all to one)
174: */
175: typedef struct {
176:   VecScatterType type;
177:   int            *count;        /* elements of vector on each processor */
178:   Scalar         *work1;
179:   Scalar         *work2;
180: } VecScatter_MPI_ToAll;

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

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

217: EXTERN int VecStashCreate_Private(MPI_Comm,int,VecStash*);
218: EXTERN int VecStashDestroy_Private(VecStash*);
219: EXTERN int VecStashExpand_Private(VecStash*,int);
220: EXTERN int VecStashScatterEnd_Private(VecStash*);
221: EXTERN int VecStashSetInitialSize_Private(VecStash*,int);
222: EXTERN int VecStashGetInfo_Private(VecStash*,int*,int*);
223: EXTERN int VecStashScatterBegin_Private(VecStash*,int*);
224: EXTERN int VecStashScatterGetMesg_Private(VecStash*,int*,int**,Scalar**,int*);

226: /* 
227:    The following are implemented as macros to avoid the function
228:    call overhead.

230:    extern int VecStashValue_Private(VecStash*,int,Scalar);
231:    extern int VecStashValuesBlocked_Private(VecStash*,int,Scalar*);
232: */

234: /*
235:   VecStashValue_Private - inserts a single values into the stash.

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

253: /*
254:   VecStashValuesBlocked_Private - inserts 1 block of values into the stash. 

256:   Input Parameters:
257:   stash  - the stash
258:   idx    - the global block index
259:   values - the values inserted
260: */
261: #define VecStashValuesBlocked_Private(stash,row,values) 
262: { 
263:   int    jj,stash_bs=(stash)->bs; 
264:   Scalar *array; 
265:   if (((stash)->n+1) > (stash)->nmax) { 
266:     VecStashExpand_Private(stash,1); 
267:   } 
268:   array = (stash)->array + stash_bs*(stash)->n; 
269:   (stash)->idx[(stash)->n]   = row; 
270:   for (jj=0; jj<stash_bs; jj++) { array[jj] = values[jj];} 
271:   (stash)->n++; 
272: }

274: EXTERN int VecReciprocal_Default(Vec);

276: #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX)
277: EXTERN_C_BEGIN
278: EXTERN int VecMatlabEnginePut_Default(PetscObject,void*);
279: EXTERN int VecMatlabEngineGet_Default(PetscObject,void*);
280: EXTERN_C_END
281: #endif


284: #endif