OpenAtom  Version1.5a
orthoBuilder.C
1 #include "orthoBuilder.h"
2 #include "orthoMap.h"
3 #include "CLA_Matrix.h"
4 
5 #include "paircalc/pcMaps.h"
6 #include "main/TimeKeeper.h"
7 #include "utility/MapFile.h"
8 #include "ortho.decl.h"
9 
10 #include "ckmulticast.h"
11 /** @addtogroup Ortho
12  @{
13 */
14 
15 namespace cp {
16  namespace ortho {
17 
18 /// Hacky way to allow Ortho builders of each instance to access the maptable for instance 0 pc
19 namespace impl { MapType2 *dirtyGlobalMapTable4Ortho, *dirtyGlobalMapTable4OrthoHelper; }
20 
21 /**
22  * Create the map objects and also all the chare arrays needed for an Ortho instance
23  */
24 CkArrayID Builder::build(cp::paircalc::InstanceIDs &asymmHandle, const startup::PCMapConfig mapCfg)
25 {
26  CkPrintf("Building Ortho Chares\n");
27 
28  // For using the multicast library : Set some reduction clients
29  /// MulticastMgr that handles CLA_Matrix collectives
30  CkGroupID mCastGID;
31  /// MulticastMgr that handles Ortho --> PC mcasts
32  CkGroupID orthoMcastGID;
33  /// MulticastMgr that handles PC --> Ortho redns
34  CkGroupID orthoRedGID;
35  /// The step 2 helper chare array proxy
36  CProxy_OrthoHelper orthoHelperProxy;
37  /// The step 2 helper chare AID to pass to ortho
38  CkArrayID helperAID;
39  /// The step 2 helper map logic object
40  MapType2 helperMapTable;
41 
42  PeList *availGlobR = mapCfg.getPeList();
43 
44  //-------------------------------------------------------------------------
45  // Create maps for placing the Ortho chare array elements
46 
47  PeList *excludePes= new PeList(1);
48  excludePes->TheList[0]=config.numPes;
49  int nOrtho= (cfg.numStates/cfg.grainSize);
50  nOrtho *= nOrtho;
51  double Timer=CmiWallTimer();
52 
53  availGlobR->reset();
54  PeList *avail= new PeList();
55  MapType2 orthoMapTable;
56  if (cfg.instanceIndex == 0)
57  {
58  orthoMapTable.buildMap(cfg.numStates/cfg.grainSize, cfg.numStates/cfg.grainSize);
59 
60  int success = 0;
61  if(config.loadMapFiles)
62  {
63  int size[2];
64  size[0] = size[1] = cfg.numStates/cfg.grainSize;
65  MapFile *mf = new MapFile("OrthoMap", 2, size, config.numPes, "TXYZ", 2, 1, 1, 1);
66  success = mf->loadMap("OrthoMap", &orthoMapTable);
67  delete mf;
68  }
69  if(success == 0)
70  {
71  SCalcMap *asymmMap = CProxy_SCalcMap(asymmHandle.mapperGID).ckLocalBranch();
72  MapType4 *maptable = asymmMap->getMapTable();
73  OrthoMapTable Otable = OrthoMapTable(&orthoMapTable, avail, cfg.numStates, cfg.grainSize, maptable, config.nchareG, config.numChunks, config.sGrainSize, excludePes);
74  }
75 
76  // Save a globally visible handle to the mapTable that builders of other ortho instances can access
77  impl::dirtyGlobalMapTable4Ortho = new MapType2(orthoMapTable);
78  }
79  // else, simply translate the instance 0 ortho map
80  else
81  {
82  int x = mapCfg.mapOffset.getx();
83  int y = mapCfg.mapOffset.gety();
84  int z = mapCfg.mapOffset.getz();
85  if((CkNumPes()==1) && !mapCfg.isTorusFake)
86  orthoMapTable = *impl::dirtyGlobalMapTable4Ortho;
87  else
88  orthoMapTable.translate(impl::dirtyGlobalMapTable4Ortho, x, y, z, mapCfg.isTorusMap);
89  }
90 
91  double newtime=CmiWallTimer();
92  CkPrintf("OrthoMap created in %g\n\n", newtime-Timer);
93 
94  // If map files need to be dumped
95  if(config.dumpMapFiles)
96  {
97  int size[2];
98  size[0] = size[1] = cfg.numStates/cfg.grainSize;
99  MapFile *mf = new MapFile("OrthoMap", 2, size, config.numPes, "TXYZ", 2, 1, 1, 1);
100  mf->dumpMap(&orthoMapTable, cfg.instanceIndex);
101  delete mf;
102  }
103 
104  // If the map coordinates need to be dumped
105  if(config.dumpMapCoordFiles)
106  {
107  int size[2];
108  size[0] = size[1] = cfg.numStates/cfg.grainSize;
109  MapFile *mf = new MapFile("OrthoMap_coord", 2, size, config.numPes, "TXYZ", 2, 1, 1, 1);
110  mf->dumpMapCoords(&orthoMapTable, cfg.instanceIndex);
111  delete mf;
112  }
113 
114  // Create the ortho map group
115  CProxy_OrthoMap orthoMap = CProxy_OrthoMap::ckNew(orthoMapTable);
116  CkArrayOptions orthoOpts;
117  orthoOpts.setMap(orthoMap);
118  orthoOpts.setStaticInsertion(true);
119  orthoOpts.setAnytimeMigration(false);
120  CProxy_Ortho orthoProxy = CProxy_Ortho::ckNew(orthoOpts);
121 
122 
123 
124  // Create maps for the Ortho helper chares
125  if(config.useOrthoHelpers)
126  {
127  double Timer=CmiWallTimer();
128 
129  if (cfg.instanceIndex == 0)
130  {
131  helperMapTable.buildMap(cfg.numStates/cfg.grainSize, cfg.numStates/cfg.grainSize);
132  int success = 0;
133  if(config.loadMapFiles)
134  {
135  int size[2];
136  size[0] = size[1] = cfg.numStates/cfg.grainSize;
137  MapFile *mf = new MapFile("OrthoHelperMap", 2, size, config.numPes, "TXYZ", 2, 1, 1, 1);
138  success = mf->loadMap("OrthoHelperMap", &helperMapTable);
139  delete mf;
140  }
141 
142  if(success == 0)
143  {
144  OrthoHelperMapTable OHtable = OrthoHelperMapTable(&helperMapTable, cfg.numStates, cfg.grainSize, &orthoMapTable, avail, excludePes);
145  }
146  // Save a globally visible handle to the mapTable that builders of other ortho instances can access
147  impl::dirtyGlobalMapTable4OrthoHelper = new MapType2(orthoMapTable);
148  }
149  else
150  {
151  int x = mapCfg.mapOffset.getx();
152  int y = mapCfg.mapOffset.gety();
153  int z = mapCfg.mapOffset.getz();
154  if((CkNumPes()==1) && !mapCfg.isTorusFake)
155  helperMapTable = *impl::dirtyGlobalMapTable4OrthoHelper;
156  else
157  helperMapTable.translate(impl::dirtyGlobalMapTable4OrthoHelper, x, y, z, mapCfg.isTorusMap);
158  }
159 
160  double newtime=CmiWallTimer();
161  CkPrintf("OrthoHelperMap created in %g\n", newtime-Timer);
162  CProxy_OrthoHelperMap orthoHMap = CProxy_OrthoHelperMap::ckNew(helperMapTable);
163  CkArrayOptions orthoHOpts;
164  orthoHOpts.setMap(orthoHMap);
165  orthoHelperProxy = CProxy_OrthoHelper::ckNew(orthoHOpts);
166  helperAID = orthoHelperProxy.ckGetArrayID();
167 
168  if(config.dumpMapFiles)
169  {
170  int size[2];
171  size[0] = size[1] = cfg.numStates/cfg.grainSize;
172  MapFile *mf = new MapFile("OrthoHelperMap", 2, size, config.numPes, "TXYZ", 2, 1, 1, 1);
173  mf->dumpMap(&helperMapTable, cfg.instanceIndex);
174  delete mf;
175  }
176 
177  if(config.dumpMapCoordFiles)
178  {
179  int size[2];
180  size[0] = size[1] = cfg.numStates/cfg.grainSize;
181  MapFile *mf = new MapFile("OrthoHelperMap_coord", 2, size, config.numPes, "TXYZ", 2, 1, 1, 1);
182  mf->dumpMapCoords(&helperMapTable, cfg.instanceIndex);
183  delete mf;
184  }
185  }
186 
187  //-------------------------------------------------------------------------
188  // Delegate collectives within the ortho array
189  #ifdef USE_COMLIB
190  Strategy *multistrat = new DirectMulticastStrategy();
191  orthoInstance=ComlibRegister(multistrat);
192  // ComlibAssociateProxy(orthoInstance, orthoProxy);
193  #endif
194 
195  // Set the root of array reductions within Ortho
196  CkCallback ocb= CkCallback(CkIndex_Ortho::collect_error(NULL), orthoProxy(0, 0));
197  orthoProxy.ckSetReductionClient(&ocb);
198 
199  // Each multiplier calls ortho back to notify that its ready
200  CkCallback ortho_ready_cb = CkCallback(CkIndex_Ortho::all_ready(), orthoProxy(0, 0));
201  // The multicast group that will handle CLA_Matrix collectives
202  mCastGID = CProxy_CkMulticastMgr::ckNew(config.numMulticastMsgs);
203 
204  /// Create multicast manager groups for Ortho to use
205  orthoMcastGID = (CProxy_CkMulticastMgr::ckNew(config.OrthoMcastSpanFactor));
206  orthoRedGID = (CProxy_CkMulticastMgr::ckNew(config.OrthoRedSpanFactor));
207 
208  //-------------------------------------------------------------------------
209  // Create matrix multiplication objects
210 
211  // extra triangle ortho elements are really a waste of our time
212  // and resources, but we don't have a triangular solver for
213  // inv_square, so we'll just make do.
214  // They need to exist solely so that the inv_sq method can work.
215  // So we need to copy their mirror elements data into them.
216  // then when complete they need to know not to call finishpaircalc.
217  // Because their redundant data has nowhere to go.
218  // We've made use of them anyway to handle: lambda reduction, the
219  // gamma multiply, and communication balancing for phantoms, so they
220  // aren't completely horrible.
221 
222  CLA_Matrix_interface matA1, matB1, matC1;
223  CLA_Matrix_interface matA2, matB2, matC2;
224  CLA_Matrix_interface matA3, matB3, matC3;
225 
226  make_multiplier(&matA1, &matB1, &matC1,
227  orthoProxy, orthoProxy, orthoProxy,
230  1, 1, 1,
231  ortho_ready_cb, ortho_ready_cb, ortho_ready_cb,
232  mCastGID, MM_ALG_2D, config.gemmSplitOrtho
233  );
234 
235  if(config.useOrthoHelpers)
236  {
237  make_multiplier(&matA2, &matB2, &matC2,
238  orthoHelperProxy, orthoHelperProxy, orthoHelperProxy,
241  1, 1, 1,
242  ortho_ready_cb, ortho_ready_cb, ortho_ready_cb,
243  mCastGID, MM_ALG_2D, config.gemmSplitOrtho
244  );
245  }
246  else
247  {
248  make_multiplier(&matA2, &matB2, &matC2,
249  orthoProxy, orthoProxy, orthoProxy,
252  1, 1, 1,
253  ortho_ready_cb, ortho_ready_cb, ortho_ready_cb,
254  mCastGID, MM_ALG_2D, config.gemmSplitOrtho
255  );
256  }
257 
258  make_multiplier(&matA3, &matB3, &matC3,
259  orthoProxy, orthoProxy, orthoProxy,
262  1, 1, 1,
263  ortho_ready_cb, ortho_ready_cb, ortho_ready_cb,
264  mCastGID, MM_ALG_2D, config.gemmSplitOrtho
265  );
266 
267  // Register with the time keeper
268  int timekeep=keeperRegister("Ortho S to T");
269  int maxorthoindex=(cfg.numStates/cfg.grainSize-1);
270  int maxorthostateindex=(cfg.numStates/cfg.grainSize-1) * cfg.grainSize;
271  // Insert each element of the Ortho array
272  for (int s1 = 0; s1 <= maxorthostateindex; s1 += cfg.grainSize)
273  for (int s2 = 0; s2 <= maxorthostateindex; s2 += cfg.grainSize)
274  {
275  int indX = s1 / cfg.grainSize;
276  int indY = s2 / cfg.grainSize;
277  indX = (indX>maxorthoindex) ? maxorthoindex : indX;
278  indY = (indY>maxorthoindex) ? maxorthoindex : indY;
279 
280  orthoProxy(indX, indY).insert(
282  matA1, matB1, matC1,
283  matA2, matB2, matC2,
284  matA3, matB3, matC3,
285  cfg,
286  helperAID,
287  timekeep,
288  orthoMcastGID, orthoRedGID);
289 
290  if(config.useOrthoHelpers)
291  {
292  CkCallback endOfStep2CB(CkIndex_Ortho::recvStep2(NULL), CkArrayIndex2D(indX,indY), orthoProxy);
293  orthoHelperProxy(indX, indY).insert(
295  matA2, matB2, matC2,
296  endOfStep2CB);
297  }
298  }
299  // Notify that you're done inserting the elements
300  orthoProxy.doneInserting();
301  if(config.useOrthoHelpers)
302  orthoHelperProxy.doneInserting();
303 
304  delete avail;
305  delete excludePes;
306 
307  return orthoProxy.ckGetArrayID();
308 }
309 
310  } // end namespace ortho
311 } // end namespace cp
312 
313 /*@}*/
int grainSize
The block size for parallelization.
Definition: orthoConfig.h:31
CkGroupID mapperGID
The group providing procNum() for placing the objects of this paircalc array instance.
Definition: pcInstanceIDs.h:15
Definition: PeList.h:33
int numStates
The number of states in the simulation (the dimension of the input square matrix) ...
Definition: orthoConfig.h:29
CkArrayID build(cp::paircalc::InstanceIDs &asymmHandle, const startup::PCMapConfig mapCfg)
Construct an ortho world given the configs.
Definition: orthoBuilder.C:24
Paircalc's map group that provides procNum() to place paircalc chares as determined by the map logic...
Definition: pcMaps.h:13
Author: Abhinav S Bhatele Date Created: December 28th, 2006.
A container for assorted mapping inputs to pass around easily.
Definition: pcMapConfig.h:15
A place to collect substep times.
Definition: IntMap.h:26
MapType4 * getMapTable()
Let local code access the paircalc maptable I store. (for use by Ortho mapping code) ...
Definition: pcMaps.h:40
orthoConfig cfg
The configurations for the ortho that should be instantiated.
Definition: orthoBuilder.h:27
double Timer
readonly globals
Definition: cpaimd.C:200
A tiny structure to hold the relevant IDs/ proxies required to interact with a paircalc instance...
Definition: pcInstanceIDs.h:11