OpenAtom  Version1.5a
map.C
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////
2 //////////////////////////////////////////////////////////////////////////////
3 //////////////////////////////////////////////////////////////////////////////
4 /** \file map.C
5  *
6  * The maps are intended to spread load around evenly and keep plane
7  * and state objects which communicate across phases close together.
8 
9  * It basically uses this key idea pe = cumload / average_load so
10  * cumload depends on the object list traversal. For plane wise we
11  * traverse it plane wise and for state wise do it states in the
12  * first loop and planes in the second loop. For hybrid map, it
13  * partitions states and processors in to K partitions
14  * k = numpes/pesperstate so apply the cumulative load logic in each
15  * partition, and add the start pe of the partition to it
16 
17  * cumload is the cumulative load till that object average load
18  * is the total_load/numpes
19 
20  * Assuming object s1,p1 is being inserted s1 is a state and p1 is a
21  * plane the map will use a certain traversal through object space
22  * for state map it will traverse all objects state by state hence
23  * cumload = load_sum { s1 * numplanesperstate + p1} for gspace it
24  * will be a loop as each plane has a different load.
25  */
26 //////////////////////////////////////////////////////////////////////////////
27 //////////////////////////////////////////////////////////////////////////////
28 //////////////////////////////////////////////////////////////////////////////
29 
30 #include <cmath>
31 #include "charm++.h"
32 #include "ckarray.h"
33 #include "util.h"
34 #include "main/cpaimd.h"
35 #include "main/groups.h"
37 #include "cp_state_plane/CP_State_Plane.h"
38 
39 //////////////////////////////////////////////////////////////////////////////
40 
41 extern int sizeX;
42 extern Config config;
43 
44 ///void hackGSpacePlaneLoad(CPcharmParaInfo *sim,int idx, double *line_load,
45 /// double *pt_load);
46 void GSpacePlaneLoad(int , double *, double *);
47 
48 //////////////////////////////////////////////////////////////////////////////
49 
50 
51 //////////////////////////////////////////////////////////////////////////////
52 //////////////////////////////////////////////////////////////////////////////
53 //////////////////////////////////////////////////////////////////////////////
54 void GSMap::GSpacePlaneLoad(int idx, double *line_load, double *pt_load){
55 //////////////////////////////////////////////////////////////////////////////
56 
57  if( (idx < 0) || (idx >= nchareG) ){
58  CkPrintf("@@@@@@@@@@@@@@@@@@@@_error_@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
59  CkPrintf("GSpace plane index %d out of range: 0 < idx > %d\n",idx,nchareG);
60  CkPrintf("@@@@@@@@@@@@@@@@@@@@_error_@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
61  CkExit();
62  }//endif
63 
64  line_load[0] = lines_per_chareG[idx];
65  pt_load[0] = pts_per_chareG[idx];
66 
67 //////////////////////////////////////////////////////////////////////////////
68  }//end routine
69 //////////////////////////////////////////////////////////////////////////////
70 
71 
72 //////////////////////////////////////////////////////////////////////////////
73 //////////////////////////////////////////////////////////////////////////////
74 //////////////////////////////////////////////////////////////////////////////
75 void SCalcMap::GSpacePlaneLoad(int idx, double *line_load, double *pt_load){
76 //////////////////////////////////////////////////////////////////////////////
77 
78 
79  if( (idx < 0) || (idx >= nchareG) ){
80  CkPrintf("@@@@@@@@@@@@@@@@@@@@_error_@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
81  CkPrintf("GSpace plane index %d out of range: 0 < idx > %d\n",idx,nchareG);
82  CkPrintf("@@@@@@@@@@@@@@@@@@@@_error_@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
83  CkExit();
84  }//endif
85 
86  line_load[0] = lines_per_chareG[idx];
87  pt_load[0] = pts_per_chareG[idx];
88 
89 //////////////////////////////////////////////////////////////////////////////
90  }//end routine
91 //////////////////////////////////////////////////////////////////////////////
92 
93 
94 //////////////////////////////////////////////////////////////////////////////
95 //////////////////////////////////////////////////////////////////////////////
96 //////////////////////////////////////////////////////////////////////////////
97 /**
98  * Void allocate each state to more than one processor. Hybrid between
99  * state allocation and plane allocation
100  */
101 //////////////////////////////////////////////////////////////////////////////
102 int basicMap(CkArrayIndex2D &idx2d, int numPlanes) {
103 //////////////////////////////////////////////////////////////////////////////
104  int pes_per_state = config.RpesPerState;
105  int np = CkNumPes()/pes_per_state;
106 
107  if(np < 1)
108  np = 1;
109 
110  int partition_nstates = config.nstates / np;
111  if(config.nstates % np != 0)
112  partition_nstates ++;
113 
114  double total_planes = config.nstates * numPlanes;
115  double numPerProc = total_planes / CkNumPes();
116 
117  //My state in the current partition
118  int s = idx2d.index[0]%partition_nstates;
119 
120  int pe = (int) floor((idx2d.index[1]*partition_nstates + s)/numPerProc);
121 
122  pe = pe % pes_per_state;
123  pe += pes_per_state * (idx2d.index[0]/partition_nstates);
124 
125  if(pe >= CkNumPes())
126  pe = pe % CkNumPes();
127 
128  return pe;
129 //////////////////////////////////////////////////////////////////////////////
130  }// end routine
131 //////////////////////////////////////////////////////////////////////////////
132 
133 
134 //////////////////////////////////////////////////////////////////////////////
135 //////////////////////////////////////////////////////////////////////////////
136 //////////////////////////////////////////////////////////////////////////////
137 /**
138  * The next two functions are needed to implement a mapping strategy different
139  * from the default strategy.
140  */
141 //////////////////////////////////////////////////////////////////////////////
142 void GSMap::makemap(){
143 //////////////////////////////////////////////////////////////////////////////
144  int numChareG=0;
145  if(config.doublePack)
146  numChareG = nchareG;
147  else
148  CkAbort("not doublepack broken!");
149 
150  for(int state = 0; state < config.nstates; state++){
151  for (int plane = 0; plane < numChareG; plane++) {
152  CkArrayIndex2D idx2d(state,plane);
153  }
154  }
155 }
156 //////////////////////////////////////////////////////////////////////////////
157 
158 
159 //////////////////////////////////////////////////////////////////////////////
160 //////////////////////////////////////////////////////////////////////////////
161 //////////////////////////////////////////////////////////////////////////////
162 ///int GSMap::slowprocNum(int arrayHdl, const CkArrayIndex2D &idx2d)
163 //////////////////////////////////////////////////////////////////////////////
164 int GSMap::procNum(int arrayHdl, const CkArrayIndex &idx){
165 //////////////////////////////////////////////////////////////////////////////
166 
167  CkArrayIndex2D idx2d = *(CkArrayIndex2D *) &idx;
168 
169  int pe = 0;
170  int numChareG = 0;
171 
172  if(config.doublePack) {
173  numChareG = nchareG;
174  }else{
175  CkAbort("not doublepack broken\n");
176  }//endif
177 
178  if(state_load <= 0.0 ) {
179  for(int x = 0; x < numChareG; x++) {
180  double curload = 0.0;
181  double sload = 0.0;
182 
183  GSpacePlaneLoad(x, &curload, &sload);
184 
185  state_load += curload;
186  }//endfor
187  }//endif
188 
189  int pes_per_state = config.GpesPerState;
190  int np = CkNumPes()/pes_per_state;
191 
192  if(np < 1){np = 1;}
193 
194  int partition_nstates = config.nstates / np;
195  if(config.nstates % np != 0){partition_nstates ++;}
196 
197  int start_pe = (idx2d.index[0]/partition_nstates) * pes_per_state;
198  int start_state = (idx2d.index[0]/partition_nstates) * partition_nstates;
199 
200  double cum_load = 0.0;
201  double average_load = state_load * config.nstates / CkNumPes();
202 
203  for(int x = 0; x < numChareG; x++) {
204  for(int s = 0; s < partition_nstates; s++) {
205  double curload = 0.0;
206  double sload = 0.0;
207 
208  GSpacePlaneLoad(x, &curload, &sload);
209 
210  cum_load += curload;
211 
212  if((idx2d.index[0] == s + start_state) && idx2d.index[1] == x) {
213  double dpe = 0.0;
214  dpe = cum_load / average_load;
215 
216  pe = (int)dpe;
217  pe = pe % pes_per_state;
218  pe += start_pe;
219 
220  return (pe % CkNumPes());
221  }//endif
222  }//endfor
223  }//endfor
224  return (idx2d.index[0]*1037+idx2d.index[1])%CkNumPes();
225 
226 //////////////////////////////////////////////////////////////////////////////
227  }//end routine
228 //////////////////////////////////////////////////////////////////////////////
229 
230 
231 //////////////////////////////////////////////////////////////////////////////
232 //////////////////////////////////////////////////////////////////////////////
233 //////////////////////////////////////////////////////////////////////////////
234 int RSMap::procNum(int arrayHdl, const CkArrayIndex &idx){
235  CkArrayIndex2D idx2d = *(CkArrayIndex2D *) &idx;
236 
237  int numPlanes = 0;
238  numPlanes = sizeX;
239 
240  int pe = 0;
241 
242  double total_planes = config.nstates * numPlanes;
243  double planes_per_proc = total_planes / CkNumPes();
244 
245  pe = basicMap(idx2d, numPlanes);
246  return pe;
247 }
248 //////////////////////////////////////////////////////////////////////////////
249 
250 
251 //////////////////////////////////////////////////////////////////////////////
252 //////////////////////////////////////////////////////////////////////////////
253 //////////////////////////////////////////////////////////////////////////////
254 inline double scalc_load(int x, int numplanes, double *load) {
255  *load = numplanes * numplanes - x*x;
256  return *load;
257 }
258 //////////////////////////////////////////////////////////////////////////////
259 
260 
261 //////////////////////////////////////////////////////////////////////////////
262 /**
263  * this one uses a lookup table built by calling the slow version
264  */
265 //////////////////////////////////////////////////////////////////////////////
266 //////////////////////////////////////////////////////////////////////////////
267 //////////////////////////////////////////////////////////////////////////////
268 int SCalcMap::procNum(int hdl, const CkArrayIndex &idx){
269  CkArrayIndex4D &idx4d = *(CkArrayIndex4D *)&idx;
270  int intidx[2];
271  CmiMemcpy(intidx,idx4d.index,2*sizeof(int)); // our 4 shorts are now 2 ints
272  if(maptable==NULL){
273  int calcchunks=max_states/gs;
274  maptable= new CkHashtableT<intdual,int> (nchareG*calcchunks*calcchunks);
275  // times blkSize, but its always 1
276  makemap();
277  }//endif
278  return maptable->get(intdual(intidx[0], intidx[1]));
279 }
280 //////////////////////////////////////////////////////////////////////////////
281 
282 //////////////////////////////////////////////////////////////////////////////
283 //////////////////////////////////////////////////////////////////////////////
284 //////////////////////////////////////////////////////////////////////////////
285 void SCalcMap::makemap(){
286 
287  if(symmetric){
288 
289  for(int numX = 0; numX < nchareG; numX++){
290  for (int s1 = 0; s1 < max_states; s1 += gs) {
291  for (int s2 = s1; s2 < max_states; s2 += gs) {
292  CkArrayIndex4D idx4d(numX,s1,s2,0);
293  int intidx[2];
294  CmiMemcpy(intidx,idx4d.index,2*sizeof(int)); // our 4 shorts are now 2 ints
295  maptable->put(intdual(intidx[0],intidx[1]))=slowprocNum(0,idx4d);
296  }//endfor
297  }//endfor
298  }//endfor
299 
300  }else{
301 
302  for(int numX = 0; numX < nchareG; numX++){
303  for (int s1 = 0; s1 < max_states; s1 += gs) {
304  for (int s2 = 0; s2 < max_states; s2 += gs) {
305  CkArrayIndex4D idx4d(numX,s1,s2,0);
306  int intidx[2];
307  CmiMemcpy(intidx,idx4d.index,2*sizeof(int)); // our 4 shorts now 2 ints
308  maptable->put(intdual(intidx[0],intidx[1]))=slowprocNum(0,idx4d);
309  }//endfor
310  }//endfor
311  }//endfor
312 
313  }//endif
314 
315 //////////////////////////////////////////////////////////////////////////////
316  }//end routine
317 //////////////////////////////////////////////////////////////////////////////
318 
319 int SCalcMap::slowprocNum2(int hdl, const CkArrayIndex4D &idx4d){
320  short *idx = reinterpret_cast<short*> ( idx4d.data() );
321  // Just use gspace as our guide for (w,x,y,z) use gsp(y+x/grainsize,w);
322  return cheesyhackgsprocNum(CPcharmParaInfo::get();, idx[2] + idx[3]/gs, idx[0]);
323 }
324 
325 /*
326 //////////////////////////////////////////////////////////////////////////////
327 //////////////////////////////////////////////////////////////////////////////
328 //////////////////////////////////////////////////////////////////////////////
329 int SCalcMap::slowprocNum(int hdl, const CkArrayIndex4D &idx4d){
330 //////////////////////////////////////////////////////////////////////////////
331 /// CkArrayIndex4D &idx4d = *(CkArrayIndex4D *)&idx;
332 /// CkPrintf("scalc map call for [%d %d %d %d] on pe %d\n",
333 /// idx4d.index[0],idx4d.index[1],idx4d.index[2],idx4d.index[3],CkMyPe());
334 //////////////////////////////////////////////////////////////////////////////
335 #if CMK_TRACE_ENABLED
336  double StartTime=CmiWallTimer();
337 #endif
338  //Here maxY is the max number of planes;
339  int planeid = idx4d.index[0];
340  int numChareG = 0;
341 
342  if(config.doublePack){
343  numChareG = config.nchareG;
344  }else{
345  numChareG = max_planes/2;
346  }//endif
347 
348  //for asymetric
349  double *load = new double[CkNumPes()];
350  memset(load, 0, CkNumPes() * sizeof(double));
351 
352  int w=0, x=0, y = 0;
353 
354  if(totalload <= 0.0) {
355  for(w = 0; w < numChareG; w ++)
356  for(x = 0; x < max_states; x += gs) {
357  if (symmetric){
358  y = x;
359  }else{
360  y = 0;
361  }//endif
362 
363  for(; y < max_states; y += gs) {
364 
365  double curload = 0.0;
366  double gload = 0.0;
367 
368  //scalc_load(w, numChareG, &curload);
369  GSpacePlaneLoad(w, &gload, &curload);
370 
371  totalload += curload;
372  }//endfor
373  }//endfor
374  }//endif
375 
376  int pe = 0;
377 
378  for(w = 0; w < numChareG; w ++) {
379  for(x = 0; x < max_states; x += gs){
380  if (symmetric){
381  y = x;
382  }else{
383  y = 0;
384  }//endif
385 
386  for(; y < max_states; y += gs) {
387  double curload = 0.0;
388  double gload = 0.0;
389 
390  //scalc_load(w, numChareG, &curload);
391  GSpacePlaneLoad(w, &gload, &curload);
392 
393  curload /= totalload;
394 
395  if(load[pe] + curload > 0.3/CkNumPes()){pe ++;}
396 
397  if(pe >= CkNumPes()){pe = 0;}
398 
399  load[pe] += curload;
400 
401  if((w == idx4d.index[0]) && (x == idx4d.index[1]) &&
402  (y == idx4d.index[2])) {
403 #if CMK_TRACE_ENABLED
404  traceUserBracketEvent(Scalcmap_, StartTime, CmiWallTimer());
405 #endif
406  delete [] load;
407  return pe;
408  }//endif
409  }//endfor
410  }//endfor
411  }//endfor : w
412 
413  delete [] load;
414 #if CMK_TRACE_ENABLED
415  traceUserBracketEvent(Scalcmap_, StartTime, CmiWallTimer());
416 #endif
417 
418 //////////////////////////////////////////////////////////////////////////////
419  return (idx4d.index[0]*197+idx4d.index[1]*23+idx4d.index[2]*7
420  +idx4d.index[3])%CkNumPes();
421 //////////////////////////////////////////////////////////////////////////////
422  }//end routine
423 //////////////////////////////////////////////////////////////////////////////
424 */
425 
426 
427 int SCalcMap::slowprocNum(int hdl, const CkArrayIndex4D &idx4d)
428 {
429  short *idx = reinterpret_cast<short*> ( idx4d.data() );
430 
431  //Here maxY is the max number of planes;
432  int planeid = idx[0];
433  int numChareG = 0;
434 
435 
436  if(config.doublePack){
437  numChareG = config.nchareG;
438  }else{
439  numChareG = max_planes/2;
440  }//endif
441 
442  //for asymetric
443  double *load = new double[CkNumPes()];
444  memset(load, 0, CkNumPes() * sizeof(double));
445 
446  int w=0, x=0, y = 0;
447 
448  if(totalload <= 0.0) {
449  for(w = 0; w < numChareG; w ++)
450  for(x = 0; x < max_states; x += gs) {
451  if (symmetric)
452  y = x;
453  else
454  y = 0;
455 
456  for(; y < max_states; y += gs) {
457 
458  double curload = 0.0;
459  double gload = 0.0;
460 
461  //scalc_load(w, numChareG, &curload);
462  GSpacePlaneLoad(w, &gload, &curload);
463 
464  totalload += curload;
465  }
466  }
467  }
468 
469  int pe = 0;
470 
471  for(w = 0; w < numChareG; w ++)
472  for(x = 0; x < max_states; x += gs) {
473  if (symmetric)
474  y = x;
475  else
476  y = 0;
477 
478  for(; y < max_states; y += gs) {
479  double curload = 0.0;
480  double gload = 0.0;
481 
482  //scalc_load(w, numChareG, &curload);
483  GSpacePlaneLoad(w, &gload, &curload);
484 
485  curload /= totalload;
486 
487  if(load[pe] + curload > 0.3/CkNumPes())
488  pe ++;
489 
490  if(pe >= CkNumPes())
491  pe = 0;
492 
493  load[pe] += curload;
494 
495  if((w == idx[0]) && (x == idx[1]) && (y == idx[2])) {
496 
497  //if(CkMyPe() == 0)
498  // CkPrintf ("scalc %d %d %d %d assigned to pe %d and curload = %f, load = %f\n", w, x ,y, symmetric, pe, curload, load[pe]);
499 
500  delete [] load;
501  return pe;
502  }
503  }
504  }
505 
506  delete [] load;
507  return (idx[0]*197+idx[1]*23+idx[2]*7+idx[3])%CkNumPes();
508 
509 }
510 
511 
int procNum(int, const CkArrayIndex &iIndex)
this one uses a lookup table built by calling the slow version
Definition: pcMaps.h:27
Add type declarations for simulationConstants class (readonly vars) and once class for each type of o...
int procNum(int, const CkArrayIndex &iIndex)
int GSMap::slowprocNum(int arrayHdl, const CkArrayIndex2D &idx2d)
Definition: cpaimd.h:315
Some basic data structures and the array map classes are defined here.
int procNum(int, const CkArrayIndex &iIndex)
Function for RealSpace objects.
Definition: cpaimd.h:371
void GSpacePlaneLoad(int, double *, double *)
void hackGSpacePlaneLoad(CPcharmParaInfo *sim,int idx, double *line_load, double *pt_load); ...
Definition: map.C:54
int basicMap(CkArrayIndex2D &idx2d, int numPlanes)
Void allocate each state to more than one processor.
Definition: map.C:102