OpenAtom  Version1.5a
PeList.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7 
8 /** \file PeList.h
9  * Author: Eric J Bohm
10  * Date Created: May 31, 2006
11  *
12  * Supports lists of processors which can be sorted by various
13  * criteria, such as distance or latency. + and - operators are
14  * supported provide union and disjoint operations.
15  *
16  * Implemented on ckvec.
17  * Used to find the nearest available processor from a given processor.
18  * Uses TopoManager for hopcount sorting if available.
19  */
20 
21 /** \ingroup mapping
22  *
23  */
24 //@{
25 #ifndef _PELIST_H
26 #define _PELIST_H
27 
28 #include <cmath>
29 #include "configure.h"
30 #include "TopoManager.h"
31 #include "cklists.h"
32 
33 class PeList
34 {
35  public:
36  int *TheList;
37  int *sortIdx;
38  int current;
39  int size;
40  bool sorted; // if pe list is kept in sorted order we can bin search it
41  PeList(); //default constructor
42 
43  // boxy constructor for Torus machines
44  PeList(int boxX, int boxY, int boxZ, int order, int maxX, int maxY, int maxZ, int maxT);
45 
46  PeList(int _size): size(_size)
47  {
48  sorted=true;
49  TheList = new int [size+1];
50  sortIdx = new int [size+1];
51  for(int i=0;i<size;i++)
52  {
53  TheList[i]=i;
54  sortIdx[i]=i;
55  }
56  current=0;
57  }
58 
59 
60  PeList(CkVec <int> inlist)
61  {
62  inlist.quickSort();
63  sorted=true;
64  current=0;
65  size=inlist.size();
66  TheList = new int [size+1];
67  sortIdx = new int [size+1];
68  TheList[0]=inlist[0];
69  int count=0;
70  for(int i=1;i<inlist.size();i++)
71  { //remove duplicates from sorted list
72  if(inlist[i]!=TheList[count])
73  {
74  count++;
75  TheList[count]=inlist[i];
76  sortIdx[count]=count;
77  }
78 
79  }
80  size=count;
81  }
82 
83  PeList(PeList &inlist)
84  {
85  CmiAssert(inlist.size > 0);
86  size=inlist.size;
87  sorted=inlist.sorted;
88  TheList = new int [size+1];
89  sortIdx = new int [size+1];
90  for(int i=0;i<inlist.size;i++)
91  {
92  TheList[i]=inlist.TheList[i];
93  sortIdx[i]=inlist.sortIdx[i];
94  }
95  current=inlist.current;
96  }
97 
98 
99  PeList(int _size, int *a)
100  {
101  sorted=false;
102  current=0;
103  size=_size;
104  TheList=new int [size+1];
105  sortIdx=new int [size+1];
106  for(int i=0;i<size;i++)
107  {
108  TheList[i]=a[i];
109  sortIdx[i]=i;
110  }
111  } // use an array to construct
112 
113  PeList(PeList *a, int start, int _size)
114  {
115  sorted=false;
116  CkAssert(start<a->size);
117  CkAssert(_size<=a->size);
118  size=_size;
119  current=0;
120  TheList=new int [size+1];
121  sortIdx=new int [size+1];
122  for(int i=0;i<size;i++)
123  {
124  TheList[i]=a->TheList[a->sortIdx[i+start]];
125  }
126  reindex();
127  }; // make a copy of a sublist
128 
129  // given the max grid/torus dimenions and the volume of a desired subpartition
130 
131  inline bool noPes()
132  {
133  return(size-current<1);
134  }
135 
136  inline int count() { return(size-current); }
137 
138  inline void reindex(){
139  for(int ri=0;ri<size;ri++)
140  sortIdx[ri]=ri;
141  current=0;
142  }
143  inline int exists(int target)
144  {
145  for(int i=0;i<size;i++)
146  if(TheList[i]==target)
147  return i;
148  return -1;
149  }
150  void rebuild();
151 
152  void reset(){current=0;}
153 
154  //! return a processor at minumum distance from source
155  int minDist(int source);
156 
157  void resort(){ sortSource(TheList[0]); };
158 
159  void append(PeList &inlist)
160  {
161  // make array large enough for both, paste together
162  int newsize=inlist.size+size;
163  int *newlist= new int [newsize+1];
164  int *newIndex= new int [newsize+1];
165  int i=0;
166  for(; i< size ; i++)
167  {
168  newlist[i]=TheList[i];
169  newIndex[i]=sortIdx[i];
170  }
171  for(int j=0; (i< newsize && j<inlist.size) ; i++,j++)
172  {
173  newlist[i]=inlist.TheList[j];
174  newIndex[i]=i;
175  }
176  size=newsize;
177  delete [] TheList;
178  delete [] sortIdx;
179  TheList=newlist;
180  sortIdx=newIndex;
181  }
182 
183  bool binsearch(int pe);
184 
185  inline bool find(int pe)
186  {
187  bool found=false;
188  if(sorted)
189  { // bin search
190  found=binsearch(pe);
191  }
192  else // brute
193  {
194  int i=0;
195  while(!found && i< size)
196  {
197  if(TheList[i]==pe)
198  {
199  found=true;
200  }
201  i++;
202  }
203  }
204  return(found);
205  }
206 
207  int *pelower_bound(int pe);
208 
209  inline void mergeOne(int pe)
210  {
211 
212  // make array large enough for both, paste together
213  if(sorted)
214  { // maintain sort order by insertion
215  if(size==1 && pe>TheList[0])
216  {
217  appendOne(pe);
218  }
219  else{
220  int *loc=pelower_bound(pe);
221  int location=loc-TheList;
222 
223  if(location>=size || loc==NULL)
224  { //
225  appendOne(pe);
226  }
227  else if ((loc>TheList) && (loc[-1] ==pe))
228  {
229  // do nothing
230  }
231  else if(TheList[location] ==pe)
232  {
233  // do nothing
234  }
235 
236  else if((size>1) &&(location<size-1) && (TheList[location+1]==pe))
237  {
238  // do nothing
239  }
240  else
241  { // not already present
242 
243  int newsize=size+1;
244  int *newlist= new int [newsize+1];
245  int *newIndex= new int [newsize+1];
246  if(loc!=TheList) // there are things before location
247  CmiMemcpy(newlist,TheList,location*sizeof(int));
248  newlist[location]=pe;
249  CmiMemcpy(&newlist[location+1],loc,(size-(location))*sizeof(int));
250  // your index is shot
251  bzero(newIndex,(newsize+1)*sizeof(int));
252  delete [] TheList;
253  delete [] sortIdx;
254  TheList=newlist;
255  sortIdx=newIndex;
256  size=newsize;
257  current=0;
258  }
259  }
260  }
261  else
262  {
263  bool found=find(pe);
264  if(!found)
265  {
266  appendOne(pe);
267  }
268  }
269  }
270 
271  inline void appendOne(int pe)
272  {
273  int newsize=size+1;
274  int *newlist= new int [newsize+1];
275  int *newIndex= new int [newsize+1];
276  CmiMemcpy(&newlist[0],&TheList[0],sizeof(int)*size);
277  CmiMemcpy(&newIndex[0],&sortIdx[0],sizeof(int)*size);
278  newlist[size]=pe;
279  newIndex[size]=size;
280  size=newsize;
281  delete [] TheList;
282  delete [] sortIdx;
283  TheList=newlist;
284  sortIdx=newIndex;
285  }
286 
287  int findNext(); // return next available, increment liststart
288 
289  void sortSource(int srcPe); // implementation depends on BG/L or not
290 
291  PeList &operator=(PeList &inlist) {TheList=inlist.TheList; sortIdx=inlist.sortIdx;return *this;}
292 
293 
294  // need to rebuild your sortIdx after set union
295  inline PeList &operator+(PeList &inlist) {
296  // make array large enough for both, paste together
297  int newsize=inlist.size+size;
298  int *newlist= new int [newsize];
299  int *newIndex= new int [newsize];
300  int i=0;
301  for(; i< size ; i++)
302  {
303  newlist[i]=TheList[i];
304  newIndex[i]=sortIdx[i];
305  }
306  for(int j=0; (i< newsize &j<inlist.size); i++)
307  {
308  newlist[i]=inlist.TheList[j];
309  newIndex[i]=i;
310  }
311  size=newsize;
312  delete [] TheList;
313  delete [] sortIdx;
314  TheList=newlist;
315  sortIdx=newIndex;
316  return *this;
317  }
318 
319  // need to rebuild your sortIdx after unary set difference
320  inline PeList &operator-(PeList &inlist) {
321  for(int i=0; i< inlist.size;i++)
322  {
323  int j=0;
324  while(j< size)
325  if(TheList[j]==inlist.TheList[i])
326  {
327  remove(j);
328  // CkPrintf("removed %d containing %d leaving %d\n",i,inlist.TheList[i], size);
329 
330  }
331  else
332  {
333  j++;
334  }
335  }
336  current=0; // your index is useless now anyway
337  return *this;
338  }
339 
340  inline void remove(int pos)
341  {
342  if(pos < size)
343  {
344 
345  for (int i=pos; i<size-1; i++)
346  {
347  TheList[i] = TheList[i+1];
348  }
349 
350  // CmiMemcpy(&TheList[pos],&TheList[pos+1],(size-(pos+1))*sizeof(int));
351  size--;
352  }
353  }
354 
355  void trimUsed()
356  {
357  // build a new array that doesn't include used elements
358  // theoretically this could be done in place, but haste makes waste
359  if(current>0 && size>0)
360  {
361  if(noPes())
362  {
363  size=0;
364  current=0;
365  }
366  else
367  {
368  int newSize= size-current;
369  int *newList = new int[newSize+1];
370  int *newSortIdx = new int[newSize+1];
371  for(int i=0; i<newSize;i++)
372  {
373  // if we just copy in sorted order we end up with a sorted list
374  newSortIdx[i]=i;
375  newList[i]=TheList[sortIdx[i+current]];
376  }
377  delete [] TheList;
378  delete [] sortIdx;
379  TheList=newList;
380  sortIdx=newSortIdx;
381  current=0;
382  size=newSize;
383  }
384  }
385  }
386 
387  void removeIdx(int pos)
388  {
389  if(pos < size)
390  {
391  for (int i=pos; i<size-1; i++)
392  {
393  sortIdx[i] = sortIdx[i+1];
394  }
395  size--;
396  }
397  }
398  void dump()
399  {
400  CkPrintf("PeList\n");
401  for(int j=0; j< size;j++)
402  CkPrintf("%d list %d sortidx %d \n",j,TheList[j], sortIdx[j]);
403  }
404  ~PeList(){
405  if(TheList !=NULL)
406  delete [] TheList;
407  if(sortIdx !=NULL)
408  delete [] sortIdx;
409 
410  }
411 
412 
413 };
414 
415 
416 /**
417  * Hacky solution to passing a PeList to GSpace(0,0) for use in paircalc mapping
418  * without actually having to pup the arrays in a PeList
419  *
420  * Written without any global knowledge of the mapping code
421  * I am puking as I write this, but let my disgust at myself exonerate me
422  */
424 {
425  public:
426  /// Default constructor
428  {
429  CkAbort("I hate that we end up in this function");
430  }
431 
432 
433  PeListFactory(int _size):
434  useDefault(true),
435  boxX(0), boxY(0), boxZ(0), order(0),
436  maxX(0), maxY(0), maxZ(0), maxT(0), size(_size)
437  {}
438 
439  /// Use this constructor when you want a PeList created using its boxy constructor
440  PeListFactory(int bxX, int bxY, int bxZ, int ordr, int mxX, int mxY, int mxZ, int mxT):
441  useDefault(false),
442  boxX(bxX), boxY(bxY), boxZ(bxZ), order(ordr),
443  maxX(mxX), maxY(mxY), maxZ(mxZ), maxT(mxT)
444  { CkAbort("how the fuck did we get here?");}
445 
446 
447  /// Return an appropriately constructed PeList
449  {
450  if (useDefault)
451  return new PeList(size);
452  else
453  return new PeList(boxX, boxY, boxZ, order, maxX, maxY, maxZ, maxT);
454  }
455 
456  private:
457  // Should I return a default PeList or a boxy PeList
458  bool useDefault;
459  // Parameters used to create a boxy PeList. Refer PeList code for more details
460  int boxX, boxY, boxZ, order, maxX, maxY, maxZ, maxT, size;
461 };
462 PUPbytes(PeListFactory)
463 
464 //@}
465 #endif
PeListFactory(int bxX, int bxY, int bxZ, int ordr, int mxX, int mxY, int mxZ, int mxT)
Use this constructor when you want a PeList created using its boxy constructor.
Definition: PeList.h:440
Definition: PeList.h:33
Hacky solution to passing a PeList to GSpace(0,0) for use in paircalc mapping without actually having...
Definition: PeList.h:423
int minDist(int source)
return a processor at minumum distance from source
Definition: PeList.C:201
PeList * operator()() const
Return an appropriately constructed PeList.
Definition: PeList.h:448
PeListFactory()
Default constructor.
Definition: PeList.h:427