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