86c9780e3b16b27fa8536080406f934fd527c6c9
[charm.git] / src / libs / ck-libs / idxl / idxl_comm.C
1 /**
2 IDXL--C++ structures used by idxl library.
3
4 Orion Sky Lawlor, olawlor@acm.org, 1/7/2003
5 */
6 #include "charm++.h"
7 #include "idxl.h"
8
9 /*Rec: lists the chunks that share a single entity.
10  */
11 IDXL_Rec::IDXL_Rec(int entity_) {
12         entity=entity_; 
13 }
14 IDXL_Rec::~IDXL_Rec() {}
15 void IDXL_Rec::pup(PUP::er &p)
16 {
17         p(entity); 
18         shares.pup(p);
19 }
20 void IDXL_Rec::add(int chk,int idx) 
21 {
22         int n=shares.size();
23 #ifndef CMK_OPTIMIZE
24         if (chk<0 || chk>1000000)
25                 CkAbort("FEM IDXL_Rec::add> Tried to add absurd chunk number!\n");
26 #endif
27         shares.setSize(n+1); //Grow slowly, to save memory
28         shares.push_back(IDXL_Share(chk,idx));
29 }
30
31 /*Map: map entity number to IDXL_Rec.  
32  */
33 IDXL_Map::IDXL_Map() {}
34 IDXL_Map::~IDXL_Map() {
35         //Delete the hashtable entries
36         CkHashtableIterator *it=map.iterator();
37         IDXL_Rec **rec;
38         while (NULL!=(rec=(IDXL_Rec **)it->next()))
39                 delete *rec;
40         delete it;
41 }
42
43 //Add a comm. entry for this entity
44 void IDXL_Map::add(int entity,int chk,int idx)
45 {
46         IDXL_Rec *rec;
47         if (NULL!=(rec=map.get(entity))) 
48         { //Already have a record in the table
49                 rec->add(chk,idx);
50         }
51         else
52         { //Make new record for this entity
53                 rec=new IDXL_Rec(entity);
54                 rec->add(chk,idx);
55                 map.put(entity)=rec;
56         }
57 }
58
59 //Look up this entity's IDXL_Rec.  Returns NULL if entity is not shared.
60 const IDXL_Rec *IDXL_Map::get(int entity) const
61 {
62         return map.get(entity);
63 }
64
65 IDXL_List::IDXL_List()
66 {
67         chunk=-1;
68 }
69 IDXL_List::IDXL_List(int otherchunk)
70 {
71         chunk=otherchunk;
72 }
73 IDXL_List::~IDXL_List() {}
74 void IDXL_List::pup(PUP::er &p)
75 {
76         p(chunk);
77         shared.pup(p);
78 }
79
80 /* IDXL_Side Itself: list the IDXL_Lists for all chunks
81 */
82 IDXL_Side::IDXL_Side(void) :cached_map(NULL) 
83 {}
84 IDXL_Side::~IDXL_Side() {
85         flushMap();
86 }
87 void IDXL_Side::pup(PUP::er &p)  //For migration
88 {
89         comm.pup(p);
90         // Cached_map need not be migrated
91 }
92
93 int IDXL_Side::total(void) const {
94         int ret=0;
95         for (int s=0;s<size();s++) ret+=comm[s]->size();
96         return ret;
97 }
98
99 IDXL_Map &IDXL_Side::getMap(void) {
100         if (cached_map) return *cached_map;
101         //Build cached_map from comm data:
102         cached_map=new IDXL_Map;
103         IDXL_Map &map=*cached_map;
104         for (int c=0;c<comm.size();c++) //Loop over chunks
105         for (int idx=0;idx<comm[c]->size();idx++) //Loop over shared entities
106                 map.add((*comm[c])[idx],comm[c]->getDest(),idx);
107         return map;
108 }
109 void IDXL_Side::flushMap(void) {
110         if (cached_map) {
111                 delete cached_map;
112                 cached_map=NULL;
113         }
114 }
115
116 const IDXL_Rec *IDXL_Side::getRec(int entity) const
117 {
118         //Cast away constness--cached_map should be declared "mutable"
119         IDXL_Side *writable=(IDXL_Side *)this; 
120         return writable->getMap().get(entity);
121 }
122
123 void IDXL_Side::add(int myChunk,int myLocalNo,
124          int hisChunk,int hisLocalNo,IDXL_Side &his)
125 {
126         IDXL_List *myList=getListN(hisChunk);
127         if (myList==NULL) 
128         {//These two chunks have never communicated before-- must add to both lists
129                 //Figure out our names in the other guy's table
130                 myList=new IDXL_List(hisChunk);
131                 IDXL_List *hisList=new IDXL_List(myChunk);
132                 comm.push_back(myList);
133                 his.comm.push_back(hisList);
134         }
135         IDXL_List *hisList=his.getListN(myChunk);
136         
137         //Add our local numbers to our lists
138         myList->push_back(myLocalNo);
139         hisList->push_back(hisLocalNo);
140         flushMap(); his.flushMap();
141 }
142
143 class IDXL_Identity_Map : public IDXL_Print_Map {
144         virtual void map(int srcIdx) const { 
145                 CkPrintf("%d  ",srcIdx);
146         }
147 };
148
149 void IDXL_Side::print(const IDXL_Print_Map *idxmap) const
150 {
151   IDXL_Identity_Map im;
152   if (idxmap==NULL) idxmap=&im;
153   CkPrintf("Communication list: %d chunks, %d total entries\n",size(),total());
154   for (int p=0;p<size();p++) {
155     const IDXL_List &l=getLocalList(p);
156     CkPrintf("     With %d:",l.getDest(),l.size());
157     for (int n=0;n<l.size();n++)
158       idxmap->map(l[n]);
159     CkPrintf("\n");
160   }
161 }
162
163
164