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

Generated on Wed May 22 04:07:16 2013 for NAMD by  doxygen 1.3.9.1