00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "cksparsecontiguousreducer.h"
00010 
00011 
00012 
00013 
00014 CkReduction::reducerType sparse_sum_int;
00015 CkReduction::reducerType sparse_sum_float;
00016 CkReduction::reducerType sparse_sum_double;
00017 CkReduction::reducerType sparse_sum_TwoFloats;
00018 CkReduction::reducerType sparse_sum_TwoDoubles;
00019 
00020 CkReduction::reducerType sparse_product_int;
00021 CkReduction::reducerType sparse_product_float;
00022 CkReduction::reducerType sparse_product_double;
00023 
00024 CkReduction::reducerType sparse_max_int;
00025 CkReduction::reducerType sparse_max_float;
00026 CkReduction::reducerType sparse_max_double;
00027 
00028 CkReduction::reducerType sparse_min_int;
00029 CkReduction::reducerType sparse_min_float;
00030 CkReduction::reducerType sparse_min_double;
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 #define SIMPLE_SPARSE_CONTIGUOUS_REDUCTION(name,dataType,typeStr,loop) \
00042 static CkReductionMsg *name(int nMsg, CkReductionMsg ** msg){\
00043   if(nMsg==1){\
00044     CkReductionMsg *ret = msg[0];\
00045     msg[0] = NULL;\
00046     return ret;\
00047   }\
00048  \
00049   int               count          = 0;\
00050   CkDataSegHeader*  finalHeaderArr = NULL; \
00051   CkDataSegHeader** msgHeaderArr   = NULL; \
00052   int*              size           = NULL; \
00053   int*              pos            = NULL; \
00054   int*              off            = NULL; \
00055   int*              arrPos         = NULL; \
00056   int*              dataPos        = NULL; \
00057   int*              flag           = NULL; \
00058   int               i              = 0;\
00059 \
00060   \
00061   for(i=0; i<nMsg; i++) {\
00062     count += numDataSegs((unsigned char*)(msg[i]->getData()));\
00063   }\
00064 \
00065   int nm  = ((nMsg*sizeof(int)) + \
00066             sizeof(CkDataSegHeader))/sizeof(CkDataSegHeader);\
00067   int nmp = ((nMsg*sizeof(CkDataSegHeader*)) + \
00068             sizeof(CkDataSegHeader))/sizeof(CkDataSegHeader);\
00069   int nc  = ((count*sizeof(int)) + \
00070             sizeof(CkDataSegHeader))/sizeof(CkDataSegHeader);\
00071   int numHeaderToAllocate = count + nmp + 3*nm + 3*nc;\
00072 \
00073   finalHeaderArr = new CkDataSegHeader[numHeaderToAllocate];\
00074 \
00075   msgHeaderArr   = (CkDataSegHeader**)(finalHeaderArr + count);\
00076   size           = (int*)(((CkDataSegHeader*)msgHeaderArr) + nmp);\
00077   pos            = (int*)(((CkDataSegHeader*)size) + nm);\
00078   off            = (int*)(((CkDataSegHeader*)pos) + nm);\
00079   arrPos         = (int*)(((CkDataSegHeader*)off) + nm);\
00080   dataPos        = (int*)(((CkDataSegHeader*)arrPos) + nc);\
00081   flag           = (int*)(((CkDataSegHeader*)dataPos) + nc);\
00082 \
00083   \
00084 \
00085   \
00086   pos [0]          = 0;\
00087   size [0]         = numDataSegs((unsigned char*)(msg[0]->getData()));\
00088   off [0]          = 0;\
00089   msgHeaderArr [0] = getDataSegHeaderPtr((unsigned char*)(msg[0]->getData()));\
00090 \
00091   for(i=1; i<nMsg; i++){\
00092     unsigned char * data = (unsigned char*)(msg[i]->getData());\
00093     pos  [i]             = 0;\
00094     size [i]             = numDataSegs(data);\
00095     off [i]              = off [i-1] + size [i-1];\
00096     msgHeaderArr [i]     = getDataSegHeaderPtr(data);\
00097   }\
00098 \
00099   for(i=0; i<count; i++){\
00100     arrPos  [i]  = -1;\
00101     dataPos [i]  = -1;\
00102   }\
00103 \
00104   \
00105   int nScanned    = 0;\
00106   int currMsg     = 0;\
00107   \
00108   int totalHeader = 0;\
00109 \
00110   \
00111   int index = 0;\
00112   int currDataOff = 0;\
00113   CkDataSegHeader minHdr = msgHeaderArr [currMsg][pos[currMsg]];\
00114 \
00115   for (index=1; index < nMsg; index++) {\
00116     if (msgHeaderArr [index][pos[index]] < minHdr)  {\
00117       currMsg = index;\
00118       minHdr = msgHeaderArr [index][pos[index]];\
00119     }\
00120   }\
00121 \
00122   arrPos [off [currMsg] + pos [currMsg]] = totalHeader;\
00123   dataPos [off [currMsg] + pos [currMsg]] = currDataOff;\
00124   finalHeaderArr [totalHeader++] = msgHeaderArr [currMsg][pos[currMsg]++];\
00125   nScanned ++;\
00126 \
00127   while (nScanned != count) {\
00128     if (pos [currMsg] != size [currMsg]) {\
00129       minHdr = msgHeaderArr [currMsg][pos[currMsg]];\
00130     } else {\
00131       currMsg = (currMsg+1)%nMsg;\
00132       continue;\
00133     }\
00134     for (index=0; index < nMsg; index++) {\
00135       if ((pos [index] != size [index])&&\
00136           (msgHeaderArr [index][pos[index]] < minHdr))  {\
00137         currMsg = index;\
00138         minHdr = msgHeaderArr [index][pos[index]];\
00139       }\
00140     }\
00141 \
00142     if (!(finalHeaderArr [totalHeader-1] == msgHeaderArr [currMsg][pos[currMsg]])) {\
00143       currDataOff += sizeof(dataType)*finalHeaderArr [totalHeader-1].getNumElements();\
00144       arrPos [off [currMsg] + pos [currMsg]] = totalHeader;\
00145       dataPos [off [currMsg] + pos [currMsg]] = currDataOff;\
00146       finalHeaderArr [totalHeader++] = msgHeaderArr [currMsg][pos[currMsg]++];\
00147     }\
00148     else {\
00149       arrPos [off [currMsg] + pos [currMsg]] = totalHeader-1;\
00150       dataPos [off [currMsg] + pos [currMsg]] = currDataOff;\
00151       pos[currMsg]++;\
00152     }\
00153     nScanned ++;\
00154   }\
00155 \
00156  
00157 \
00158 \
00159   int alignedHdrSize = 2*sizeof(int) + sizeof(CkDataSegHeader)*totalHeader;\
00160   if (alignedHdrSize%sizeof(double))\
00161     alignedHdrSize += sizeof(double) - (alignedHdrSize%sizeof(double));\
00162   int dataSize = alignedHdrSize + \
00163                  currDataOff + \
00164                  sizeof(dataType)*finalHeaderArr [totalHeader-1].getNumElements();\
00165 \
00166   CkReductionMsg* m = CkReductionMsg::buildNew(dataSize, NULL); \
00167   unsigned char *data = (unsigned char*)(m->getData ());\
00168   memset (flag, 0, totalHeader*sizeof(int));\
00169 \
00170   *(int*)data = totalHeader;\
00171   data += sizeof(int);\
00172   *(int*)data = alignedHdrSize;\
00173   data += sizeof(int);\
00174 \
00175   int dataOffset = alignedHdrSize - 2*sizeof (int);\
00176   int numElems;\
00177   CkDataSegHeader* hdrPtr = (CkDataSegHeader*)data;\
00178   dataType*        dataptr = (dataType*)(data + dataOffset);\
00179 \
00180   for (i=0; i<nMsg; i++) {\
00181     dataType* msgDataptr = (dataType*)getDataPtr((unsigned char*)(msg[i]->getData()));\
00182     for (index=0; index<size[i]; index++) {\
00183       numElems = msgHeaderArr [i][index].getNumElements();\
00184 \
00185       hdrPtr [arrPos [off [i] + index]] = msgHeaderArr [i][index];\
00186       dataptr = (dataType*)(data + dataOffset + dataPos [off [i] + index]);\
00187       if (!flag [arrPos [off [i] + index]]) {\
00188         flag [arrPos [off [i] + index]] = 1;\
00189         memcpy(dataptr, msgDataptr, sizeof(dataType)*numElems);\
00190         msgDataptr += numElems;\
00191       } else {\
00192         for (int k=0; k<numElems; k++) {\
00193           loop\
00194           msgDataptr++;\
00195         }\
00196       }\
00197     }\
00198   }\
00199 \
00200   delete[] finalHeaderArr;\
00201 \
00202   return m;\
00203 }
00204 
00205 
00206 #define SIMPLE_POLYMORPH_SPARSE_CONTIGUOUS_REDUCTION(nameBase,loop) \
00207   SIMPLE_SPARSE_CONTIGUOUS_REDUCTION(nameBase##_int,int,"%d",loop) \
00208   SIMPLE_SPARSE_CONTIGUOUS_REDUCTION(nameBase##_float,float,"%f",loop) \
00209   SIMPLE_SPARSE_CONTIGUOUS_REDUCTION(nameBase##_double,double,"%f",loop)
00210 
00211 
00212 #define POLYMORPH_SPARSE_CONTIGUOUS_REDUCTION(nameBase,loop) \
00213   SIMPLE_SPARSE_CONTIGUOUS_REDUCTION(nameBase##_TwoFloats,CkTwoFloats,"%d",loop) \
00214   SIMPLE_SPARSE_CONTIGUOUS_REDUCTION(nameBase##_TwoDoubles,CkTwoDoubles,"%f",loop) \
00215 
00216 
00217 
00218 POLYMORPH_SPARSE_CONTIGUOUS_REDUCTION(_sparse_sum, *(dataptr + k) +=
00219   *msgDataptr;)
00220 
00221 
00222 
00223 SIMPLE_POLYMORPH_SPARSE_CONTIGUOUS_REDUCTION(_sparse_sum, *(dataptr + k) +=
00224   *msgDataptr;)
00225 
00226 
00227 
00228 SIMPLE_POLYMORPH_SPARSE_CONTIGUOUS_REDUCTION(_sparse_product, *(dataptr + k) *=
00229   *msgDataptr;)
00230 
00231 
00232 
00233 SIMPLE_POLYMORPH_SPARSE_CONTIGUOUS_REDUCTION(_sparse_max,
00234   if(*(dataptr+k)<*msgDataptr) *(dataptr+k)=*msgDataptr;)
00235 
00236 
00237 
00238 SIMPLE_POLYMORPH_SPARSE_CONTIGUOUS_REDUCTION(_sparse_min,
00239   if(*(dataptr+k)>*msgDataptr) *(dataptr+k)=*msgDataptr;)
00240 
00241 
00242 
00243 
00244 void registerReducers(void)
00245 {
00246   sparse_sum_int = CkReduction::addReducer(_sparse_sum_int);
00247   sparse_sum_float = CkReduction::addReducer(_sparse_sum_float);
00248   sparse_sum_double = CkReduction::addReducer(_sparse_sum_double);
00249   sparse_sum_TwoFloats = CkReduction::addReducer(_sparse_sum_TwoFloats);
00250   sparse_sum_TwoDoubles = CkReduction::addReducer(_sparse_sum_TwoDoubles);
00251 
00252   sparse_product_int = CkReduction::addReducer(_sparse_product_int);
00253   sparse_product_float= CkReduction::addReducer(_sparse_product_float);
00254   sparse_product_double = CkReduction::addReducer(_sparse_product_double);
00255 
00256   sparse_max_int = CkReduction::addReducer(_sparse_max_int);
00257   sparse_max_float = CkReduction::addReducer(_sparse_max_float);
00258   sparse_max_double = CkReduction::addReducer(_sparse_max_double);
00259 
00260   sparse_min_int = CkReduction::addReducer(_sparse_min_int);
00261   sparse_min_float= CkReduction::addReducer(_sparse_min_float);
00262   sparse_min_double = CkReduction::addReducer(_sparse_min_double);
00263 }
00264 
00265 int numDataSegs(const unsigned char *data){
00266   return *(int*)data;
00267 }
00268 
00269 CkDataSegHeader getDataSegHeader(int index, const unsigned char *data){
00270   int size=numDataSegs(data);
00271   CkDataSegHeader r;
00272   if(index >= size)
00273     CkAbort("Error!!!\n");
00274 
00275   memcpy(&r, data+2*sizeof(int)+sizeof(CkDataSegHeader)*index, sizeof(CkDataSegHeader));
00276   return r;
00277 }
00278 
00279 
00280 
00281 
00282 
00283 
00284 
00285 
00286 
00287 unsigned char * getDataPtr(unsigned char *ptr){
00288 
00289 
00290 
00291 
00292 
00293   return (ptr + *(((int*)ptr)+1));
00294 }
00295 
00296 CkDataSegHeader* getDataSegHeaderPtr(const unsigned char *ptr) {
00297   return (CkDataSegHeader*)(ptr + 2*sizeof(int));
00298 }
00299 
00300 CkDataSegHeader getDecompressedDataHdr(const unsigned char *msg){
00301   CkDataSegHeader retHead(0, 0, 0, 0);
00302   CkDataSegHeader h;
00303   int numSegs = numDataSegs(msg);
00304 
00305   for(int i=0; i<numSegs; i++){
00306     h = getDataSegHeader(i, msg);
00307     if(retHead.sx > h.sx)
00308       retHead.sx = h.sx;
00309     if(retHead.sy > h.sy)
00310       retHead.sy = h.sy;
00311     if(retHead.ex < h.ex)
00312       retHead.ex = h.ex;
00313     if(retHead.ey < h.ey)
00314       retHead.ey = h.ey;
00315   }
00316   return retHead;
00317 }
00318 
00319 #define SIMPLE_DECOMPRESSOR(dataType)\
00320 dataType *decompressMsg(CkReductionMsg *m, CkDataSegHeader &h, dataType nullVal){\
00321   unsigned char *msg = (unsigned char*)m->getData();\
00322   h = getDecompressedDataHdr(msg);\
00323   CkDataSegHeader head;\
00324   dataType *data;\
00325   int sizeX = h.ex - h.sx + 1;\
00326   int sizeY = h.ey - h.sy + 1;\
00327   int numSegs = numDataSegs(msg);\
00328 \
00329   data = new dataType[sizeX*sizeY];\
00330 \
00331   int i;    \
00332   for(i=0; i<sizeX*sizeY; i++)\
00333       data[i] = nullVal;\
00334 \
00335   dataType *msgDataptr = (dataType *)getDataPtr(msg);\
00336   for(i=0; i<numSegs; i++){\
00337     head = getDataSegHeader(i, msg);\
00338     int startY = head.sy - h.sy;\
00339     int endY   = head.ey - h.sy;\
00340     int startX = head.sx - h.sx;\
00341     int endX   = head.ex - h.sx;\
00342     for(int y=startY; y<=endY; y++){\
00343       int inc = y*sizeX;\
00344       for(int x=startX; x<=endX; x++)\
00345         data[x+inc] = *msgDataptr++;\
00346     }\
00347   }\
00348   return data;\
00349 }
00350 
00351 
00352 SIMPLE_DECOMPRESSOR(int)
00353 
00354 
00355 SIMPLE_DECOMPRESSOR(float)
00356 
00357 
00358 SIMPLE_DECOMPRESSOR(double)
00359 
00360 
00361 SIMPLE_DECOMPRESSOR(CkTwoFloats)
00362 
00363 
00364 SIMPLE_DECOMPRESSOR(CkTwoDoubles)
00365 #include "CkSparseContiguousReducer.def.h"