00001 
00005 
00006 #include <converse.h>
00007 
00008 #if CMK_LBDB_ON
00009 
00010 #include <math.h>
00011 #include "LBComm.h"
00012 #include <set>
00013 
00014 #include "TopoManager.h"
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 LBCommData* LBCommTable::HashInsert(const LBCommData &data)
00029 {
00030   if (in_use > cur_sz/2)
00031     Resize();
00032   int i = 0;
00033   int j;
00034   do {
00035     j = data.hash(i,cur_sz);
00036     
00037     if (state[j] == nil) {
00038       state[j] = InUse;
00039       set[j] = data;
00040       in_use++;
00041       return &set[j];
00042     } else i++;
00043   } while (i != cur_sz);
00044 
00045   
00046   
00047   CmiPrintf("HashInsert Couldn't insert!\n");
00048   return 0;
00049 }
00050 
00051 LBCommData* LBCommTable::HashSearch(const LBCommData &data)
00052 {
00053   int i=0;
00054   int j;
00055   do {
00056     j = data.hash(i,cur_sz);
00057     if (state[j] != nil && set[j].equal(data)) {
00058       return &set[j];
00059     }
00060     i++;
00061   } while (state[j] != nil && i != cur_sz);
00062   return 0;
00063 }
00064 
00065 LBCommData* LBCommTable::HashInsertUnique(const LBCommData &data)
00066 {
00067   LBCommData* item = HashSearch(data);
00068   if (!item) {
00069     item = HashInsert(data);
00070   }
00071   return item;
00072 }
00073 
00074 void LBCommTable::Resize()
00075 {
00076   LBCommData* old_set = set;
00077   TableState* old_state = state;
00078   int old_sz = cur_sz;
00079 
00080   NewTable(old_sz*2);
00081   for(int i=0; i < old_sz; i++) {
00082     if (old_state[i] == InUse)
00083       HashInsert(old_set[i]);
00084   }
00085   delete [] old_set;
00086   delete [] old_state;
00087 }   
00088 
00089 bool LBCommData::equal(const LBCommData &d2) const
00090 {
00091   if (from_proc()) {
00092     if (src_proc != d2.src_proc)
00093       return false;
00094   } else {
00095     if (srcObj.omID() != d2.srcObj.omID()
00096     || srcObj.objID() != d2.srcObj.objID() )
00097       return false;
00098   }
00099   return (bool)(destObj == d2.destObj);
00100 }
00101 
00102 int LBCommData::compute_key()
00103 {
00104   int kstring[80];
00105   char* kptr = (char*)((void*)(&(kstring[0])));
00106   int pcount;
00107 
00108   if (from_proc()) {
00109     pcount = sprintf(kptr,"%d",src_proc);
00110     kptr += pcount;
00111   } else {
00112     pcount = sprintf(kptr,"%d%" PRIu64 "",srcObj.omID().id.idx,
00113              srcObj.id);
00114     kptr += pcount;
00115   }
00116 
00117   
00118   switch (destObj.get_type()) {
00119   case LD_PROC_MSG:
00120        pcount += sprintf(kptr,"%d", destObj.proc());
00121        break;
00122   case LD_OBJ_MSG: {
00123        LDObjKey &destKey = destObj.get_destObj();
00124        pcount += sprintf(kptr,"%d%" PRIu64 "XXXXXXXX",destKey.omID().id.idx,
00125             destKey.objID());
00126        pcount -= 8;  
00127        break;
00128        }
00129   case LD_OBJLIST_MSG: {
00130        int len;
00131        const LDObjKey *destKeys = destObj.get_destObjs(len);
00132        CmiAssert(len>0);
00133        pcount += sprintf(kptr,"%d%" PRIu64 "XXXXXXXX",destKeys[0].omID().id.idx,
00134             destKeys[0].objID());
00135        pcount -= 8;  
00136        break;
00137        }
00138   }
00139 
00140   int k=-1;
00141   for(int i=0; i < (pcount+3)/4; i++)
00142     k ^= kstring[i];
00143 
00144   
00145 
00146   return k;
00147 }
00148 
00149 int LBCommData::hash(const int i, const int m) const
00150 {
00151   const double a = 0.6803398875;
00152   const int k = key();
00153   const double ka = k * a;
00154 
00155   int h1 = (int) floor(m*(ka-floor(ka)));
00156   int h2 = 1;  
00157            
00158 
00159   
00160   return (h1 + i * h2) % m;
00161 }
00162 
00163 void LBCommTable::GetCommData(LDCommData* data)
00164 {
00165   LDCommData* out=data;
00166   LBCommData* curtable=set;
00167   TableState* curstate=state;
00168   int i;
00169 
00170   for(i=0; i < cur_sz; i++, curtable++, curstate++) {
00171     if (*curstate == InUse) {
00172       out->clearHash();
00173       if (curtable->from_proc()) {
00174     out->src_proc = curtable->src_proc;
00175       } else {
00176     out->src_proc = -1;
00177         out->sender.omID() = curtable->srcObj.omID();
00178         out->sender.objID() = curtable->srcObj.objID();
00179       }
00180       out->receiver = curtable->destObj;
00181       out->messages = curtable->n_messages;
00182       out->bytes = curtable->n_bytes;
00183       out++;
00184     }
00185   }
00186 }
00187 
00188 struct LDCommDescComp {
00189   bool operator() (const LDCommDesc& lhs, const LDCommDesc &rhs) const {
00190     return (lhs.get_destObj() < rhs.get_destObj());
00191   }
00192 };
00193 
00194 void LBCommTable::GetCommInfo(int& bytes, int& msgs, int& outsidepemsgs, int&
00195     outsidepebytes, int& num_nghbor, int& hops, int& hopbytes) {
00196 
00197   LBCommData* curtable=set;
00198   TableState* curstate=state;
00199   int i;
00200   bytes = 0;
00201   msgs = 0;
00202   outsidepemsgs = 0;
00203   outsidepebytes = 0;
00204   hops = 0;
00205   hopbytes = 0;
00206   std::set<LDCommDesc, LDCommDescComp> num_neighbors;
00207 
00208   int h;
00209 
00210   for(i=0; i < cur_sz; i++, curtable++, curstate++) {
00211     if (*curstate == InUse) {
00212       msgs += curtable->n_messages;
00213       bytes += curtable->n_bytes;
00214       if (curtable->destObj.get_type() == LD_OBJ_MSG) {
00215         num_neighbors.insert(curtable->destObj);
00216       }
00217 
00218       if (curtable->destObj.lastKnown() != CkMyPe()) {
00219         outsidepebytes += curtable->n_bytes;
00220         outsidepemsgs += curtable->n_messages;
00221         if(curtable->destObj.lastKnown()>=0 && curtable->destObj.lastKnown()<CkNumPes()){
00222           TopoManager_getHopsBetweenPeRanks(CkMyPe(), curtable->destObj.lastKnown(), &h);
00223           hops += curtable->n_messages * h;
00224           hopbytes += curtable->n_bytes * h;
00225         }
00226       }
00227     }
00228   }
00229   num_nghbor = num_neighbors.size();
00230 }
00231 
00232 #endif // CMK_LBDB_ON
00233