Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

GlobalMasterServer.C

Go to the documentation of this file.
00001 
00007 /*
00008    Forwards atoms to master node for force evaluation.
00009 */
00010 
00011 #include "ComputeGlobalMsgs.h"
00012 #include "ComputeMgr.h"
00013 #include "NamdTypes.h"
00014 
00015 //#define DEBUGM
00016 #define MIN_DEBUG_LEVEL 1
00017 #include "Debug.h"
00018 
00019 void GlobalMasterServer::addClient(GlobalMaster *newClient) {
00020   DebugM(3,"Adding client\n");
00021   clientList.add(newClient);
00022   DebugM(2,"Added.\n");
00023 }
00024 
00025 void GlobalMasterServer::recvData(ComputeGlobalDataMsg *msg) {
00026   DebugM(3,"Storing data (" << msg->aid.size() << " positions) on master\n");
00027 
00028   if ( msg->step != -1 ) step = msg->step;
00029 
00030   /* get the beginning and end of the lists */
00031   AtomIDList::iterator a_i = msg->aid.begin();
00032   AtomIDList::iterator a_e = msg->aid.end();
00033   PositionList::iterator p_i = msg->p.begin();
00034   PositionList::iterator g_i = msg->gcom.begin();
00035   PositionList::iterator g_e = msg->gcom.end();
00036 
00037   /* iterate over each member of the atom lists */
00038   for ( ; a_i != a_e; ++a_i, ++p_i ) {
00039     receivedAtomIDs.add(*a_i);
00040     receivedAtomPositions.add(*p_i);
00041   }
00042   
00043   /* iterate over each member of "total force" lists */
00044   a_e = msg->fid.end();
00045   ForceList::iterator f_i=msg->tf.begin();
00046   for (a_i=msg->fid.begin() ; a_i!=a_e; ++a_i,++f_i) {
00047     receivedForceIDs.add(*a_i);
00048     receivedTotalForces.add(*f_i);
00049   }
00050 
00051   /* iterate over each member of the group position list */
00052   int i=0;
00053   for ( ; g_i != g_e; ++g_i ) {
00054     DebugM(1,"Received center of mass "<<*g_i<<"\n");
00055     if(i >= totalGroupsRequested) NAMD_die("Received too many groups.");
00056     receivedGroupPositions[i] += (*g_i);
00057     i++;
00058   }
00059   if(i!=totalGroupsRequested) NAMD_die("Received too few groups.");
00060 
00061   /* done with the message, delete it */
00062   delete msg;
00063 
00064   /* check whether we've gotten all the expected messages */
00065   recvCount++;
00066   if(recvCount == numDataSenders) {
00067     DebugM(3,"received messages from each of the ComputeGlobals\n");
00068     callClients();
00069 
00070     /* now restart */
00071     step = -1;
00072     receivedAtomIDs.resize(0);
00073     receivedAtomPositions.resize(0);
00074     receivedGroupPositions.resize(totalGroupsRequested);
00075     receivedGroupPositions.setall(Vector(0,0,0));
00076     receivedForceIDs.resize(0);
00077     receivedTotalForces.resize(0);
00078     recvCount = 0;
00079   }
00080 }
00081 
00082 void GlobalMasterServer::resetAtomList(AtomIDList atomsRequested) {
00083   atomsRequested.resize(0);
00084 
00085   /* iterate over all of the masters */
00086   GlobalMaster **m_i = clientList.begin();
00087   GlobalMaster **m_e = clientList.end();
00088   while(m_i != m_e) {
00089     /* add all of the atoms in this master */
00090     int i;
00091     for(i=0;i<(*m_i)->requestedAtoms().size();i++) {
00092       atomsRequested.add((*m_i)->requestedAtoms()[i]);
00093     }
00094 
00095     /* go to next master */
00096     m_i++;
00097   }
00098 }
00099 
00100 void GlobalMasterServer::resetGroupList(AtomIDList groupsRequested,
00101                                         int *numGroups) {
00102   DebugM(3,"Rebuilding the group list\n");
00103   groupsRequested.resize(0);
00104   *numGroups = 0;
00105 
00106   /* iterate over all of the masters */
00107   GlobalMaster **m_i = clientList.begin();
00108   GlobalMaster **m_e = clientList.end();
00109   while(m_i != m_e) {
00110 
00111     /* add all of the groups requested by this master */
00112     int i;
00113     GlobalMaster *master = *m_i;
00114     for(i=0;i<master->requestedGroups().size();i++) {
00115       /* add all of the atoms in this group, then add a -1 */
00116       int j;
00117       const AtomIDList &atoms_in_group = master->requestedGroups()[i];
00118       (*numGroups) ++;
00119       DebugM(1,"adding group "<<*numGroups<<"\n");
00120       for(j=0;j<atoms_in_group.size();j++) {
00121         groupsRequested.add(atoms_in_group[j]); // add an atom
00122       }
00123       DebugM(1,"here\n");
00124       groupsRequested.add(-1); // add a -1 to separate the groups (yuck)
00125     }
00126 
00127     /* go to next master */
00128     m_i++;
00129   }
00130 }
00131 
00132 void GlobalMasterServer::resetForceList(AtomIDList atomsForced,
00133                                         ForceList forces,
00134                                         ForceList groupForces) {
00135   DebugM(1,"Restting forces\n");
00136   atomsForced.resize(0);
00137   forces.resize(0);
00138   groupForces.resize(0);
00139   lastAtomsForced.resize(0);
00140   lastForces.resize(0);
00141 
00142   /* iterate over all of the masters */
00143   GlobalMaster **m_i = clientList.begin();
00144   GlobalMaster **m_e = clientList.end();
00145   while(m_i != m_e) {
00146     (*m_i)->check(); // just in case!
00147 
00148     /* add all of the atoms in this master */
00149     int i;
00150     DebugM(1,"Adding atom forces\n");
00151     for(i=0;i<(*m_i)->forcedAtoms().size();i++) {
00152       atomsForced.add((*m_i)->forcedAtoms()[i]);
00153       forces.add((*m_i)->appliedForces()[i]);
00154       lastAtomsForced.add((*m_i)->forcedAtoms()[i]);
00155       lastForces.add((*m_i)->appliedForces()[i]);
00156     }
00157 
00158     /* add all of the group forces for this master */
00159     DebugM(1,"Adding "<<(*m_i)->requestedGroups().size()<<" group forces\n");
00160     for(i=0;i<(*m_i)->requestedGroups().size();i++) {
00161       groupForces.add((*m_i)->groupForces()[i]);
00162     }
00163 
00164     /* go to next master */
00165     DebugM(1,"Next master...\n");
00166     m_i++;
00167   }
00168   DebugM(1,"Done restting forces\n");
00169 }
00170 
00171 
00172 void GlobalMasterServer::callClients() {
00173   DebugM(3,"Calling clients\n");
00174   if(firstTime) {
00175     /* the first time we just get the requested atom ids from the
00176        clients and send messages to the compute globals requesting
00177        those atoms, so they can have coordinates for the first time
00178        step. */
00179     DebugM(1,"first time.\n");
00180     ComputeGlobalResultsMsg *msg = new ComputeGlobalResultsMsg;
00181     resetAtomList(msg->newaid); // add any atom IDs made in constructors
00182     resetForceList(msg->aid,msg->f,msg->gforce); // same for forces
00183     resetGroupList(msg->newgdef,&totalGroupsRequested);
00184     msg->resendCoordinates = 1;
00185     msg->reconfig = 1;
00186     totalAtomsRequested = msg->newaid.size(); // record the atom total
00187 
00188     DebugM(3,"Sending configure ("<<totalAtomsRequested<<" atoms, "
00189            <<totalGroupsRequested<<" groups)\n");
00190     myComputeManager->sendComputeGlobalResults(msg);
00191 
00192     firstTime = 0;
00193     return;
00194   }
00195 
00196   /* check to make sure we've got everything */
00197   if(receivedAtomIDs.size() != totalAtomsRequested) {
00198     DebugM(3,"Requested " << totalAtomsRequested << " atoms.\n");
00199     NAMD_die("Got the wrong number of atoms");
00200   }
00201   if(receivedGroupPositions.size() != totalGroupsRequested) {
00202     DebugM(3,"Requested " << totalGroupsRequested << " groups.\n");
00203     DebugM(3,"Got " << receivedGroupPositions.size() << " group positions.\n");
00204     NAMD_die("Got the wrong number of groups");
00205   }
00206 
00207   /* get the beginning and end of the lists */
00208   AtomIDList::iterator a_i = receivedAtomIDs.begin();
00209   AtomIDList::iterator a_e = receivedAtomIDs.end();
00210   PositionList::iterator p_i = receivedAtomPositions.begin();
00211   PositionList::iterator g_i = receivedGroupPositions.begin();
00212   PositionList::iterator g_e = receivedGroupPositions.end();
00213   AtomIDList::iterator forced_atoms_i = lastAtomsForced.begin();
00214   AtomIDList::iterator forced_atoms_e = lastAtomsForced.end();
00215   ForceList::iterator forces_i = lastForces.begin();
00216   GlobalMaster **m_i = clientList.begin();
00217   GlobalMaster **m_e = clientList.end();
00218 
00219   /* use these to check whether anything has changed for any master */
00220   bool requested_atoms_changed=false;
00221   bool requested_forces_changed=false;
00222   bool requested_groups_changed=false;
00223   
00224   /* call each of the masters with the coordinates */
00225   while(m_i != m_e) {
00226     int num_atoms_requested, num_groups_requested;
00227     
00228     /* get the masters information */
00229     GlobalMaster *master = *m_i;
00230     num_atoms_requested = master->requestedAtoms().size();
00231     num_groups_requested = master->requestedGroups().size();
00232 
00233     /* check to make sure we have some atoms left.  This must work for
00234      zero requested atoms, as well! */
00235     if(a_i+num_atoms_requested > a_e)
00236       NAMD_die("GlobalMasterServer ran out of atom IDs!");
00237 
00238     /* check for condition that will exercise bug */
00239     if ( CkNumPes() > 1 &&
00240          num_atoms_requested && a_i+num_atoms_requested != a_e ) {
00241       NAMD_die("Due to a design error, GlobalMasterServer does not support individual atom requests from multiple global force clients on parallel runs.");
00242     }
00243 
00244     /* update this master */
00245     master->clearChanged();
00246     master->step = step;
00247     master->processData(a_i,a_i+num_atoms_requested,
00248                         p_i,g_i,g_i+num_groups_requested,
00249                         forced_atoms_i,forced_atoms_e,forces_i,
00250      receivedForceIDs.begin(),receivedForceIDs.end(),receivedTotalForces.begin());
00251 
00252     /* check to see if anything changed */
00253     if(master->changedAtoms()) {
00254       requested_atoms_changed = true;
00255     }
00256     if(master->changedForces()) {
00257       requested_forces_changed = true;
00258     }
00259     if(master->changedGroups()) {
00260       requested_groups_changed = true;
00261     }
00262 
00263     /* go to next master */
00264     m_i++;
00265 
00266 // XXX Completely wrong if multiple clients request atoms in parallel! XXX
00267 
00268     /* next atoms/groups start farther down the lists */
00269     a_i += num_atoms_requested;
00270     p_i += num_atoms_requested;
00271     g_i += num_groups_requested;
00272   }
00273   
00274   /* make a new message */
00275   ComputeGlobalResultsMsg *msg = new ComputeGlobalResultsMsg;
00276 
00277   /* build an atom list, if necessary */
00278   if(requested_atoms_changed || requested_groups_changed) {
00279     resetAtomList(msg->newaid); // add all of the atom IDs
00280     totalAtomsRequested = msg->newaid.size();
00281     msg->reconfig = 1; // request a reconfig
00282     resetGroupList(msg->newgdef,&totalGroupsRequested); // add all of the group IDs
00283   }
00284   resetForceList(msg->aid,msg->f,msg->gforce); // could this be more efficient?
00285 
00286   /* now send the results */
00287   DebugM(3,"Sending results ("<<totalAtomsRequested<<" atoms requested, "
00288          <<totalGroupsRequested<<" groups requested, "
00289          <<msg->f.size()<<" forces set)\n");
00290   myComputeManager->sendComputeGlobalResults(msg);
00291   DebugM(3,"Sent.\n");
00292 }
00293 
00294 GlobalMasterServer::GlobalMasterServer(ComputeMgr *m,
00295                                        int theNumDataSenders) {
00296   DebugM(3,"Constructing GlobalMasterServer\n");
00297   myComputeManager = m;
00298   numDataSenders = theNumDataSenders;
00299   recvCount = 0; /* we haven't gotten any messages yet */
00300   firstTime = 1; /* XXX temporary */
00301   step = -1;
00302   totalAtomsRequested = 0;
00303   totalGroupsRequested = 0;
00304   DebugM(3,"done constructing\n");
00305 }
00306 
00307 GlobalMasterServer::~GlobalMasterServer() {
00308   GlobalMaster *m_i = *clientList.begin();
00309   GlobalMaster *m_e = *clientList.end();
00310   
00311   /* delete each of the masters */
00312   while(m_i != m_e) {
00313     delete m_i;
00314     m_i++;
00315   }
00316 }
00317 
00318 
00319  

Generated on Tue Nov 24 04:07:44 2009 for NAMD by  doxygen 1.3.9.1