Add support for Charm++'s change to use 64 bit ID for load balancing
[namd.git] / src / LdbCoordinator.C
1 /**
2 ***  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 by
3 ***  The Board of Trustees of the University of Illinois.
4 ***  All rights reserved.
5 **/
6  
7 /*****************************************************************************
8  * $Source: /home/cvs/namd/cvsroot/namd2/src/LdbCoordinator.C,v $
9  * $Author: jim $
10  * $Date: 2017/03/30 20:06:17 $
11  * $Revision: 1.128 $
12  *****************************************************************************/
13
14 #include <stdlib.h>
15
16 #include "InfoStream.h"
17 #include "NamdCentLB.h"
18 #include "NamdHybridLB.h"
19 #include "NamdDummyLB.h"
20 #include "NamdNborLB.h"
21
22 #include "HomePatch.h"
23 #include "LdbCoordinator.decl.h"
24 #include "LdbCoordinator.h"
25 #include "NamdTypes.h"
26 #include "Node.h"
27 #include "SimParameters.h"
28 #include "PatchMap.inl"
29 #include "ComputeMap.h"
30 #include "ComputeNonbondedMICKernel.h"
31 //#define DEBUGM
32 #define MIN_DEBUG_LEVEL 3
33 #include "Debug.h"
34 #include "Controller.h"
35 #include "Sequencer.h"
36 #include "RefineOnly.h"
37 #include "ComputeMgr.h"
38 #include "Compute.h"
39 #include "packmsg.h"
40 #include "Sync.h"
41
42 #include "elements.h"
43 #include "ComputeMgr.decl.h"
44
45 #define DEBUG_LEVEL 4
46
47 #if CONVERSE_VERSION_ELAN
48 extern "C" void enableBlockingReceives();
49 extern "C" void disableBlockingReceives();
50 #endif
51
52 void LdbCoordinator_initproc() {
53   // Set the load balancing period (in seconds).  Without this the
54   // load balancing framework will hang until 1 second has passed
55   // since the last load balancing, causing hiccups in very fast runs.
56   // This is duplicated below for older versions, but putting it here
57   // also fixes the first load balance.
58   LBSetPeriod(1.0e-5);
59 }
60
61 void LdbCoordinator::staticMigrateFn(LDObjHandle handle, int dest)
62 {
63    LdbCoordinator *ldbCoordinator = (LdbCoordinator *)LDOMUserData(handle.omhandle);
64    ldbCoordinator->Migrate(handle,dest);
65 }
66
67 void LdbCoordinator::Migrate(LDObjHandle handle, int dest)
68 {
69   LdbMigrateMsg* msg = new LdbMigrateMsg;
70   msg->handle = handle;
71   msg->from = CkMyPe();
72   msg->to = dest;
73   if ( msg->to != CkMyPe() ) {
74     CProxy_LdbCoordinator ldbProxy(thisgroup);
75     ldbProxy[CkMyPe()].RecvMigrate(msg);
76   } else {
77     ExpectMigrate(msg);
78   }
79 }
80
81 void LdbCoordinator::staticStatsFn(LDOMHandle h, int state)
82 {
83   CkPrintf("I'm supposed to set stats\n");
84 }
85
86 void LdbCoordinator::staticQueryEstLoadFn(LDOMHandle h)
87 {
88   CkPrintf("I'm supposed to query load\n");
89 }
90
91 void LdbCoordinator::staticReceiveAtSync(void* data)
92 {
93
94 #if CONVERSE_VERSION_ELAN
95     //disableBlockingReceives();
96 #endif
97
98   ((LdbCoordinator*)data)->ReceiveAtSync();
99 }
100
101 void LdbCoordinator::ReceiveAtSync()
102 {
103   theLbdb->RegisteringObjects(myHandle);
104 }
105
106 void LdbCoordinator::staticResumeFromSync(void* data)
107 {
108   ((LdbCoordinator*)data)->ResumeFromSync();
109 }
110
111 void LdbCoordinator::ResumeFromSync()
112 {
113   theLbdb->DoneRegisteringObjects(myHandle);
114   CkCallback cb(CkIndex_LdbCoordinator::nodeDone(NULL), 0, thisgroup);
115   contribute(0, NULL, CkReduction::random, cb);
116 }
117
118 LdbCoordinator::LdbCoordinator()
119 {
120   if (CkpvAccess(LdbCoordinator_instance) == NULL) {
121     CkpvAccess(LdbCoordinator_instance) = this;
122   } else {
123     NAMD_bug("LdbCoordinator instanced twice on same node!");
124   }
125   
126 #if 0
127   // Create a load balancer
128   if (CkMyPe() == 0) {
129     //   CreateCentralLB();
130     CreateNamdCentLB();
131     //   CreateNamdNborLB();
132   }
133 #endif
134
135   collPes = 0;
136   ldbCycleNum = 1;
137   takingLdbData = 1;
138   totalStepsDone = 0;
139   nLocalComputes = nLocalPatches = 0;
140   patchNAtoms = (int *) NULL;
141   sequencerThreads = (Sequencer **) NULL;
142   ldbStatsFP = NULL;
143   computeArray = NULL;
144   patchArray = NULL;
145   processorArray = NULL;
146
147   // Register self as an object manager for new charm++ balancer framework
148   theLbdb = LBDatabase::Object(); 
149
150   // Set the load balancing period (in seconds).  Without this the
151   // load balancing framework will hang until 1 second has passed
152   // since the last load balancing, causing hiccups in very fast runs.
153   // Unfortunately, the clock is already set for the first load
154   // balancing, but only +LBPeriod 1.0e-5 can fix that in older charm.
155   // For newer versions this is handled in initproc above.
156
157   theLbdb->SetLBPeriod(1.0e-5);
158
159   myOMid.id.idx = 1;
160   LDCallbacks cb = { (LDMigrateFn)staticMigrateFn,
161                      (LDStatsFn)staticStatsFn,
162                      (LDQueryEstLoadFn)staticQueryEstLoadFn
163                    };
164   myHandle = theLbdb->RegisterOM(myOMid,(void*)this,cb);
165
166   // Add myself as a local barrier receiver, so I know when I might
167   // be registering objects.
168   theLbdb->AddLocalBarrierReceiver((LDBarrierFn)staticReceiveAtSync,
169                                    (void*)this);;
170
171   // Also, add a local barrier client, to trigger load balancing
172   ldBarrierHandle = theLbdb->
173     AddLocalBarrierClient((LDResumeFn)staticResumeFromSync,
174                           (void*)this);
175   migrateMsgs = 0; // linked list
176   numComputes = 0;
177   reg_all_objs = 1;
178 }
179
180 LdbCoordinator::~LdbCoordinator(void)
181 {
182   delete [] patchNAtoms;
183   delete [] sequencerThreads;
184   if (CkMyPe() == 0)
185   {
186     delete [] computeArray;
187     delete [] patchArray;
188     delete [] processorArray;
189   }
190   if (ldbStatsFP)
191     fclose(ldbStatsFP);
192
193 }
194
195 void LdbCoordinator::createLoadBalancer()
196 {
197   const SimParameters *simParams = Node::Object()->simParameters;
198
199   // Create hierarchical or centralized load balancers
200   // Currently centralized is the default
201   if (simParams->ldBalancer == LDBAL_CENTRALIZED) {
202     CkPrintf("LDB: Central LB being created...\n");
203     CreateNamdCentLB();
204   } else if (simParams->ldBalancer == LDBAL_HYBRID) {
205     CkPrintf("LDB: Hybrid LB being created...\n");
206     CreateNamdHybridLB();
207   }
208 }
209
210 void LdbCoordinator::initialize(PatchMap *pMap, ComputeMap *cMap, int reinit)
211 {
212   const SimParameters *simParams = Node::Object()->simParameters;
213
214 #if 0
215   static int lbcreated = 0; // XXX static variables are unsafe for SMP
216   // PE0 first time Create a load balancer
217   if (CkMyPe() == 0 && !lbcreated) {
218     if (simParams->ldbStrategy == LDBSTRAT_ALGNBOR) 
219       CreateNamdNborLB();
220     else {
221       //   CreateCentralLB();
222       CreateNamdCentLB();
223     }
224     lbcreated = 1;
225   }
226 #endif
227
228   //  DebugM(10,"stepsPerLdbCycle initialized\n");
229   stepsPerLdbCycle = simParams->ldbPeriod;
230   firstLdbStep = simParams->firstLdbStep;
231   int lastLdbStep = simParams->lastLdbStep;
232   int stepsPerCycle = simParams->stepsPerCycle;
233
234   computeMap = cMap;
235   patchMap = pMap;
236
237   // Set the number of received messages correctly for node 0
238
239   nStatsMessagesExpected = Node::Object()->numNodes();
240   nStatsMessagesReceived = 0;
241
242   if (patchNAtoms) 
243     delete [] patchNAtoms;  // Depends on delete NULL to do nothing
244   nPatches = patchMap->numPatches();
245   patchNAtoms = new int[nPatches];
246
247   typedef Sequencer *seqPtr;
248
249   if ( ! reinit ) {
250     delete [] sequencerThreads;  // Depends on delete NULL to do nothing
251     sequencerThreads = new seqPtr[nPatches];
252   }
253
254   nLocalPatches=0;
255
256   int i;
257   for(i=0;i<nPatches;i++)
258   {
259     if (patchMap->node(i) == Node::Object()->myid())
260     {
261       nLocalPatches++;
262       patchNAtoms[i]=0;
263     } else {
264       patchNAtoms[i]=-1;
265     }
266     if ( ! reinit ) sequencerThreads[i]=NULL;
267   }
268   if ( ! reinit ) controllerThread = NULL;
269   if (nLocalPatches != patchMap->numHomePatches())
270     NAMD_die("Disaggreement in patchMap data.\n");
271  
272   const int oldNumComputes = numComputes;
273   nLocalComputes = 0;
274   numComputes = computeMap->numComputes();
275
276   for(i=0;i<numComputes;i++)  {
277     if ( (computeMap->node(i) == Node::Object()->myid())
278          && ( 0
279               #if (defined(NAMD_CUDA) || defined(NAMD_MIC))
280                 #if defined(NAMD_MIC)
281                   || ((computeMap->type(i) == computeNonbondedSelfType) && (computeMap->directToDevice(i) == 0))
282                   || ((computeMap->type(i) == computeNonbondedPairType) && (computeMap->directToDevice(i) == 0))
283                 #endif
284               #else
285               || (computeMap->type(i) == computeNonbondedSelfType)
286               || (computeMap->type(i) == computeNonbondedPairType)
287 #endif
288 #if defined(NAMD_CUDA) && defined(BONDED_CUDA)
289         || (computeMap->type(i) == computeSelfBondsType && !(simParams->bondedCUDA & 1))
290         || (computeMap->type(i) == computeBondsType && !(simParams->bondedCUDA & 1))
291         || (computeMap->type(i) == computeSelfAnglesType && !(simParams->bondedCUDA & 2))
292         || (computeMap->type(i) == computeAnglesType && !(simParams->bondedCUDA & 2))
293         || (computeMap->type(i) == computeSelfDihedralsType && !(simParams->bondedCUDA & 4))
294         || (computeMap->type(i) == computeDihedralsType && !(simParams->bondedCUDA & 4))
295         || (computeMap->type(i) == computeSelfImpropersType && !(simParams->bondedCUDA & 8))
296         || (computeMap->type(i) == computeImpropersType && !(simParams->bondedCUDA & 8))
297         || (computeMap->type(i) == computeSelfExclsType && !(simParams->bondedCUDA & 16))
298         || (computeMap->type(i) == computeExclsType && !(simParams->bondedCUDA & 16))
299         || (computeMap->type(i) == computeSelfCrosstermsType && !(simParams->bondedCUDA & 32))
300         || (computeMap->type(i) == computeCrosstermsType && !(simParams->bondedCUDA & 32))
301 #else
302         || (computeMap->type(i) == computeSelfBondsType)
303         || (computeMap->type(i) == computeBondsType)
304         || (computeMap->type(i) == computeSelfAnglesType)
305         || (computeMap->type(i) == computeAnglesType)
306         || (computeMap->type(i) == computeSelfDihedralsType)
307         || (computeMap->type(i) == computeDihedralsType)
308         || (computeMap->type(i) == computeSelfImpropersType)
309         || (computeMap->type(i) == computeImpropersType)
310         || (computeMap->type(i) == computeSelfExclsType)
311         || (computeMap->type(i) == computeExclsType)
312         || (computeMap->type(i) == computeSelfCrosstermsType)
313         || (computeMap->type(i) == computeCrosstermsType)
314 #endif
315               || (computeMap->type(i) == computeLCPOType)
316               || (computeMap->type(i) == computeSelfTholeType)
317               || (computeMap->type(i) == computeSelfAnisoType)
318
319                  || (computeMap->type(i) == computeTholeType)
320                  || (computeMap->type(i) == computeAnisoType)
321               // JLai
322                  || (computeMap->type(i) == computeGromacsPairType)
323                  || (computeMap->type(i) == computeSelfGromacsPairType)
324         ) ) {
325       nLocalComputes++;
326     }
327   }
328   
329   // New LB frameworks registration
330
331   // Allocate data structure to save incoming migrations.  Processor
332   // zero will get all migrations
333
334   // If this is the first time through, we need it register patches
335   if (ldbCycleNum == reg_all_objs) {
336     if ( 1 ) { // ( Node::Object()->simParameters->ldBalancer == LDBAL_CENTRALIZED ) {
337       reg_all_objs = 3;
338     }
339     // Tell the lbdb that I'm registering objects, until I'm done
340     // registering them.
341     theLbdb->RegisteringObjects(myHandle);
342     
343    if ( ldbCycleNum == 1 ) {
344     patchHandles = new LDObjHandle[nLocalPatches];
345     int patch_count=0;
346     int i;
347     for(i=0;i<nPatches;i++)
348       if (patchMap->node(i) == Node::Object()->myid()) {
349
350         LdbId elemID;
351         LdbIdField(elemID, 0) = i;
352         LdbIdField(elemID, 1) = PATCH_TYPE;
353
354         if (patch_count >= nLocalPatches) {
355     NAMD_bug("LdbCoordinator found too many local patches!");
356         }
357         HomePatch *p = patchMap->homePatch(i);
358         p->ldObjHandle = 
359         patchHandles[patch_count] 
360           = theLbdb->RegisterObj(myHandle,elemID,0,0);
361         patch_count++;
362
363       }
364    }
365   
366     if ( numComputes > oldNumComputes ) {
367       // Register computes
368       for(i=oldNumComputes; i<numComputes; i++)  {
369         if ( computeMap->node(i) == Node::Object()->myid())
370         {
371           if ( 0
372                #if (defined(NAMD_CUDA) || defined(NAMD_MIC))
373                  #if defined(NAMD_MIC)
374                    || ((computeMap->type(i) == computeNonbondedSelfType) && (computeMap->directToDevice(i) == 0))
375                    || ((computeMap->type(i) == computeNonbondedPairType) && (computeMap->directToDevice(i) == 0))
376                  #endif
377                #else
378                   || (computeMap->type(i) == computeNonbondedSelfType)
379                   || (computeMap->type(i) == computeNonbondedPairType)
380                #endif
381 #if defined(NAMD_CUDA) && defined(BONDED_CUDA)
382             || (computeMap->type(i) == computeSelfBondsType && !(simParams->bondedCUDA & 1))
383             || (computeMap->type(i) == computeSelfAnglesType && !(simParams->bondedCUDA & 2))
384             || (computeMap->type(i) == computeSelfDihedralsType && !(simParams->bondedCUDA & 4))
385             || (computeMap->type(i) == computeSelfImpropersType && !(simParams->bondedCUDA & 8))
386             || (computeMap->type(i) == computeSelfExclsType && !(simParams->bondedCUDA & 16))
387             || (computeMap->type(i) == computeSelfCrosstermsType && !(simParams->bondedCUDA & 32))
388 #else
389             || (computeMap->type(i) == computeSelfBondsType)
390             || (computeMap->type(i) == computeSelfAnglesType)
391             || (computeMap->type(i) == computeSelfDihedralsType)
392             || (computeMap->type(i) == computeSelfImpropersType)
393             || (computeMap->type(i) == computeSelfExclsType)
394             || (computeMap->type(i) == computeSelfCrosstermsType)
395 #endif
396                   || (computeMap->type(i) == computeLCPOType)
397                   || (computeMap->type(i) == computeSelfTholeType)
398                   || (computeMap->type(i) == computeSelfAnisoType)
399                // JLai
400                   || (computeMap->type(i) == computeSelfGromacsPairType)
401                // End of JLai
402                 )  {
403           // Register the object with the load balancer
404           // Store the depended patch IDs in the rest of the element ID
405           LdbId elemID;
406           LdbIdField(elemID, 0) = i;
407
408           if (computeMap->numPids(i) > 0)
409             LdbIdField(elemID, 1) =  computeMap->pid(i,0);
410           else LdbIdField(elemID, 1) = NONBONDED_OR_SELF_TYPE;
411
412           Compute *c = computeMap->compute(i);
413           if ( ! c ) NAMD_bug("LdbCoordinator::initialize() null compute pointer");
414
415           c->ldObjHandle = theLbdb->RegisterObj(myHandle,elemID,0,1);
416           }
417           else if ( 
418 #if defined(NAMD_CUDA) && defined(BONDED_CUDA)
419                     (computeMap->type(i) == computeBondsType && !(simParams->bondedCUDA & 1))
420                  || (computeMap->type(i) == computeAnglesType && !(simParams->bondedCUDA & 2))
421                  || (computeMap->type(i) == computeDihedralsType && !(simParams->bondedCUDA & 4))
422                  || (computeMap->type(i) == computeImpropersType && !(simParams->bondedCUDA & 8))
423                  || (computeMap->type(i) == computeExclsType && !(simParams->bondedCUDA & 16))
424                  || (computeMap->type(i) == computeCrosstermsType && !(simParams->bondedCUDA & 32))
425 #else
426                     (computeMap->type(i) == computeBondsType)
427                  || (computeMap->type(i) == computeAnglesType)
428                  || (computeMap->type(i) == computeDihedralsType)
429                  || (computeMap->type(i) == computeImpropersType)
430                  || (computeMap->type(i) == computeExclsType)
431                  || (computeMap->type(i) == computeCrosstermsType)
432 #endif
433                  || (computeMap->type(i) == computeTholeType)
434                  || (computeMap->type(i) == computeAnisoType)
435                  // JLai
436                  || (computeMap->type(i) == computeGromacsPairType)
437                  // End of JLai
438                ) {
439           // Register the object with the load balancer
440           // Store the depended patch IDs in the rest of the element ID
441           LdbId elemID;
442           LdbIdField(elemID, 0) = i;
443         
444           LdbIdField(elemID, 1) = BONDED_TYPE;
445
446           Compute *c = computeMap->compute(i);
447           if ( ! c ) NAMD_bug("LdbCoordinator::initialize() null compute pointer");
448
449           c->ldObjHandle = theLbdb->RegisterObj(myHandle,elemID,0,0);
450           }
451         }
452       }
453     }
454     theLbdb->DoneRegisteringObjects(myHandle);
455   }
456
457   // process saved migration messages, if any
458   while ( migrateMsgs ) {
459     LdbMigrateMsg *m = migrateMsgs;
460     migrateMsgs = m->next;
461     Compute *c = computeMap->compute(LdbIdField(m->handle.id, 0));
462     if ( ! c ) NAMD_bug("LdbCoordinator::initialize() null compute pointer 2");
463     c->ldObjHandle = m->handle;
464     delete m;
465   }
466
467   // Fixup to take care of the extra timestep at startup
468   // This is pretty ugly here, but it makes the count correct
469   
470   // iout << "LDB Cycle Num: " << ldbCycleNum << "\n";
471
472  if ( 1 ) { // ( simParams->ldBalancer == LDBAL_CENTRALIZED ) {
473   if (ldbCycleNum == 1 || ldbCycleNum == 3) {
474     numStepsToRun = stepsPerCycle;
475     totalStepsDone += numStepsToRun;
476     takingLdbData = 0;
477     theLbdb->CollectStatsOff();
478   } else if (ldbCycleNum == 2 || ldbCycleNum == 4) {
479     numStepsToRun = firstLdbStep - stepsPerCycle;
480     while ( numStepsToRun <= 0 ) numStepsToRun += stepsPerCycle;
481     totalStepsDone += numStepsToRun;
482     takingLdbData = 1;
483     theLbdb->CollectStatsOn();
484   } else if ( (ldbCycleNum <= 6) || !takingLdbData )
485   {
486     totalStepsDone += firstLdbStep;
487     if(lastLdbStep != -1 && totalStepsDone > lastLdbStep) {
488       numStepsToRun = -1;
489       takingLdbData = 0;
490       theLbdb->CollectStatsOff();
491     } else {
492       numStepsToRun = firstLdbStep;
493       takingLdbData = 1;
494       theLbdb->CollectStatsOn();
495     }
496   }
497   else 
498   {
499     totalStepsDone += stepsPerLdbCycle - firstLdbStep;
500     if(lastLdbStep != -1 && totalStepsDone > lastLdbStep) {
501       numStepsToRun = -1;
502       takingLdbData = 0;
503       theLbdb->CollectStatsOff();
504     } else {
505       numStepsToRun = stepsPerLdbCycle - firstLdbStep;
506       takingLdbData = 0;
507       theLbdb->CollectStatsOff();
508     }
509   }
510  } else {
511   if (ldbCycleNum==1)
512   {
513     totalStepsDone += firstLdbStep;
514     numStepsToRun = firstLdbStep;
515     takingLdbData = 0;
516     theLbdb->CollectStatsOff();
517   }
518   else if ( (ldbCycleNum <= 4) || !takingLdbData )
519   {
520     totalStepsDone += firstLdbStep;
521     if(lastLdbStep != -1 && totalStepsDone > lastLdbStep) {
522       numStepsToRun = -1;
523       takingLdbData = 0;
524       theLbdb->CollectStatsOff();
525     } else {
526       numStepsToRun = firstLdbStep;
527       takingLdbData = 1;
528       theLbdb->CollectStatsOn();
529     }
530   }
531   else 
532   {
533     totalStepsDone += stepsPerLdbCycle - firstLdbStep;
534     if(lastLdbStep != -1 && totalStepsDone > lastLdbStep) {
535       numStepsToRun = -1;
536       takingLdbData = 0;
537       theLbdb->CollectStatsOff();
538     } else {
539       numStepsToRun = stepsPerLdbCycle - firstLdbStep;
540       takingLdbData = 0;
541       theLbdb->CollectStatsOff();
542     }
543   }
544  }
545
546 /*-----------------------------------------------------------------------------*
547  * --------------------------------------------------------------------------- *
548  * Comments inserted by Abhinav to clarify relation between ldbCycleNum,       *
549  * load balancing step numbers (printed by the step() function) and            *
550  * tracing of the steps                                                        *
551  * --------------------------------------------------------------------------- *
552  * If trace is turned off in the beginning, then tracing is turned on          *
553  * at ldbCycleNum = 4 and turned off at ldbCycleNum = 8. ldbCycleNum can       *
554  * be adjusted by specifying firstLdbStep and ldbPeriod which are set by       *
555  * default to 5*stepspercycle and 200*stepspercycle if not specified.          *
556  *                                                                             *
557  * If we choose firstLdbStep = 20 and ldbPeriod = 100, we have the             *
558  * following timeline (for these particular numbers):                          *
559  *                                                                             *
560  * Tracing         :  <------ off ------><------------- on -----------><-- off *
561  * Ldb Step() No   :              1     2     3        4      5       6      7 *
562  * Iteration Steps : 00====20====40====60====80======160====180=====260====280 *
563  * ldbCycleNum     :  1     2     3     4     5        6      7       8      9 *
564  * Instrumention   :          Inst  Inst  Inst           Inst            Inst  *
565  * LDB Strategy    :              TLB  RLB   RLB            RLB            RLB *
566  *                                                                             *
567  * TLB = TorusLB                                                               *
568  * RLB = RefineTorusLB                                                         *
569  * Inst = Instrumentation Phase (no real load balancing)                       *
570  * --------------------------------------------------------------------------- *
571  *-----------------------------------------------------------------------------*
572  */
573 #if 0 //replaced by traceBarrier at Controller and Sequencer
574   if (traceAvailable()) {
575     static int specialTracing = 0; // XXX static variables are unsafe for SMP
576     if (ldbCycleNum == 1 && traceIsOn() == 0)  specialTracing = 1;
577     if (specialTracing) {
578       if (ldbCycleNum == 4) traceBegin();
579       if (ldbCycleNum == 8) traceEnd();
580     }
581   }
582 #endif
583
584   nPatchesReported = 0;
585   nPatchesExpected = nLocalPatches;
586   nComputesReported = 0;
587   nComputesExpected = nLocalComputes * numStepsToRun;
588   controllerReported = 0;
589   controllerExpected = ! CkMyPe();
590
591   if (simParams->multigratorOn) {
592     // Add the number of pressure cycles into nComputesExpected:
593     // Pressure cycle is done when !(step % simParams->multigratorPressureFreq) = true
594     // step = Current step
595     int step = totalStepsDone - numStepsToRun;
596     int freq = simParams->multigratorPressureFreq;
597     // dstep = Number of steps we have to take until next pressure cycle
598     int dstep = 0;
599     if ((step % freq) != 0) dstep = freq - (step % freq);
600     step += dstep;
601     if (step < totalStepsDone) {
602       int numPressureCycles = 1 + ((totalStepsDone-step-1)/freq);
603       if (step==0) numPressureCycles--;
604       // if (CkMyPe()==2) fprintf(stderr, "step %d totalStepsDone %d numPressureCycles %d\n",
605       //   step, totalStepsDone, numPressureCycles);
606       nComputesExpected += 2*nLocalComputes*numPressureCycles;
607     }
608   }
609
610   if (CkMyPe() == 0)
611   {
612     if (computeArray == NULL)
613       computeArray = new computeInfo[numComputes];
614     if (patchArray == NULL)
615       patchArray = new patchInfo[nPatches];
616     if (processorArray == NULL)
617       processorArray = new processorInfo[CkNumPes()];
618   }
619     
620   theLbdb->ClearLoads();
621 }
622
623 void LdbCoordinator::patchLoad(PatchID id, int nAtoms, int /* timestep */)
624 {
625   CmiAssert( id >=0 && id < nPatches);
626   if (patchNAtoms[id] != -1) {
627     patchNAtoms[id] = nAtoms;
628     nPatchesReported++;
629   } else {
630     DebugM(10, "::patchLoad() Unexpected patch reporting in\n");
631   }
632 }
633
634 void LdbCoordinator::rebalance(Sequencer *seq, PatchID pid)
635 {
636   if (Node::Object()->simParameters->ldBalancer == LDBAL_NONE)
637     return;
638
639   sequencerThreads[pid] = seq;
640   seq->suspend();
641 }
642
643 void LdbCoordinator::rebalance(Controller *c)
644 {
645   if (Node::Object()->simParameters->ldBalancer == LDBAL_NONE)
646     return;
647
648   iout << "LDB: ============= START OF LOAD BALANCING ============== " << CmiWallTimer() << "\n" << endi;
649   DebugM(3, "Controller reached load balance barrier.\n");
650   controllerReported = 1;
651   controllerThread = c;
652
653   CProxy_LdbCoordinator(thisgroup).barrier();
654
655   CthSuspend();
656 }
657
658 void LdbCoordinator::barrier(void)
659 {
660   if ( (nPatchesReported != nPatchesExpected) 
661        || (nComputesReported != nComputesExpected)
662        || (controllerReported != controllerExpected) )
663   {
664     NAMD_bug("Load balancer received wrong number of events.\n");
665   }
666
667   theLbdb->AtLocalBarrier(ldBarrierHandle);
668 }
669
670 void LdbCoordinator::nodeDone(CkReductionMsg *msg)
671 {
672   delete msg;
673
674   iout << "LDB: ============== END OF LOAD BALANCING =============== " << CmiWallTimer() << "\n" << endi;
675   if ( takingLdbData ) {
676       ExecuteMigrations();
677   } else {
678       updateComputesReady();
679   }
680 }
681
682 void LdbCoordinator::ExecuteMigrations(void)
683 {
684  // computeMgr->updateComputes() call only on Node(0) i.e. right here
685   // This will barrier for all Nodes - (i.e. Computes must be
686   // here and with proxies before anyone can start up
687
688   CProxy_ComputeMgr cm(CkpvAccess(BOCclass_group).computeMgr);
689   ComputeMgr *computeMgr = cm.ckLocalBranch();
690   computeMgr->updateComputes(CkIndex_LdbCoordinator::
691                              updateComputesReady(),thisgroup);
692 }
693
694 void LdbCoordinator::RecvMigrate(LdbMigrateMsg* m)
695 {
696   // This method receives the migration from the framework,
697   // unregisters it, and sends it to the destination PE
698
699   if ( m->to != CkMyPe() ) {
700     theLbdb->UnregisterObj(m->handle);
701
702     CProxy_LdbCoordinator  ldbProxy(thisgroup);
703     ldbProxy[m->to].ExpectMigrate(m);
704   } else {
705     ExpectMigrate(m);
706   }
707 }
708
709 void LdbCoordinator::ExpectMigrate(LdbMigrateMsg* m)
710 {
711   if ( m->from != CkMyPe() ) {
712     m->handle = theLbdb->RegisterObj(myHandle,m->handle.id,0,1);
713     theLbdb->Migrated(m->handle);
714   }
715
716   m->next = migrateMsgs;
717   migrateMsgs = m;
718 }
719
720 void LdbCoordinator::updateComputesReady() {
721   DebugM(3,"updateComputesReady()\n");
722
723   CProxy_LdbCoordinator(thisgroup).resume();
724   CkStartQD(CkIndex_LdbCoordinator::resumeReady((CkQdMsg*)0),&thishandle);
725 }
726
727 void LdbCoordinator::resume(void)
728 {
729   DebugM(3,"resume()\n");
730   //  printLocalLdbReport();
731
732   ldbCycleNum++;
733   initialize(PatchMap::Object(),ComputeMap::Object(),1);
734
735   Sync::Object()->openSync();
736 }
737
738 void LdbCoordinator::resumeReady(CkQdMsg *msg) {
739
740   iout << "LDB: =============== DONE WITH MIGRATION ================ " << CmiWallTimer() << "\n" << endi;
741   DebugM(3,"resumeReady()\n");
742   delete msg;
743
744   CProxy_LdbCoordinator(thisgroup).resume2();
745 }
746
747 void LdbCoordinator::resume2(void)
748 {
749   DebugM(3,"resume2()\n");
750
751 #if CONVERSE_VERSION_ELAN
752   //  enableBlockingReceives();
753 #endif
754
755   awakenSequencers();
756 }
757
758 void LdbCoordinator::awakenSequencers()
759 {
760   if (controllerThread)
761   {
762     controllerThread->awaken();
763     controllerThread = NULL;
764   }
765   for(int i=0; i < patchMap->numPatches(); i++)
766   {
767     if (sequencerThreads[i])
768     {
769       sequencerThreads[i]->awaken();
770     }
771     sequencerThreads[i]= NULL;
772   }
773 }
774
775 // Figure out which proxies we will definitely create on other
776 // nodes, without regard for non-bonded computes.  This code is swiped
777 // from ProxyMgr, and changes there probable need to be propagated here.
778
779 int LdbCoordinator::requiredProxies(PatchID id, int neighborNodes[])
780 {
781   PatchID neighbors[1 + PatchMap::MaxOneAway];
782   neighbors[0] = id;
783   int numNeighbors = 1 + patchMap->downstreamNeighbors(id,neighbors+1);
784
785   int nProxyNodes = 0;
786   int myNode = patchMap->node(id);
787   for ( int i = 0; i < numNeighbors; ++i ) {
788     const int proxyNode = patchMap->basenode(neighbors[i]);
789     if ( proxyNode != myNode ) {
790       int j;
791       for ( j = 0; j < nProxyNodes; ++j ) {
792         if ( neighborNodes[j] == proxyNode ) break;
793       }
794       if ( j == nProxyNodes ) {
795         neighborNodes[nProxyNodes] = proxyNode;
796         nProxyNodes++;
797       }
798     }
799   }
800   return nProxyNodes;
801 }
802
803 void LdbCoordinator::printLocalLdbReport(void)
804 {
805   char outputBuf[255];
806   char *curLoc;
807
808   CkPrintf("%d:Patch report:\n",CkMyPe());
809   
810   curLoc = outputBuf;
811   int i,j=0;
812   for(i=0; i<patchMap->numPatches(); i++)
813   {
814     if (patchNAtoms[i] != -1)
815     {
816       curLoc += sprintf(curLoc,"%5d: %5d ",i,patchNAtoms[i]);
817       j++;
818     } 
819     if (((j % 4) == 0) && j)
820     {
821       curLoc = outputBuf;
822       CkPrintf("[%d]%s\n",CkMyPe(),outputBuf);
823       j=0;
824     }
825   }
826
827   CkPrintf("%d:Compute report:\n",CkMyPe());
828   
829   curLoc = outputBuf;
830   j=0;
831 }
832
833 void LdbCoordinator::printRequiredProxies(PatchID id, FILE *fp)
834 {
835   // Check all two-away neighbors.
836   // This is really just one-away neighbors, since 
837   // two-away always returns zero: RKB
838   int neighborNodes[PatchMap::MaxOneAway + PatchMap::MaxTwoAway];
839   const int nProxyNodes = requiredProxies(id,neighborNodes);
840
841   fprintf(fp,"%4d ",nProxyNodes);
842
843   for(int i=0;i<nProxyNodes;i++)
844     fprintf(fp,"%4d ",neighborNodes[i]);
845 }
846
847 void LdbCoordinator::sendCollectLoads(CollectLoadsMsg *msg) {
848   CProxy_LdbCoordinator(thisgroup)[0].collectLoads(msg);
849 }
850
851 void LdbCoordinator::collectLoads(CollectLoadsMsg *msg) {
852   // CkPrintf("LdbCoordinator::collectLoads recv %d-%d\n", msg->firstPe, msg->lastPe);
853   if ( collPes == 0 ) {
854     reverted = 0;
855     initTotalProxies = 0;
856     finalTotalProxies = 0;
857     initMaxPeProxies = 0;
858     finalMaxPeProxies = 0;
859     initMaxPatchProxies = 0;
860     finalMaxPatchProxies = 0;
861     initTime = 0;
862     finalTime = 0;
863     initMemory = 0;
864     finalMemory = 0;
865     initAvgPeLoad = 0;
866     finalAvgPeLoad = 0;
867     initMaxPeLoad = 0;
868     finalMaxPeLoad = 0;
869   }
870   int numPes = msg->lastPe - msg->firstPe + 1;
871   collPes += numPes;
872 #define COLL_MAX(F) if ( msg->F > F ) F = msg->F;
873 #define COLL_AVG(F) F += msg->F * (double) numPes / (double) CkNumPes();
874 #define COLL_SUM(F) F += msg->F;
875   COLL_SUM(reverted)
876   COLL_SUM(initTotalProxies)
877   COLL_SUM(finalTotalProxies)
878   COLL_MAX(initMaxPeProxies)
879   COLL_MAX(finalMaxPeProxies)
880   COLL_MAX(initMaxPatchProxies)
881   COLL_MAX(finalMaxPatchProxies)
882   if ( (msg->finalTime - msg->initTime) > (finalTime - initTime) ) {
883     initTime = msg->initTime;
884     finalTime = msg->finalTime;
885   }
886   COLL_MAX(initMemory)
887   COLL_MAX(finalMemory)
888   COLL_AVG(initAvgPeLoad)
889   COLL_AVG(finalAvgPeLoad)
890   COLL_MAX(initMaxPeLoad)
891   COLL_MAX(finalMaxPeLoad)
892
893   if ( collPes == CkNumPes() ) {
894     collPes = 0;
895     iout << "LDB: TIME " << initTime << " LOAD: AVG " << initAvgPeLoad
896       << " MAX " << initMaxPeLoad << "  PROXIES: TOTAL " << initTotalProxies << " MAXPE " <<
897       initMaxPeProxies << " MAXPATCH " << initMaxPatchProxies << " " << "None"
898       << " MEM: " << initMemory << " MB\n";
899     if ( reverted ) iout << "LDB: Reverting to original mapping on " << reverted << " balancers\n";
900     iout << "LDB: TIME " << finalTime << " LOAD: AVG " << finalAvgPeLoad
901       << " MAX " << finalMaxPeLoad << "  PROXIES: TOTAL " << finalTotalProxies << " MAXPE " <<
902       finalMaxPeProxies << " MAXPATCH " << finalMaxPatchProxies << " " << msg->strategyName
903       << " MEM: " << finalMemory << " MB\n";
904     iout << endi;
905     fflush(stdout);
906   }
907
908   delete msg;
909 }
910
911 #include "LdbCoordinator.def.h"