00001
00002
00003
00004
00005
00006
00007 #ifndef _MBLOCK_IMPL_H
00008 #define _MBLOCK_IMPL_H
00009
00010 #include <stdio.h>
00011
00012 #include "mblock.decl.h"
00013 #include "mblock.h"
00014 #include "patch.h"
00015 #include "charm-api.h"
00016 #include "tcharm.h"
00017 #include "tcharmc.h"
00018
00019 #define CHK(p) do{if((p)==0)CkAbort("MBLK>Memory Allocation failure.");}while(0)
00020
00021
00022
00023 struct DType {
00024 int base_type;
00025 int vec_len;
00026 int init_offset;
00027 int distance;
00028 DType(void) {}
00029 DType(const DType& dt) :
00030 base_type(dt.base_type), vec_len(dt.vec_len), init_offset(dt.init_offset),
00031 distance(dt.distance) {}
00032 void operator=(const DType& dt) {
00033 base_type = dt.base_type;
00034 vec_len = dt.vec_len;
00035 init_offset = dt.init_offset;
00036 distance = dt.distance;
00037 }
00038 DType( const int b, const int v=1, const int i=0, const int d=0) :
00039 base_type(b), vec_len(v), init_offset(i) {
00040 distance = (d ? d : length());
00041 }
00042 int length(const int nitems=1) const {
00043 int blen;
00044 switch(base_type) {
00045 case MBLK_BYTE : blen = 1; break;
00046 case MBLK_INT : blen = sizeof(int); break;
00047 case MBLK_REAL : blen = sizeof(float); break;
00048 case MBLK_DOUBLE : blen = sizeof(double); break;
00049 }
00050 return blen * vec_len * nitems;
00051 }
00052
00053 void pup(PUP::er &p) {
00054 p(base_type);
00055 p(vec_len);
00056 p(init_offset);
00057 p(distance);
00058 }
00059
00060 };
00061
00062 class MBlockDataMsg : public CMessage_MBlockDataMsg
00063 {
00064 public:
00065 int seqnum;
00066 int from;
00067 int fid;
00068 unsigned char *data;
00069 int patchno;
00070 MBlockDataMsg(int s, int f, int fid_, int p) :
00071 seqnum(s), from(f), fid(fid_), patchno(p) { }
00072 };
00073
00074 #define MBLK_MAXDT 20
00075 #define MBLK_MAXUDATA 20
00076 #define MBLK_MAXBC 20
00077
00078 class field_t {
00079 public:
00080 DType dt;
00081 blockDim dim;
00082 int arrayBytes;
00083 bool forVoxel;
00084 field_t(const DType &dt_,const blockDim &dim_,bool forVoxel_)
00085 :dt(dt_),dim(dim_),forVoxel(forVoxel_) {
00086 arrayBytes=dim.getSize()*dt.distance;
00087 }
00088
00089 field_t() { }
00090 void pup(PUP::er &p) {
00091 dt.pup(p);
00092 dim.pup(p);
00093 p(forVoxel);
00094 }
00095 };
00096
00097 class MBlockChunk: public CBase_MBlockChunk
00098 {
00099 private:
00100 int nfields;
00101 field_t *fields[MBLK_MAXDT];
00102
00103 int nudata;
00104 void *userdata[MBLK_MAXUDATA];
00105 MBLK_PupFn pup_ud[MBLK_MAXUDATA];
00106
00107 CProxy_TCharm threads;
00108 TCharm *thread;
00109
00110 class bc_t {
00111 public:
00112 MBLK_BcFn fn;
00113 extrudeMethod m;
00114 bool isFortran;
00115 };
00116 bc_t bcs[MBLK_MAXBC];
00117
00118 CmmTable messages;
00119 int seqnum;
00120 class update_t {
00121 public:
00122 int nRecd;
00123 extrudeMethod m;
00124 int wait_seqnum;
00125 void *ogrid;
00126 };
00127 update_t update;
00128 int nRecvPatches;
00129
00130 void *reduce_output;
00131
00132 void commonInit(void);
00133 void migInit(void);
00134 public:
00135 block *b;
00136
00137 MBlockChunk(const CkArrayID &threads);
00138 MBlockChunk(CkMigrateMessage *msg);
00139 ~MBlockChunk();
00140
00141 void read(const char *prefix,int nDim);
00142
00143 void ckJustMigrated(void);
00144
00145
00146 void recv(MBlockDataMsg *);
00147 void reductionResult(CkReductionMsg *);
00148
00149 int add_field(field_t *f) {
00150 if (nfields==MBLK_MAXDT) return -1;
00151 fields[nfields]=f;
00152 nfields++;
00153 return nfields-1;
00154 }
00155
00156 void start_update(int fid,const extrudeMethod &m,void *ingrid, void *outgrid);
00157 int test_update(void);
00158 int wait_update(void);
00159 void reduce_field(int fid, const void *nodes, void *outbuf, int op);
00160 void reduce(int fid, const void *inbuf, void *outbuf, int op);
00161 void print(void);
00162
00163 int register_bc(const int bcnum, const MBLK_BcFn bcfn,const extrudeMethod &m,bool isFortran)
00164 {
00165 if(bcnum<0 || bcnum>=MBLK_MAXBC) {
00166 CkError("MBLK> BC index should be between 0 and %d!\n", MBLK_MAXBC-1);
00167 return MBLK_FAILURE;
00168 }
00169 bcs[bcnum].fn = bcfn;
00170 bcs[bcnum].m=m;
00171 bcs[bcnum].isFortran=isFortran;
00172 return MBLK_SUCCESS;
00173 }
00174
00175 void apply_single_bc(patch *p,void *p1,void *p2) {
00176 int bcNo=((externalBCpatch *)p)->bcNo;
00177 blockSpan s=p->getExtents(bcs[bcNo].m,true);
00178 int start[3],end[3];
00179 if (bcs[bcNo].isFortran) {
00180 s.start=s.start+blockLoc(1,1,1);
00181 s.end=s.end+blockLoc(1,1,1);
00182 }
00183 s.getInt3(start,end);
00184 TCharm::activateThread();
00185 (bcs[bcNo].fn)(p1,p2,start,end);
00186 TCharm::deactivateThread();
00187 }
00188
00189 int apply_bc(const int bcnum, void *p1,void *p2)
00190 {
00191 if(bcs[bcnum].fn == 0) {
00192 CkError("MBLK> BC handler not registered for bcnum %d!\n", bcnum);
00193 return MBLK_FAILURE;
00194 }
00195 int n = b->getPatches();
00196 for (int i=0; i< n; i++) {
00197 patch *p = b->getPatch(i);
00198 if(p->type == patch::ext && ((externalBCpatch*)p)->bcNo == bcnum)
00199 apply_single_bc(p,p1,p2);
00200 }
00201 return MBLK_SUCCESS;
00202 }
00203
00204 int apply_bc_all(void *p1,void *p2)
00205 {
00206 int i;
00207 int n = b->getPatches();
00208 for(i=0;i<n;i++) {
00209 patch *p = b->getPatch(i);
00210 if(p->type == patch::ext)
00211 apply_single_bc(p,p1,p2);
00212 }
00213 return MBLK_SUCCESS;
00214 }
00215
00216 static void copy(const blockLoc &src,int *dest,int shift=0) {
00217 dest[0]=src[0]+shift; dest[1]=src[1]+shift; dest[2]=src[2]+shift;
00218 }
00219
00220 void pup(PUP::er &p);
00221
00222 private:
00223 void send(int fid,const extrudeMethod &m,const void *grid);
00224 void update_field(MBlockDataMsg *m);
00225 };
00226
00227 class MBlockSetupCookie
00228 {
00229 public:
00230 MBlockSetupCookie();
00231 char prefix[1024];
00232 int ndims;
00233 int nblocks;
00234 void createArray(void);
00235 };
00236
00237 #define MBLOCKAPI(routineName) TCHARM_API_TRACE(routineName,"mblock")
00238
00239 #endif
00240
00241