ParallelIOMgr Class Reference

#include <ParallelIOMgr.h>

List of all members.

Public Member Functions

 ParallelIOMgr ()
 ~ParallelIOMgr ()
void initialize (Node *node)
void readPerAtomInfo ()
void migrateAtomsMGrp ()
void recvAtomsMGrp (MoveInputAtomsMsg *msg)
void integrateMigratedAtoms ()
void updateMolInfo ()
void recvMolInfo (MolInfoMsg *msg)
void bcastMolInfo (MolInfoMsg *msg)
void recvHydroBasedCounter (HydroBasedMsg *msg)
void bcastHydroBasedCounter (HydroBasedMsg *msg)
void calcAtomsInEachPatch ()
void recvAtomsCntPerPatch (AtomsCntPerPatchMsg *msg)
void sendAtomsToHomePatchProcs ()
void ackAtomsToHomePatchProcs ()
void recvAtomsToHomePatchProcs (MovePatchAtomsMsg *msg)
void createHomePatches ()
void freeMolSpace ()
int getNumOutputProcs ()
bool isOutputProcessor (int pe)
void recvClusterSize (ClusterSizeMsg *msg)
void integrateClusterSize ()
void recvFinalClusterSize (ClusterSizeMsg *msg)
void receivePositions (CollectVectorVarMsg *msg)
void receiveVelocities (CollectVectorVarMsg *msg)
void receiveForces (CollectVectorVarMsg *msg)
void disposePositions (int seq, double prevT)
void disposeVelocities (int seq, double prevT)
void disposeForces (int seq, double prevT)
void wrapCoor (int seq, Lattice lat)
void recvClusterCoor (ClusterCoorMsg *msg)
void recvFinalClusterCoor (ClusterCoorMsg *msg)

Public Attributes

CthThread sendAtomsThread
int numAcksOutstanding

Detailed Description

Definition at line 153 of file ParallelIOMgr.h.


Constructor & Destructor Documentation

ParallelIOMgr::ParallelIOMgr (  ) 

Definition at line 152 of file ParallelIOMgr.C.

References sendAtomsThread, Vector::x, Vector::y, and Vector::z.

00153 {
00154     CkpvAccess(BOCclass_group).ioMgr = thisgroup;
00155 
00156     numInputProcs=-1;
00157     inputProcArray = NULL;
00158     numOutputProcs=-1;
00159     outputProcArray = NULL;
00160 
00161     procsReceived=0;
00162     hydroMsgRecved=0;
00163 
00164     totalMV.x = totalMV.y = totalMV.z = 0.0;
00165     totalMass = 0.0;
00166     totalCharge = 0.0;
00167     numTotalExclusions = 0;
00168     numCalcExclusions = 0;
00169     numCalcFullExclusions = 0;
00170 
00171     isOKToRecvHPAtoms = false;
00172     hpAtomsList = NULL;
00173 
00174     clusterID = NULL;
00175     clusterSize = NULL;
00176 
00177 #ifdef MEM_OPT_VERSION
00178     midCM = NULL;
00179 #endif
00180 
00181     isWater = NULL;
00182 
00183     numCSMAck = 0;
00184     numReqRecved = 0;
00185 
00186     sendAtomsThread = 0;
00187 
00188 #if COLLECT_PERFORMANCE_DATA
00189     numFixedAtomLookup = 0;
00190 #endif
00191 }

ParallelIOMgr::~ParallelIOMgr (  ) 

Definition at line 193 of file ParallelIOMgr.C.

00194 {
00195     delete [] inputProcArray;
00196     delete [] outputProcArray;
00197     delete [] clusterID;
00198     delete [] clusterSize;
00199 
00200 #ifdef MEM_OPT_VERSION
00201     delete midCM;
00202 #endif
00203 
00204     delete [] isWater;
00205 }


Member Function Documentation

void ParallelIOMgr::ackAtomsToHomePatchProcs (  ) 

Definition at line 1498 of file ParallelIOMgr.C.

References numAcksOutstanding, and sendAtomsThread.

01499 {
01500   --numAcksOutstanding;
01501   if ( sendAtomsThread ) {
01502     CthAwaken(sendAtomsThread);
01503     sendAtomsThread = 0;
01504   }
01505 }

void ParallelIOMgr::bcastHydroBasedCounter ( HydroBasedMsg msg  ) 

Definition at line 1206 of file ParallelIOMgr.C.

References endi(), SimParameters::fixedAtomsOn, iINFO(), iout, SimParameters::lattice, Molecule::maxHydrogenGroupSize, Molecule::maxMigrationGroupSize, Molecule::num_deg_freedom(), Molecule::numAngles, Molecule::numAtoms, Molecule::numBonds, Molecule::numCrossterms, Molecule::numDihedrals, Molecule::numExclusions, Molecule::numFixedAtoms, HydroBasedMsg::numFixedGroups, Molecule::numFixedGroups, HydroBasedMsg::numFixedRigidBonds, Molecule::numFixedRigidBonds, Molecule::numHydrogenGroups, Molecule::numImpropers, Molecule::numMigrationGroups, Molecule::numMultipleDihedrals, Molecule::numMultipleImpropers, Molecule::numRigidBonds, SimParameters::paraTypeCharmmOn, SimParameters::paraTypeXplorOn, SimParameters::rigidBonds, and Lattice::volume().

01206                                                             {
01207 #ifdef MEM_OPT_VERSION
01208     //only the rank 0 in the SMP node update the Molecule object
01209     if(CmiMyRank()) {
01210         delete msg;
01211         return;
01212     }
01213     molecule->numFixedRigidBonds = msg->numFixedRigidBonds;
01214     molecule->numFixedGroups = msg->numFixedGroups;
01215     delete msg;
01216 
01217     if(!CkMyPe()) {
01218         iout << iINFO << "****************************\n";
01219         iout << iINFO << "STRUCTURE SUMMARY:\n";
01220         iout << iINFO << molecule->numAtoms << " ATOMS\n";
01221         iout << iINFO << molecule->numBonds << " BONDS\n";
01222         iout << iINFO << molecule->numAngles << " ANGLES\n";
01223         iout << iINFO << molecule->numDihedrals << " DIHEDRALS\n";
01224         iout << iINFO << molecule->numImpropers << " IMPROPERS\n";
01225         iout << iINFO << molecule->numCrossterms << " CROSSTERMS\n";
01226         iout << iINFO << molecule->numExclusions << " EXCLUSIONS\n";
01227 
01228             //****** BEGIN CHARMM/XPLOR type changes
01229         if ((molecule->numMultipleDihedrals) && (simParameters->paraTypeXplorOn)){
01230             iout << iINFO << molecule->numMultipleDihedrals 
01231              << " DIHEDRALS WITH MULTIPLE PERIODICITY (BASED ON PSF FILE)\n";
01232         }
01233         if ((molecule->numMultipleDihedrals) && (simParameters->paraTypeCharmmOn)){
01234             iout << iINFO << molecule->numMultipleDihedrals 
01235          << " DIHEDRALS WITH MULTIPLE PERIODICITY IGNORED (BASED ON PSF FILE) \n";
01236             iout << iINFO  
01237          << " CHARMM MULTIPLICITIES BASED ON PARAMETER FILE INFO! \n";
01238         }
01239             //****** END CHARMM/XPLOR type changes
01240 
01241         if (molecule->numMultipleImpropers){
01242             iout << iINFO << molecule->numMultipleImpropers 
01243                  << " IMPROPERS WITH MULTIPLE PERIODICITY\n";
01244         }
01245 
01246         if (simParameters->fixedAtomsOn)
01247            iout << iINFO << molecule->numFixedAtoms << " FIXED ATOMS\n";
01248         
01249 
01250         if (simParameters->rigidBonds)        
01251            iout << iINFO << molecule->numRigidBonds << " RIGID BONDS\n";        
01252 
01253         if (simParameters->fixedAtomsOn && simParameters->rigidBonds)        
01254            iout << iINFO << molecule->numFixedRigidBonds <<
01255                 " RIGID BONDS BETWEEN FIXED ATOMS\n";
01256 
01257         iout << iINFO << molecule->num_deg_freedom(1)
01258              << " DEGREES OF FREEDOM\n";
01259 
01260         iout << iINFO << molecule->numHydrogenGroups << " HYDROGEN GROUPS\n";
01261         iout << iINFO << molecule->maxHydrogenGroupSize
01262             << " ATOMS IN LARGEST HYDROGEN GROUP\n";
01263         iout << iINFO << molecule->numMigrationGroups << " MIGRATION GROUPS\n";
01264         iout << iINFO << molecule->maxMigrationGroupSize
01265             << " ATOMS IN LARGEST MIGRATION GROUP\n";
01266         if (simParameters->fixedAtomsOn)
01267         {
01268            iout << iINFO << molecule->numFixedGroups <<
01269                 " HYDROGEN GROUPS WITH ALL ATOMS FIXED\n";
01270         }
01271         
01272         iout << iINFO << "TOTAL MASS = " << totalMass << " amu\n"; 
01273         iout << iINFO << "TOTAL CHARGE = " << totalCharge << " e\n"; 
01274 
01275         BigReal volume = simParameters->lattice.volume();
01276         if ( volume ) {
01277             iout << iINFO << "MASS DENSITY = "
01278                 << ((totalMass/volume) / 0.6022) << " g/cm^3\n";
01279             iout << iINFO << "ATOM DENSITY = "
01280                 << (molecule->numAtoms/volume) << " atoms/A^3\n";
01281         }
01282     
01283         iout << iINFO << "*****************************\n";
01284         iout << endi;
01285         fflush(stdout);               
01286     }
01287 #endif
01288 }

void ParallelIOMgr::bcastMolInfo ( MolInfoMsg msg  ) 

Definition at line 1147 of file ParallelIOMgr.C.

References SimParameters::comMove, endi(), iINFO(), iout, MolInfoMsg::numAngles, Molecule::numAngles, MolInfoMsg::numBonds, Molecule::numBonds, MolInfoMsg::numCalcAngles, Molecule::numCalcAngles, MolInfoMsg::numCalcBonds, Molecule::numCalcBonds, MolInfoMsg::numCalcCrossterms, Molecule::numCalcCrossterms, MolInfoMsg::numCalcDihedrals, Molecule::numCalcDihedrals, MolInfoMsg::numCalcExclusions, Molecule::numCalcExclusions, MolInfoMsg::numCalcFullExclusions, Molecule::numCalcFullExclusions, MolInfoMsg::numCalcImpropers, Molecule::numCalcImpropers, MolInfoMsg::numCrossterms, Molecule::numCrossterms, MolInfoMsg::numDihedrals, Molecule::numDihedrals, MolInfoMsg::numExclusions, MolInfoMsg::numImpropers, Molecule::numImpropers, MolInfoMsg::numRigidBonds, Molecule::numRigidBonds, Molecule::numTotalExclusions, PDBVELFACTOR, ResizeArray< Elem >::size(), MolInfoMsg::totalMass, and MolInfoMsg::totalMV.

01148 {
01149 #ifdef MEM_OPT_VERSION
01150     if(myInputRank!=-1) {
01151         if(!simParameters->comMove) {
01152             //needs to remove the center of mass motion from a molecule
01153             Vector val = msg->totalMV / msg->totalMass;
01154             for (int i=0; i<initAtoms.size(); i++) initAtoms[i].velocity -= val;
01155         }
01156     }
01157 
01158     //only the rank 0 in the SMP node update the Molecule object
01159     if(CmiMyRank()) {
01160         delete msg;
01161         return;
01162     }
01163 
01164     molecule->numBonds = msg->numBonds;
01165     molecule->numCalcBonds = msg->numCalcBonds;
01166     molecule->numAngles = msg->numAngles;
01167     molecule->numCalcAngles = msg->numCalcAngles;
01168     molecule->numDihedrals = msg->numDihedrals;
01169     molecule->numCalcDihedrals = msg->numCalcDihedrals;
01170     molecule->numImpropers = msg->numImpropers;
01171     molecule->numCalcImpropers = msg->numCalcImpropers;
01172     molecule->numCrossterms = msg->numCrossterms;
01173     molecule->numCalcCrossterms = msg->numCalcCrossterms;
01174 
01175     molecule->numTotalExclusions = msg->numExclusions;
01176     molecule->numCalcExclusions = msg->numCalcExclusions;
01177     molecule->numCalcFullExclusions = msg->numCalcFullExclusions;
01178 
01179     molecule->numRigidBonds = msg->numRigidBonds;
01180     delete msg;
01181 
01182     if(!CkMyPe()) {
01183         iout << iINFO << "LOADED " << molecule->numTotalExclusions << " TOTAL EXCLUSIONS\n" << endi;
01184         if(!simParameters->comMove) {
01185             iout << iINFO << "REMOVING COM VELOCITY "
01186                  << (PDBVELFACTOR * (msg->totalMV / msg->totalMass))<< "\n" <<endi;
01187         }
01188     }
01189 #endif
01190 }

void ParallelIOMgr::calcAtomsInEachPatch (  ) 

Definition at line 1290 of file ParallelIOMgr.C.

References PatchMap::assignToPatch(), AtomsCntPerPatchMsg::atomsCntList, AtomsCntPerPatchMsg::fixedAtomsCntList, SimParameters::fixedAtomsOn, PatchMap::getTmpPatchAtomsList(), PatchMap::initTmpPatchAtomsList(), InputAtom::isMP, InputAtom::isValid, j, SimParameters::lattice, AtomsCntPerPatchMsg::length, NAMD_die(), PatchMap::numPatches(), numPatches, PatchMap::Object(), AtomsCntPerPatchMsg::pidList, CompAtom::position, and ResizeArray< Elem >::size().

01291 {
01292     if(myInputRank==-1) return;
01293 
01294     PatchMap *patchMap = PatchMap::Object();
01295     int numPatches = patchMap->numPatches();
01296 
01297     patchMap->initTmpPatchAtomsList();
01298 
01299     //each list contains the atom index to the initAtoms
01300     vector<int> *eachPatchAtomList = patchMap->getTmpPatchAtomsList();
01301 
01302     CProxy_PatchMgr pm(CkpvAccess(BOCclass_group).patchMgr);
01303     PatchMgr *patchMgr = pm.ckLocalBranch();
01304 
01305     int pid=0;
01306     const Lattice lattice = simParameters->lattice;
01307     for(int i=0; i<initAtoms.size(); i++) {
01308         InputAtom *atom = &(initAtoms[i]);
01309         if(!atom->isValid) continue;
01310         if(atom->isMP) {
01311             pid = patchMap->assignToPatch(atom->position, lattice);
01312         }
01313         eachPatchAtomList[pid].push_back(i);
01314     }
01315 
01316     CProxy_ParallelIOMgr pIO(thisgroup);
01317 
01318     int patchCnt = 0;
01319     for(int i=0; i<numPatches; i++) {
01320         int cursize = eachPatchAtomList[i].size();
01321         if(cursize>0) patchCnt++;
01322     }
01323 
01324     AtomsCntPerPatchMsg *msg = NULL;
01325     if(simParameters->fixedAtomsOn) {
01326         msg = new (patchCnt, patchCnt, patchCnt, 0)AtomsCntPerPatchMsg;
01327     } else {
01328         msg = new (patchCnt, patchCnt, 0, 0)AtomsCntPerPatchMsg;
01329     }
01330 
01331     msg->length = patchCnt;
01332     patchCnt = 0;
01333     for(int i=0; i<numPatches; i++) {
01334         int cursize = eachPatchAtomList[i].size();
01335         if(cursize>0) {
01336             if ( cursize > USHRT_MAX ) {
01337               char errstr[512];
01338               sprintf(errstr, "Patch %d exceeds %d atoms.", i, USHRT_MAX);
01339               NAMD_die(errstr);
01340             }
01341             msg->pidList[patchCnt] = i;
01342             msg->atomsCntList[patchCnt] = cursize;
01343             patchCnt++;
01344         }
01345     }
01346 
01347     if(simParameters->fixedAtomsOn) {
01348         patchCnt = 0;
01349         for(int i=0; i<numPatches; i++) {
01350             int cursize = eachPatchAtomList[i].size();
01351             if(cursize>0) {
01352                 int fixedCnt = 0;
01353                 for(int j=0; j<cursize; j++) {
01354                     int aid = eachPatchAtomList[i][j];
01355                     //atomFixed is either 0 or 1
01356                     fixedCnt += initAtoms[aid].atomFixed;
01357                 }
01358                 msg->fixedAtomsCntList[patchCnt] = fixedCnt;
01359                 patchCnt++;
01360             }
01361         }
01362     }
01363 
01364     pIO[0].recvAtomsCntPerPatch(msg);
01365 
01366 }

void ParallelIOMgr::createHomePatches (  ) 

Definition at line 1571 of file ParallelIOMgr.C.

References ResizeArray< Elem >::clear(), PatchMgr::createHomePatch(), PatchMap::node(), PatchMap::numPatches(), PatchMap::numPatchesOnNode(), Node::Object(), PatchMap::Object(), ResizeArray< Elem >::size(), sort, and Node::workDistrib.

01572 {
01573 #ifdef MEM_OPT_VERSION
01574 
01575     int assignedPids = PatchMap::Object()->numPatchesOnNode(CkMyPe());
01576     int numPids = hpIDList.size();
01577     if(numPids==0){
01578         //this node actually contains no homepatches
01579         if(assignedPids == 0) return; 
01580 
01581         //Entering the rare condition that all the homepatches this node has
01582         //are empty so that "recvAtomsToHomePatchProcs" is never called!
01583         //But we still need to create those empty homepatches!
01584         CmiAssert(isOKToRecvHPAtoms == false);        
01585         PatchMap *patchMap = PatchMap::Object();
01586         CProxy_PatchMgr pm(CkpvAccess(BOCclass_group).patchMgr);
01587         PatchMgr *patchMgr = pm.ckLocalBranch();
01588         for(int i=0; i<patchMap->numPatches(); i++) {
01589             if(patchMap->node(i)==CkMyPe()) {
01590                 FullAtomList emptyone;
01591                 patchMgr->createHomePatch(i, emptyone);
01592             }
01593         }        
01594         return;
01595     }
01596 
01597     CProxy_PatchMgr pm(CkpvAccess(BOCclass_group).patchMgr);
01598     PatchMgr *patchMgr = pm.ckLocalBranch();
01599 
01600     //go through the home patch list
01601     for(int i=0; i<numPids; i++) {
01602         int pid = hpIDList[i];
01603 
01604         //re-sort the atom list of this patch
01605         std::sort(hpAtomsList[i].begin(), hpAtomsList[i].end());
01606         Node::Object()->workDistrib->fillAtomListForOnePatch(pid, hpAtomsList[i]);
01607         patchMgr->createHomePatch(pid, hpAtomsList[i]);
01608     }
01609 
01610     hpIDList.clear();   
01611     delete [] hpAtomsList;
01612 
01613     hpAtomsList = NULL;
01614 #endif
01615 }

void ParallelIOMgr::disposeForces ( int  seq,
double  prevT 
)

Definition at line 1814 of file ParallelIOMgr.C.

01815 {
01816 #ifdef MEM_OPT_VERSION
01817         double iotime = CmiWallTimer();
01818     midCM->disposeForces(seq);
01819         iotime = CmiWallTimer()-iotime+prevT;
01820     
01821 #if OUTPUT_SINGLE_FILE
01822         //Token-based file output
01823     if(myOutputRank==getMyOutputGroupHighestRank()) {
01824         //notify the CollectionMaster to start the next round
01825         CProxy_CollectionMaster cm(mainMaster);
01826         cm.startNextRoundOutputForce(iotime);
01827     } else {
01828         CProxy_ParallelIOMgr io(thisgroup);
01829         io[outputProcArray[myOutputRank+1]].disposeForces(seq, iotime);
01830     }
01831 #else
01832         //notify the CollectionMaster to start the next round
01833         CProxy_CollectionMaster cm(mainMaster);
01834         cm.startNextRoundOutputForce(iotime);   
01835 #endif
01836 
01837 #endif
01838 }

void ParallelIOMgr::disposePositions ( int  seq,
double  prevT 
)

Definition at line 1762 of file ParallelIOMgr.C.

01763 {
01764 #ifdef MEM_OPT_VERSION
01765         double iotime = CmiWallTimer();
01766     midCM->disposePositions(seq);
01767         iotime = CmiWallTimer()-iotime+prevT;
01768 
01769 #if OUTPUT_SINGLE_FILE    
01770         //Token-based file output
01771     if(myOutputRank == getMyOutputGroupHighestRank()) {
01772         //notify the CollectionMaster to start the next round
01773         CProxy_CollectionMaster cm(mainMaster);
01774         cm.startNextRoundOutputPos(iotime);
01775     } else {
01776         CProxy_ParallelIOMgr io(thisgroup);
01777         io[outputProcArray[myOutputRank+1]].disposePositions(seq, iotime);
01778     }
01779 #else
01780         //notify the CollectionMaster to start the next round
01781         CProxy_CollectionMaster cm(mainMaster);
01782         cm.startNextRoundOutputPos(iotime);
01783 #endif
01784 
01785 #endif
01786 }

void ParallelIOMgr::disposeVelocities ( int  seq,
double  prevT 
)

Definition at line 1788 of file ParallelIOMgr.C.

01789 {
01790 #ifdef MEM_OPT_VERSION
01791         double iotime = CmiWallTimer();
01792     midCM->disposeVelocities(seq);
01793         iotime = CmiWallTimer()-iotime+prevT;
01794     
01795 #if OUTPUT_SINGLE_FILE
01796         //Token-based file output
01797     if(myOutputRank==getMyOutputGroupHighestRank()) {
01798         //notify the CollectionMaster to start the next round
01799         CProxy_CollectionMaster cm(mainMaster);
01800         cm.startNextRoundOutputVel(iotime);
01801     } else {
01802         CProxy_ParallelIOMgr io(thisgroup);
01803         io[outputProcArray[myOutputRank+1]].disposeVelocities(seq, iotime);
01804     }
01805 #else
01806         //notify the CollectionMaster to start the next round
01807         CProxy_CollectionMaster cm(mainMaster);
01808         cm.startNextRoundOutputVel(iotime);     
01809 #endif
01810 
01811 #endif
01812 }

void ParallelIOMgr::freeMolSpace (  ) 

Definition at line 1617 of file ParallelIOMgr.C.

References SimParameters::freeEnergyOn.

01618 {
01619 #ifdef MEM_OPT_VERSION
01620     molecule->delAtomNames();
01621     molecule->delChargeSpace();
01622 
01623     //???TODO NOT SURE WHETHER freeEnergyOn is support in MEM_OPT_VERSION
01624     //-CHAOMEI
01625     if(!CkMyPe() && !simParameters->freeEnergyOn)
01626         molecule->delMassSpace();
01627 
01628     molecule->delFixedAtoms();
01629 #endif
01630 }

int ParallelIOMgr::getNumOutputProcs (  )  [inline]

Definition at line 388 of file ParallelIOMgr.h.

00388 { return numOutputProcs; }

void ParallelIOMgr::initialize ( Node node  ) 

Definition at line 212 of file ParallelIOMgr.C.

References UniqueSet< Elem >::clear(), endi(), CollectionMgr::getMasterChareID(), iINFO(), iout, Node::molecule, NAMD_bug(), SimParameters::numinputprocs, SimParameters::numoutputprocs, SimParameters::numoutputwrts, CollectionMgr::Object(), WorkDistrib::peCompactOrderingIndex, WorkDistrib::peDiffuseOrdering, ResizeArray< Elem >::resize(), Node::simParameters, and sort.

00213 {
00214     simParameters = node->simParameters;
00215     molecule = node->molecule;
00216 
00217     numInputProcs = simParameters->numinputprocs;
00218     numOutputProcs = simParameters->numoutputprocs;
00219     numOutputWrts = simParameters->numoutputwrts;
00220 
00221     numProxiesPerOutputProc = std::min((int)sqrt(CkNumPes()),(CkNumPes()-1)/numOutputProcs-1);
00222     if ( numProxiesPerOutputProc < 2 ) numProxiesPerOutputProc = 0;
00223 
00224     if(!CkMyPe()) {
00225         iout << iINFO << "Running with " <<numInputProcs<<" input processors.\n"<<endi;
00226         #if OUTPUT_SINGLE_FILE
00227         iout << iINFO << "Running with " <<numOutputProcs<<" output processors ("<<numOutputWrts<<" of them will output simultaneously).\n"<<endi;
00228         #else
00229         iout << iINFO << "Running with " <<numOutputProcs<<" output processors, and each of them will output to its own separate file.\n"<<endi;
00230         #endif
00231         if ( numProxiesPerOutputProc ) {
00232             iout << iINFO << "Running with " <<numProxiesPerOutputProc<<" proxies per output processor.\n"<<endi;
00233         }
00234     }
00235 
00236     //build inputProcArray
00237    {
00238     inputProcArray = new int[numInputProcs];
00239     myInputRank = -1;
00240     for(int i=0; i<numInputProcs; ++i) {
00241       inputProcArray[i] = WorkDistrib::peDiffuseOrdering[(1+numOutputProcs+i)%CkNumPes()];
00242     }
00243     std::sort(inputProcArray, inputProcArray+numInputProcs);
00244     for(int i=0; i<numInputProcs; ++i) {
00245       if ( CkMyPe() == inputProcArray[i] ) {
00246         if ( myInputRank != -1 ) NAMD_bug("Duplicate input proc");
00247         myInputRank = i;
00248       }
00249     }
00250 
00251     if(!CkMyPe()) {
00252       iout << iINFO << "INPUT PROC LOCATIONS:";
00253       int i;
00254       for ( i=0; i<numInputProcs && i < 10; ++i ) {
00255         iout << " " << inputProcArray[i];
00256       }
00257       if ( i<numInputProcs ) iout << " ... " << inputProcArray[numInputProcs-1];
00258       iout << "\n" << endi;
00259     }
00260    }
00261 
00262     if(myInputRank!=-1) {
00263         //NOTE: this could further be optimized by pre-allocate the memory
00264         //for incoming atoms --Chao Mei
00265         int numMyAtoms = numInitMyAtomsOnInput();
00266         initAtoms.resize(numMyAtoms+100);  // extra space for orphan hydrogens
00267         initAtoms.resize(numMyAtoms);
00268         tmpRecvAtoms.resize(0);
00269     } else {
00270         initAtoms.resize(0);
00271         tmpRecvAtoms.resize(0);
00272     }
00273     hpIDList.resize(0);
00274 
00275     //build outputProcArray
00276     //spread the output processors across all the processors
00277    {
00278     outputProcArray = new int[numOutputProcs];
00279     outputProcFlags = new char[CkNumPes()];
00280     outputProxyArray = new int[numOutputProcs*numProxiesPerOutputProc];
00281     myOutputProxies = new int[numOutputProcs];
00282     myOutputRank = -1;
00283     myOutputProxyRank = -1;
00284     for(int i=0; i<numOutputProcs; ++i) {
00285       outputProcArray[i] = WorkDistrib::peDiffuseOrdering[(1+i)%CkNumPes()];
00286     }
00287     std::sort(outputProcArray, outputProcArray+numOutputProcs);
00288     for(int i=0; i<numOutputProcs*numProxiesPerOutputProc; ++i) {
00289       outputProxyArray[i] = WorkDistrib::peDiffuseOrdering[(1+numOutputProcs+i)%CkNumPes()];
00290     }
00291     std::sort(outputProxyArray, outputProxyArray+numOutputProcs*numProxiesPerOutputProc,
00292        WorkDistrib::pe_sortop_compact());
00293     for(int i=0; i<CkNumPes(); ++i) {
00294       outputProcFlags[i] = 0;
00295     }
00296     for(int i=0; i<numOutputProcs; ++i) {
00297       outputProcFlags[outputProcArray[i]] = 1;
00298       if ( CkMyPe() == outputProcArray[i] ) {
00299         if ( myOutputRank != -1 ) NAMD_bug("Duplicate output proc");
00300         myOutputRank = i;
00301       }
00302     }
00303     for(int i=0; i<numOutputProcs*numProxiesPerOutputProc; ++i) {
00304       if ( CkMyPe() == outputProxyArray[i] ) {
00305         if ( myOutputRank != -1 ) NAMD_bug("Output proxy is also output proc");
00306         if ( myOutputProxyRank != -1 ) NAMD_bug("Duplicate output proxy");
00307         myOutputProxyRank = i;
00308       }
00309     }
00310     int myProxySet = (WorkDistrib::peCompactOrderingIndex[CkMyPe()]*numProxiesPerOutputProc)/CkNumPes();
00311     for(int i=0; i<numOutputProcs; ++i) {
00312       if ( numProxiesPerOutputProc ) {
00313         myOutputProxies[i] = outputProxyArray[myProxySet*numOutputProcs+i];
00314       } else {
00315         myOutputProxies[i] = outputProcArray[i];
00316       }
00317     }
00318 
00319     // delay building sequences until after PatchMap is initialized
00320     myOutputProxyPositions = 0;
00321     myOutputProxyVelocities = 0;
00322     myOutputProxyForces = 0;
00323 
00324     if(!CkMyPe()) {
00325       iout << iINFO << "OUTPUT PROC LOCATIONS:";
00326       int i;
00327       for ( i=0; i<numOutputProcs && i < 10; ++i ) {
00328         iout << " " << outputProcArray[i];
00329       }
00330       if ( i<numOutputProcs ) iout << " ... " << outputProcArray[numOutputProcs-1];
00331       iout << "\n" << endi;
00332     }
00333    }
00334 
00335 #ifdef MEM_OPT_VERSION
00336     if(myOutputRank!=-1) {
00337         midCM = new CollectionMidMaster(this);
00338     }
00339     remoteClusters.clear();
00340     csmBuf.resize(0);
00341     remoteCoors.clear();
00342     ccmBuf.resize(0);
00343 
00344     mainMaster = CollectionMgr::Object()->getMasterChareID();
00345 #endif
00346 }

void ParallelIOMgr::integrateClusterSize (  ) 

Definition at line 677 of file ParallelIOMgr.C.

References ClusterSizeMsg::atomsCnt, ClusterSizeMsg::clusterId, recvFinalClusterSize(), ResizeArray< Elem >::resize(), ResizeArray< Elem >::size(), ClusterSizeMsg::srcRank, SimParameters::wrapAll, and SimParameters::wrapWater.

00678 {
00679     if(myOutputRank==-1) return;
00680     if(!(simParameters->wrapAll || simParameters->wrapWater)) return;
00681 
00682     int fromIdx, toIdx; //atoms' range
00683     getMyAtomsRangeOnOutput(fromIdx,toIdx);
00684 
00685     //calculated the final cluster size
00686     for(int i=0; i<csmBuf.size(); i++) {
00687         ClusterSizeMsg *msg = csmBuf[i];
00688         int lidx = msg->clusterId - fromIdx;
00689         clusterSize[lidx] += msg->atomsCnt;
00690     }
00691 
00692     CProxy_ParallelIOMgr pIO(thisgroup);
00693     for(int i=0; i<csmBuf.size(); i++) {
00694         ClusterSizeMsg *msg = csmBuf[i];
00695         int lidx = msg->clusterId - fromIdx;
00696         msg->atomsCnt = clusterSize[lidx];
00697         pIO[outputProcArray[msg->srcRank]].recvFinalClusterSize(msg);
00698     }
00699     numRemoteReqs = csmBuf.size();
00700     csmBuf.resize(0);
00701     
00702     //There's a possible msg race problem here that recvFinalClusterSize 
00703     //executes before integrateClusterSize because other proc finishes faster
00704     //in calculating the cluster size. The recvFinalClusterSize should be
00705     //executed after integrateClusterSize. To avoid this, a self message is
00706     //sent to participate the reduction.
00707     if(numRemoteClusters!=0){
00708         recvFinalClusterSize(NULL);
00709     }else{
00710         //this output proc already has the final cluster size for each atom
00711         int numMyAtoms = toIdx-fromIdx+1;
00712         for(int i=0; i<numMyAtoms; i++) {
00713             int lidx = clusterID[i]-fromIdx;
00714             clusterSize[i] = clusterSize[lidx];
00715         }
00716         
00717         #if 0 //write out cluster debug info
00718         char fname[128];
00719         sprintf(fname, "cluster.par.%d", CkMyPe());
00720         FILE *ofp = fopen(fname, "w");
00721         for(int i=0; i<numMyAtoms; i++) {
00722             fprintf(ofp, "%d: %d: %d\n", i+fromIdx, clusterID[i], clusterSize[i]);
00723         }
00724         fclose(ofp);
00725         #endif
00726     }
00727 }

void ParallelIOMgr::integrateMigratedAtoms (  ) 

Definition at line 836 of file ParallelIOMgr.C.

References ResizeArray< Elem >::add(), ResizeArray< Elem >::begin(), ResizeArray< Elem >::clear(), ResizeArray< Elem >::end(), CompAtom::hydrogenGroupSize, InputAtom::isGP, InputAtom::isValid, j, Molecule::numFixedAtoms, HydroBasedMsg::numFixedGroups, HydroBasedMsg::numFixedRigidBonds, Molecule::numRigidBonds, FullAtom::rigidBondLength, ResizeArray< Elem >::size(), and sort.

00837 {
00838     if(myInputRank==-1) return;
00839 
00840     for(int i=0; i<tmpRecvAtoms.size(); i++) {
00841         tmpRecvAtoms[i].isValid = true;
00842         initAtoms.add(tmpRecvAtoms[i]);
00843     }
00844     tmpRecvAtoms.clear();
00845 
00846     //sort atom list based on hydrogenList value
00847     std::sort(initAtoms.begin(), initAtoms.end());
00848 
00849     //now compute the counters inside Molecule such as numFixedRigidBonds
00850     //which is based on the hydrogen group info
00851 
00852     int numFixedRigidBonds = 0;
00853     if(molecule->numRigidBonds){
00854         int parentIsFixed = 0;
00855         for(int i=0; i<initAtoms.size(); i++) {
00856             InputAtom *one = &(initAtoms[i]);
00857             if(!one->isValid) continue;
00858             if(one->isGP) {
00859                 parentIsFixed = one->atomFixed;
00860                 InputAtom *a1 = &(initAtoms[i+1]);
00861                 InputAtom *a2 = &(initAtoms[i+2]);
00862                 if((one->rigidBondLength>0.0) &&
00863                    a1->atomFixed && a2->atomFixed) {
00864                     numFixedRigidBonds++;
00865                 }
00866             }else{
00867                 if((one->rigidBondLength>0.0) &&
00868                    one->atomFixed && parentIsFixed) {
00869                     numFixedRigidBonds++;
00870                 }
00871             }
00872         }
00873     }
00874 
00875     int numFixedGroups = 0;
00876     if(molecule->numFixedAtoms){        
00877         for(int i=0; i<initAtoms.size();) {
00878             InputAtom *one = &(initAtoms[i]);
00879             if(!one->isValid){
00880                 i++;
00881                 continue;
00882             }
00883             if(one->isGP) {
00884                 int allFixed = 1;                
00885                 for(int j=0; j<one->hydrogenGroupSize; j++){
00886                     InputAtom *a1 = &(initAtoms[i+j]);
00887                     allFixed = allFixed & a1->atomFixed;
00888                     if(!allFixed) break;
00889                 }
00890                 if(allFixed) numFixedGroups++;                
00891                 i += one->hydrogenGroupSize;
00892             }
00893         }
00894     }
00895     
00896     CProxy_ParallelIOMgr pIO(thisgroup);
00897     HydroBasedMsg *msg = new HydroBasedMsg;
00898     msg->numFixedGroups = numFixedGroups;
00899     msg->numFixedRigidBonds = numFixedRigidBonds;
00900     pIO[0].recvHydroBasedCounter(msg);
00901 }

bool ParallelIOMgr::isOutputProcessor ( int  pe  ) 

Definition at line 348 of file ParallelIOMgr.C.

00348                                             {
00349    return outputProcFlags[pe];
00350 }

void ParallelIOMgr::migrateAtomsMGrp (  ) 

Definition at line 776 of file ParallelIOMgr.C.

References ResizeArray< Elem >::add(), MoveInputAtomsMsg::atomList, ResizeArray< Elem >::begin(), ResizeArray< Elem >::clear(), MoveInputAtomsMsg::length, and ResizeArray< Elem >::size().

00777 {
00778     if(myInputRank==-1) return;
00779 
00780     //1. first get the list of atoms to be migrated
00781     //which should be few compared with the number of atoms
00782     //initially assigned to this input proc.
00783     AtomIDList toMigrateList; //the list of atoms to be migrated
00784     //the max distance from this processor of atoms to be sent
00785     int maxOffset = 0;
00786     for(int i=0; i<initAtoms.size(); i++) {
00787         //returns the proc id on which atom MPID resides on
00788         int parentRank = atomInitRankOnInput(initAtoms[i].MPID);
00789         if(parentRank != myInputRank) {
00790             toMigrateList.add(i);
00791             initAtoms[i].isValid = false;
00792             int tmp = parentRank - myInputRank;
00793             tmp = tmp>0 ? tmp : -tmp;
00794             if(tmp > maxOffset) maxOffset = tmp;
00795         }
00796     }
00797 
00798     //2. prepare atom migration messages
00799     //the messages are indexed as [-maxOffset,..., -1,0,1,..., maxOffset]
00800     //where the "0" is not used at all. It is added for the sake of
00801     //computing the index easily.
00802     InputAtomList *migLists = new InputAtomList[2*maxOffset+1];
00803     for(int i=0; i<toMigrateList.size(); i++) {
00804         int idx = toMigrateList[i];
00805         int parentRank = atomInitRankOnInput(initAtoms[idx].MPID);
00806         //decide which migList to put this atom
00807         int offset = parentRank - myInputRank + maxOffset;
00808         migLists[offset].add(initAtoms[idx]);
00809     }
00810 
00811     CProxy_ParallelIOMgr pIO(thisgroup);
00812     for(int i=0; i<2*maxOffset+1; i++) {
00813         int migLen = migLists[i].size();
00814         if(migLen>0) {
00815             MoveInputAtomsMsg *msg = new (migLen, 0)MoveInputAtomsMsg;
00816             msg->length = migLen;
00817             memcpy(msg->atomList, migLists[i].begin(), sizeof(InputAtom)*migLen);
00818             int destRank = i-maxOffset+myInputRank;
00819             pIO[inputProcArray[destRank]].recvAtomsMGrp(msg);
00820             migLists[i].clear();
00821         }
00822     }
00823     
00824     toMigrateList.clear();
00825     delete [] migLists;
00826 }

void ParallelIOMgr::readPerAtomInfo (  ) 

Definition at line 358 of file ParallelIOMgr.C.

References j, SimParameters::wrapAll, and SimParameters::wrapWater.

00359 {
00360 #ifdef MEM_OPT_VERSION
00361     if(myInputRank!=-1) {
00362         int myAtomLIdx, myAtomUIdx;
00363         getMyAtomsInitRangeOnInput(myAtomLIdx, myAtomUIdx);
00364 
00365         //1. read the file that contains per-atom info such as signature index
00366         molecule->read_binary_atom_info(myAtomLIdx, myAtomUIdx, initAtoms);
00367 
00368         //2. read coordinates and velocities of each atom if the velocity file
00369         //exists, otherwise, the velocity of each atom is randomly generated.
00370         //This has to be DONE AFTER THE FIRST STEP as the atom mass is required
00371         //if the velocity is generated randomly.
00372         readCoordinatesAndVelocity();
00373 
00374         //3. set every atom's output processor rank, i.e. the dest pe this
00375         //atom will be sent for writing positions and velocities etc.
00376         int oRank=atomRankOnOutput(myAtomLIdx);
00377         for(int i=oRank; i<numOutputProcs; i++) {
00378             int lIdx, uIdx; //indicates the range of atom ids outputProcArray[i] has
00379             getAtomsRangeOnOutput(lIdx, uIdx, i);
00380             if(lIdx > myAtomUIdx) break;
00381             int fid = lIdx>myAtomLIdx?lIdx:myAtomLIdx;
00382             int tid = uIdx>myAtomUIdx?myAtomUIdx:uIdx;
00383             for(int j=fid; j<=tid; j++) initAtoms[j-myAtomLIdx].outputRank = i;
00384         }
00385     }
00386 
00387     //read clusters
00388     if(myOutputRank!=-1) {
00389         //only when wrapAll or wrapWater is set, cluster info is required
00390         if(!(simParameters->wrapAll || simParameters->wrapWater)) return;
00391         readInfoForParOutput();
00392     }
00393 #endif
00394 }

void ParallelIOMgr::receiveForces ( CollectVectorVarMsg msg  ) 

Definition at line 1738 of file ParallelIOMgr.C.

References NAMD_bug(), CollectVectorVarMsg::seq, and CollectProxyVectorSequence::submitData().

01739 {
01740 #ifdef MEM_OPT_VERSION
01741   if ( myOutputRank != -1 ) {
01742     int ready = midCM->receiveForces(msg);
01743     if(ready) {
01744         CProxy_CollectionMaster cm(mainMaster);
01745         cm.receiveOutputForceReady(msg->seq);        
01746     }
01747     delete msg;
01748   } else if ( myOutputProxyRank != -1 ) {
01749     if ( ! myOutputProxyForces ) {
01750       myOutputProxyForces = new CollectProxyVectorSequence(calcMyOutputProxyClients());
01751     }
01752     CollectVectorVarMsg *newmsg = myOutputProxyForces->submitData(msg);
01753     if ( newmsg ) thisProxy[outputProcArray[myOutputProxyRank%numOutputProcs]].receiveForces(newmsg);
01754     delete msg;
01755   } else {
01756     NAMD_bug("ParallelIOMgr::receiveForces on bad pe");
01757   }
01758 #endif
01759 }

void ParallelIOMgr::receivePositions ( CollectVectorVarMsg msg  ) 

Definition at line 1692 of file ParallelIOMgr.C.

References NAMD_bug(), CollectVectorVarMsg::seq, and CollectProxyVectorSequence::submitData().

01693 {
01694 #ifdef MEM_OPT_VERSION
01695   if ( myOutputRank != -1 ) {
01696     int ready = midCM->receivePositions(msg);
01697     if(ready) {
01698         CProxy_CollectionMaster cm(mainMaster);
01699         cm.receiveOutputPosReady(msg->seq);
01700     }
01701     delete msg;
01702   } else if ( myOutputProxyRank != -1 ) {
01703     if ( ! myOutputProxyPositions ) {
01704       myOutputProxyPositions = new CollectProxyVectorSequence(calcMyOutputProxyClients());
01705     }
01706     CollectVectorVarMsg *newmsg = myOutputProxyPositions->submitData(msg);
01707     if ( newmsg ) thisProxy[outputProcArray[myOutputProxyRank%numOutputProcs]].receivePositions(newmsg);
01708     delete msg;
01709   } else {
01710     NAMD_bug("ParallelIOMgr::receivePositions on bad pe");
01711   }
01712 #endif
01713 }

void ParallelIOMgr::receiveVelocities ( CollectVectorVarMsg msg  ) 

Definition at line 1715 of file ParallelIOMgr.C.

References NAMD_bug(), CollectVectorVarMsg::seq, and CollectProxyVectorSequence::submitData().

01716 {
01717 #ifdef MEM_OPT_VERSION
01718   if ( myOutputRank != -1 ) {
01719     int ready = midCM->receiveVelocities(msg);
01720     if(ready) {
01721         CProxy_CollectionMaster cm(mainMaster);
01722         cm.receiveOutputVelReady(msg->seq);        
01723     }
01724     delete msg;
01725   } else if ( myOutputProxyRank != -1 ) {
01726     if ( ! myOutputProxyVelocities ) {
01727       myOutputProxyVelocities = new CollectProxyVectorSequence(calcMyOutputProxyClients());
01728     }
01729     CollectVectorVarMsg *newmsg = myOutputProxyVelocities->submitData(msg);
01730     if ( newmsg ) thisProxy[outputProcArray[myOutputProxyRank%numOutputProcs]].receiveVelocities(newmsg);
01731     delete msg;
01732   } else {
01733     NAMD_bug("ParallelIOMgr::receiveVelocities on bad pe");
01734   }
01735 #endif
01736 }

void ParallelIOMgr::recvAtomsCntPerPatch ( AtomsCntPerPatchMsg msg  ) 

Definition at line 1368 of file ParallelIOMgr.C.

References AtomsCntPerPatchMsg::atomsCntList, endi(), AtomsCntPerPatchMsg::fixedAtomsCntList, SimParameters::fixedAtomsOn, iINFO(), iout, AtomsCntPerPatchMsg::length, NAMD_die(), Molecule::numAtoms, PatchMap::numPatches(), Node::Object(), PatchMap::Object(), and AtomsCntPerPatchMsg::pidList.

01369 {
01370 #ifdef MEM_OPT_VERSION
01371     PatchMap *patchMap = PatchMap::Object();
01372     for(int i=0; i<msg->length; i++) {
01373         int pid = msg->pidList[i];
01374         int oldNum = patchMap->numAtoms(pid);
01375         if ( oldNum + msg->atomsCntList[i] > USHRT_MAX ) {
01376           char errstr[512];
01377           sprintf(errstr, "Patch %d exceeds %d atoms.", pid, USHRT_MAX);
01378           NAMD_die(errstr);
01379         }
01380         patchMap->setNumAtoms(pid, oldNum+msg->atomsCntList[i]);
01381         if(simParameters->fixedAtomsOn) {
01382             oldNum = patchMap->numFixedAtoms(pid);
01383             patchMap->setNumFixedAtoms(pid, oldNum+msg->fixedAtomsCntList[i]);
01384         }
01385     }
01386     delete msg;
01387 
01388     if(++procsReceived == numInputProcs) {
01389         //print max PATCH info
01390         int maxAtoms = -1;
01391         int maxPatch = -1;
01392         int totalAtoms = 0;
01393         for(int i=0; i<patchMap->numPatches(); i++) {
01394             int cnt = patchMap->numAtoms(i);
01395             totalAtoms += cnt;
01396             if(cnt>maxAtoms) {
01397                 maxAtoms = cnt;
01398                 maxPatch = i;
01399             }
01400         }
01401         procsReceived = 0;
01402         iout << iINFO << "LARGEST PATCH (" << maxPatch <<
01403              ") HAS " << maxAtoms << " ATOMS\n" << endi;
01404         if ( totalAtoms !=  Node::Object()->molecule->numAtoms ) {
01405           char errstr[512];
01406           sprintf(errstr, "Incorrect atom count in void ParallelIOMgr::recvAtomsCntPerPatch: %d vs %d", totalAtoms, Node::Object()->molecule->numAtoms);
01407           NAMD_die(errstr);
01408         }
01409     }
01410 #endif
01411 }

void ParallelIOMgr::recvAtomsMGrp ( MoveInputAtomsMsg msg  ) 

Definition at line 828 of file ParallelIOMgr.C.

References ResizeArray< Elem >::add(), MoveInputAtomsMsg::atomList, and MoveInputAtomsMsg::length.

00829 {
00830     for(int i=0; i<msg->length; i++) {
00831         tmpRecvAtoms.add((msg->atomList)[i]);
00832     }
00833     delete msg;
00834 }

void ParallelIOMgr::recvAtomsToHomePatchProcs ( MovePatchAtomsMsg msg  ) 

Definition at line 1507 of file ParallelIOMgr.C.

References ResizeArray< Elem >::add(), MovePatchAtomsMsg::allAtoms, MovePatchAtomsMsg::from, j, MovePatchAtomsMsg::patchCnt, MovePatchAtomsMsg::pidList, and MovePatchAtomsMsg::sizeList.

01508 {
01509     CProxy_ParallelIOMgr pIO(thisgroup);
01510     pIO[msg->from].ackAtomsToHomePatchProcs();
01511 
01512     if(!isOKToRecvHPAtoms) {
01513         prepareHomePatchAtomList();
01514         isOKToRecvHPAtoms = true;
01515     }
01516 
01517     int numRecvPatches = msg->patchCnt;
01518     int aid = 0;
01519     for(int i=0; i<numRecvPatches; i++) {
01520         int pid = msg->pidList[i];
01521         int size = msg->sizeList[i];
01522         int idx = binaryFindHPID(pid);
01523         for(int j=0; j<size; j++, aid++) {
01524             hpAtomsList[idx].add(msg->allAtoms[aid]);
01525         }
01526     }
01527     //CkPrintf("Pe %d recvAtomsToHomePatchProcs for %d patches %d atoms\n",CkMyPe(),numRecvPatches,aid);
01528     delete msg;
01529 }

void ParallelIOMgr::recvClusterCoor ( ClusterCoorMsg msg  ) 

Definition at line 1915 of file ParallelIOMgr.C.

References ResizeArray< Elem >::add().

Referenced by wrapCoor().

01915                                                       {
01916     //only add the msg from remote procs
01917     if(msg!=NULL) ccmBuf.add(msg);
01918 
01919     //include a msg sent by itself
01920     if(++numReqRecved == (numRemoteReqs+1)){
01921         numReqRecved = 0;
01922         integrateClusterCoor();
01923     }
01924 }

void ParallelIOMgr::recvClusterSize ( ClusterSizeMsg msg  ) 

Definition at line 669 of file ParallelIOMgr.C.

References ResizeArray< Elem >::add().

00670 {
00671     csmBuf.add(msg); //added to buffer for reuse to send back to src
00672 
00673     //update cluster size has to be delayed to integration to prevent
00674     //data racing where the clusterSize has not been created!
00675 }

void ParallelIOMgr::recvFinalClusterCoor ( ClusterCoorMsg msg  ) 

Definition at line 1987 of file ParallelIOMgr.C.

References UniqueSet< Elem >::clear(), ClusterCoorElem::clusterId, ClusterCoorMsg::clusterId, ClusterCoorMsg::dsum, ClusterCoorElem::dsum, UniqueSet< Elem >::find(), ResizeArray< Elem >::size(), Lattice::wrap_delta(), Lattice::wrap_nearest_delta(), SimParameters::wrapAll, and SimParameters::wrapNearest.

01987                                                            {
01988 #ifdef MEM_OPT_VERSION
01989     if(msg!=NULL){
01990         //only process the message sent from other procs!
01991         ClusterCoorElem one(msg->clusterId);
01992         ClusterCoorElem *ret = remoteCoors.find(one);
01993         ret->dsum = msg->dsum;
01994         delete msg;
01995     }
01996     
01997     if(++numCSMAck == (numRemoteClusters+1)){        
01998         //final wrap coor computation
01999         int fromIdx = coorInstance->fromAtomID;
02000         int toIdx = coorInstance->toAtomID;
02001         int numMyAtoms = toIdx-fromIdx+1;
02002         ResizeArray<Vector> &data = coorInstance->data;
02003         ResizeArray<FloatVector> &fdata = coorInstance->fdata;
02004         ClusterCoorElem tmp;
02005         for(int i=0; i<numMyAtoms; i++){
02006             if(!simParameters->wrapAll && !isWater[i]) continue;
02007             int cid = clusterID[i];
02008             int lidx = cid-fromIdx;
02009             if(lidx<0){
02010                 //this cid should be inside remoteCoors
02011                 tmp.clusterId = cid;
02012                 ClusterCoorElem *fone = remoteCoors.find(tmp);
02013                 if(data.size()) data[i] += fone->dsum; 
02014                 if(fdata.size()) fdata[i] = fdata[i] + fone->dsum; 
02015             }else{
02016                 if(lidx==i){
02017                     Lattice *lat = &(coorInstance->lattice);
02018                     Vector coni = tmpCoorCon[lidx]/clusterSize[lidx];
02019                     tmpCoorCon[lidx] = (simParameters->wrapNearest ?
02020                     lat->wrap_nearest_delta(coni) : lat->wrap_delta(coni));
02021                 }
02022                 if(data.size()) data[i] += tmpCoorCon[lidx]; 
02023                 if(fdata.size()) fdata[i] = fdata[i] + tmpCoorCon[lidx];
02024             }
02025         }
02026 
02027         delete [] tmpCoorCon;
02028         tmpCoorCon = NULL;
02029         CProxy_CollectionMaster cm(mainMaster);
02030         cm.wrapCoorFinished();
02031         numCSMAck = 0;
02032         remoteCoors.clear();
02033     }
02034 #endif
02035 }

void ParallelIOMgr::recvFinalClusterSize ( ClusterSizeMsg msg  ) 

Definition at line 729 of file ParallelIOMgr.C.

References ClusterSizeMsg::atomsCnt, ClusterElem::atomsCnt, UniqueSet< Elem >::clear(), ClusterElem::clusterId, ClusterSizeMsg::clusterId, and UniqueSet< Elem >::find().

Referenced by integrateClusterSize().

00730 {
00731     //only process the message sent by other procs
00732     if(msg!=NULL) {
00733         //indicating a message from other procs
00734         ClusterElem one(msg->clusterId);
00735         ClusterElem *ret = remoteClusters.find(one);
00736         CmiAssert(ret!=NULL);
00737         ret->atomsCnt = msg->atomsCnt;
00738     }
00739     delete msg;
00740 
00741     //include a msg sent by itself for reduction
00742     if(++numCSMAck == (numRemoteClusters+1)) {
00743         //recved all the msgs needed to update the cluster size for each atom finally
00744         int fromIdx, toIdx; //atoms' range
00745         getMyAtomsRangeOnOutput(fromIdx,toIdx);
00746         int numMyAtoms = toIdx-fromIdx+1;
00747         ClusterElem tmp;
00748         for(int i=0; i<numMyAtoms; i++) {
00749             int cid = clusterID[i];
00750             int lidx = cid-fromIdx;
00751             if(lidx<0) {
00752                 //this cid should be inside remoteClusters
00753                 tmp.clusterId = cid;
00754                 ClusterElem *fone = remoteClusters.find(tmp);
00755                 clusterSize[i] = fone->atomsCnt;
00756             } else {
00757                 clusterSize[i] = clusterSize[lidx];
00758             }
00759         }
00760         numCSMAck = 0;
00761         remoteClusters.clear();
00762 
00763 #if 0 //write out cluster debug info
00764         char fname[128];
00765         sprintf(fname, "cluster.par.%d", CkMyPe());
00766         FILE *ofp = fopen(fname, "w");
00767         for(int i=0; i<numMyAtoms; i++) {
00768             fprintf(ofp, "%d: %d: %d\n", i+fromIdx, clusterID[i], clusterSize[i]);
00769         }
00770         fclose(ofp);
00771 #endif
00772 
00773     }
00774 }

void ParallelIOMgr::recvHydroBasedCounter ( HydroBasedMsg msg  ) 

Definition at line 1193 of file ParallelIOMgr.C.

References HydroBasedMsg::numFixedGroups, Molecule::numFixedGroups, HydroBasedMsg::numFixedRigidBonds, and Molecule::numFixedRigidBonds.

01193                                                            {
01194     molecule->numFixedRigidBonds += msg->numFixedRigidBonds;
01195     molecule->numFixedGroups += msg->numFixedGroups;
01196 
01197     if(++hydroMsgRecved == numInputProcs){
01198         msg->numFixedRigidBonds = molecule->numFixedRigidBonds;
01199         msg->numFixedGroups = molecule->numFixedGroups;
01200         CProxy_ParallelIOMgr pIO(thisgroup);
01201         pIO.bcastHydroBasedCounter(msg);
01202         hydroMsgRecved = 0;
01203     }else delete msg;
01204 }

void ParallelIOMgr::recvMolInfo ( MolInfoMsg msg  ) 

Definition at line 1091 of file ParallelIOMgr.C.

References SimParameters::comMove, MolInfoMsg::numAngles, Molecule::numAngles, MolInfoMsg::numBonds, Molecule::numBonds, MolInfoMsg::numCalcAngles, Molecule::numCalcAngles, MolInfoMsg::numCalcBonds, Molecule::numCalcBonds, MolInfoMsg::numCalcCrossterms, Molecule::numCalcCrossterms, MolInfoMsg::numCalcDihedrals, Molecule::numCalcDihedrals, MolInfoMsg::numCalcExclusions, MolInfoMsg::numCalcFullExclusions, MolInfoMsg::numCalcImpropers, Molecule::numCalcImpropers, MolInfoMsg::numCrossterms, Molecule::numCrossterms, MolInfoMsg::numDihedrals, Molecule::numDihedrals, MolInfoMsg::numExclusions, MolInfoMsg::numImpropers, Molecule::numImpropers, MolInfoMsg::numRigidBonds, Molecule::numRigidBonds, MolInfoMsg::totalCharge, MolInfoMsg::totalMass, and MolInfoMsg::totalMV.

01092 {
01093     molecule->numBonds += msg->numBonds;
01094     molecule->numCalcBonds += msg->numCalcBonds;
01095     molecule->numAngles += msg->numAngles;
01096     molecule->numCalcAngles += msg->numCalcAngles;
01097     molecule->numDihedrals += msg->numDihedrals;
01098     molecule->numCalcDihedrals += msg->numCalcDihedrals;
01099     molecule->numImpropers += msg->numImpropers;
01100     molecule->numCalcImpropers += msg->numCalcImpropers;
01101     molecule->numCrossterms += msg->numCrossterms;
01102     molecule->numCalcCrossterms += msg->numCalcCrossterms;
01103     numTotalExclusions += msg->numExclusions;
01104     numCalcExclusions += msg->numCalcExclusions;
01105     numCalcFullExclusions += msg->numCalcFullExclusions;
01106     molecule->numRigidBonds += msg->numRigidBonds;
01107 
01108     totalMass += msg->totalMass;
01109     totalCharge += msg->totalCharge;
01110 
01111     if(!simParameters->comMove) {
01112         totalMV += msg->totalMV;        
01113     }
01114 
01115     if(++procsReceived == numInputProcs) {
01116         //received all the counters
01117         msg->numBonds = molecule->numBonds;
01118         msg->numCalcBonds = molecule->numCalcBonds;
01119         msg->numAngles = molecule->numAngles;
01120         msg->numCalcAngles = molecule->numCalcAngles;
01121         msg->numDihedrals = molecule->numDihedrals;
01122         msg->numCalcDihedrals = molecule->numCalcDihedrals;
01123         msg->numImpropers = molecule->numImpropers;
01124         msg->numCalcImpropers = molecule->numCalcImpropers;
01125         msg->numCrossterms = molecule->numCrossterms;
01126         msg->numCalcCrossterms = molecule->numCalcCrossterms;
01127         msg->numExclusions = numTotalExclusions/2;
01128         msg->numCalcExclusions = numCalcExclusions/2;
01129         msg->numCalcFullExclusions = numCalcFullExclusions/2;
01130         msg->numRigidBonds = molecule->numRigidBonds;
01131 
01132         msg->totalMass = totalMass;
01133         msg->totalCharge = totalCharge;
01134 
01135         if(!simParameters->comMove) {
01136             msg->totalMV = totalMV;            
01137         }
01138 
01139         CProxy_ParallelIOMgr pIO(thisgroup);
01140         pIO.bcastMolInfo(msg);
01141 
01142         //reset to 0 for the next p2p-based reduction on input procs
01143         procsReceived = 0;
01144     } else delete msg;
01145 }

void ParallelIOMgr::sendAtomsToHomePatchProcs (  ) 

Definition at line 1418 of file ParallelIOMgr.C.

References ResizeArray< Elem >::add(), MovePatchAtomsMsg::allAtoms, ResizeArray< Elem >::begin(), call_sendAtomsToHomePatchProcs(), ResizeArray< Elem >::clear(), PatchMap::delTmpPatchAtomsList(), MovePatchAtomsMsg::from, PatchMap::getTmpPatchAtomsList(), j, PatchMap::node(), numAcksOutstanding, PatchMap::numPatches(), numPatches, PatchMap::Object(), MovePatchAtomsMsg::patchCnt, MovePatchAtomsMsg::pidList, sendAtomsThread, ResizeArray< Elem >::size(), and MovePatchAtomsMsg::sizeList.

01419 {
01420 #ifdef MEM_OPT_VERSION
01421     if(myInputRank==-1) return;
01422 
01423     if ( sendAtomsThread == 0 ) {
01424       sendAtomsThread = CthCreate((CthVoidFn)call_sendAtomsToHomePatchProcs,this,0);
01425       CthAwaken(sendAtomsThread);
01426       return;
01427     }
01428     sendAtomsThread = 0;
01429     numAcksOutstanding = 0;
01430 
01431     PatchMap *patchMap = PatchMap::Object();
01432     int numPatches = patchMap->numPatches();
01433     vector<int> *eachPatchAtomList = patchMap->getTmpPatchAtomsList();
01434 
01435     //each element (proc) contains the list of ids of patches which will stay
01436     //on that processor
01437     ResizeArray<int> *procList = new ResizeArray<int>[CkNumPes()];
01438     ResizeArray<int> pesToSend;
01439     for(int i=0; i<numPatches; i++) {
01440         if(eachPatchAtomList[i].size()==0) continue;
01441         int onPE = patchMap->node(i);
01442         if ( procList[onPE].size() == 0 ) pesToSend.add(onPE);
01443         procList[onPE].add(i);
01444     }
01445 
01446     Random(CkMyPe()).reorder(pesToSend.begin(),pesToSend.size());
01447     //CkPrintf("Pe %d ParallelIOMgr::sendAtomsToHomePatchProcs sending to %d pes\n",CkMyPe(),pesToSend.size());
01448 
01449     //go over every processor to send a message if necessary
01450     //TODO: Optimization for local home patches to save temp memory usage??? -CHAOMEI
01451     CProxy_ParallelIOMgr pIO(thisgroup);
01452     for(int k=0; k<pesToSend.size(); k++) {
01453         const int i = pesToSend[k];
01454         int len = procList[i].size();
01455         if(len==0) continue;
01456 
01457         // Sending one message per pe can result in very large messages
01458         // that break Converse so send one message per patch instead.
01459         for(int j=0; j<len; j++) {
01460             int pid = procList[i][j];
01461             int atomCnt = eachPatchAtomList[pid].size();
01462 
01463             if ( numAcksOutstanding >= 10 ) {
01464               sendAtomsThread = CthSelf();
01465               CthSuspend();
01466             }
01467             ++numAcksOutstanding;
01468 
01469             MovePatchAtomsMsg *msg = new (1, 1, atomCnt, 0)MovePatchAtomsMsg;
01470             msg->from = CkMyPe();
01471             msg->patchCnt = 1;
01472             int atomIdx = 0;
01473             msg->pidList[0] = pid;
01474             msg->sizeList[0] = atomCnt;
01475             for(int k=0; k<atomCnt; k++, atomIdx++) {
01476                 int aid = eachPatchAtomList[pid][k];
01477                 FullAtom one = initAtoms[aid];
01478                 //HACK to re-sort the atom list after receiving the atom list on
01479                 //home patch processor -Chao Mei
01480                 one.hydVal = initAtoms[aid].hydList;
01481                 msg->allAtoms[atomIdx] = one;
01482             }
01483             pIO[i].recvAtomsToHomePatchProcs(msg);
01484         }
01485 
01486         procList[i].clear();
01487     }
01488 
01489     //clean up to free space
01490     delete [] procList;
01491     patchMap->delTmpPatchAtomsList();
01492 
01493     //free the space occupied by the list that contains the input atoms
01494     initAtoms.clear();
01495 #endif
01496 }

void ParallelIOMgr::updateMolInfo (  ) 

Definition at line 903 of file ParallelIOMgr.C.

References AtomSignature::angleCnt, AtomSignature::angleSigs, atomSigPool, AtomSignature::bondCnt, AtomSignature::bondSigs, SimParameters::comMove, AtomSignature::crosstermCnt, AtomSignature::crosstermSigs, AtomSignature::dihedralCnt, AtomSignature::dihedralSigs, SimParameters::fixedAtomsForces, ExclusionSignature::fullExclCnt, ExclusionSignature::fullOffset, AtomSignature::gromacsPairCnt, AtomSignature::gromacsPairSigs, AtomSignature::improperCnt, AtomSignature::improperSigs, j, ExclusionSignature::modExclCnt, ExclusionSignature::modOffset, MolInfoMsg::numAngles, MolInfoMsg::numBonds, MolInfoMsg::numCalcAngles, MolInfoMsg::numCalcBonds, MolInfoMsg::numCalcCrossterms, MolInfoMsg::numCalcDihedrals, MolInfoMsg::numCalcExclusions, MolInfoMsg::numCalcFullExclusions, MolInfoMsg::numCalcImpropers, MolInfoMsg::numCalcLJPairs, MolInfoMsg::numCrossterms, MolInfoMsg::numDihedrals, MolInfoMsg::numExclusions, Molecule::numFixedAtoms, MolInfoMsg::numImpropers, MolInfoMsg::numLJPairs, MolInfoMsg::numRigidBonds, TupleSignature::offset, ResizeArray< Elem >::size(), MolInfoMsg::totalCharge, MolInfoMsg::totalMass, and MolInfoMsg::totalMV.

00904 {
00905 #ifdef MEM_OPT_VERSION
00906     if(myInputRank==-1) return;
00907 
00908     CProxy_ParallelIOMgr pIO(thisgroup);
00909 
00910     MolInfoMsg *msg = new MolInfoMsg;
00911     msg->numBonds = msg->numCalcBonds = 0;
00912     msg->numAngles = msg->numCalcAngles = 0;
00913     msg->numDihedrals = msg->numCalcDihedrals = 0;
00914     msg->numImpropers = msg->numCalcImpropers = 0;
00915     msg->numCrossterms = msg->numCalcCrossterms = 0;
00916     msg->numExclusions = msg->numCalcExclusions = 0;
00917     int64 numFullExclusions = msg->numCalcFullExclusions = 0;
00918     // JLai
00919     msg->numLJPairs = msg->numCalcLJPairs = 0;
00920     // End of JLai
00921     msg->numRigidBonds = 0;
00922     msg->totalMass = 0.0;
00923     msg->totalCharge = 0.0;
00924 
00925     //calculate the tuples this input processor have
00926     AtomSignature *atomSigPool = molecule->atomSigPool;
00927     ExclusionSignature *exclSigPool = molecule->exclSigPool;
00928     for(int i=0; i<initAtoms.size(); i++) {
00929         AtomSignature *thisSig = &atomSigPool[initAtoms[i].sigId];
00930         msg->numBonds += thisSig->bondCnt;
00931         msg->numAngles += thisSig->angleCnt;
00932         msg->numDihedrals += thisSig->dihedralCnt;
00933         msg->numImpropers += thisSig->improperCnt;
00934         msg->numCrossterms += thisSig->crosstermCnt;
00935         // JLai
00936         msg->numLJPairs += thisSig->gromacsPairCnt;
00937         // End of JLai
00938 
00939         ExclusionSignature *exclSig = &exclSigPool[initAtoms[i].exclId];
00940         msg->numExclusions += (exclSig->fullExclCnt + exclSig->modExclCnt);
00941         numFullExclusions += exclSig->fullExclCnt;
00942 
00943         if(initAtoms[i].rigidBondLength > 0.0) msg->numRigidBonds++;
00944 
00945         msg->totalMass += initAtoms[i].mass;
00946         msg->totalCharge += initAtoms[i].charge;
00947     }
00948 
00949     //deal with numCalc* which is related with fixed atoms!
00950     if(molecule->numFixedAtoms>0 && ! simParameters->fixedAtomsForces) {
00951         //if there's fixed atoms, calcExclusions needs to be calculated
00952         //Since it's possible the atom inside the this exclusion set is on
00953         //another input processor, we have to resort to the global fixed atoms
00954         //info inside the Molecule object. The number of such accesses should
00955         //be very small! --Chao Mei
00956         int sAId = initAtoms[0].id;
00957         int remoteCnt=0; //stats info
00958         for(int i=0; i<initAtoms.size(); i++) {
00959             //When all the atoms in the set are fixed, the elem (Bond etc.)
00960             //is not counted as a calc*.
00961             int myAId = initAtoms[i].id;
00962             AtomSignature *thisSig = &atomSigPool[initAtoms[i].sigId];
00963             ExclusionSignature *exclSig = &exclSigPool[initAtoms[i].exclId];
00964             if(!initAtoms[i].atomFixed) {
00965                 msg->numCalcBonds += thisSig->bondCnt;                
00966                 msg->numCalcAngles += thisSig->angleCnt;
00967                 msg->numCalcDihedrals += thisSig->dihedralCnt;
00968                 msg->numCalcImpropers += thisSig->improperCnt;
00969                 msg->numCalcCrossterms += thisSig->crosstermCnt;
00970                 msg->numCalcExclusions+=(exclSig->fullExclCnt+exclSig->modExclCnt);
00971                 msg->numCalcFullExclusions+=(exclSig->fullExclCnt);
00972                 continue;
00973             }
00974                        
00975             //1. Bonds
00976             for(int j=0; j<thisSig->bondCnt; j++) {            
00977                 TupleSignature *bsig = &(thisSig->bondSigs[j]);
00978                 int a1 = myAId + bsig->offset[0];
00979                 if(!isAtomFixed(sAId, a1)) msg->numCalcBonds++;
00980             }
00981             
00982             //2. Angles
00983             for(int j=0; j<thisSig->angleCnt; j++) {            
00984                 TupleSignature *bsig = &(thisSig->angleSigs[j]);
00985                 int a1 = myAId + bsig->offset[0];
00986                 int a2 = myAId + bsig->offset[1];
00987                 if(!isAtomFixed(sAId, a1) || !isAtomFixed(sAId, a2)) 
00988                     msg->numCalcAngles++;
00989             }
00990 
00991             //3. Dihedrals
00992             for(int j=0; j<thisSig->dihedralCnt; j++) {            
00993                 TupleSignature *bsig = &(thisSig->dihedralSigs[j]);
00994                 int a1 = myAId + bsig->offset[0];
00995                 int a2 = myAId + bsig->offset[1];
00996                 int a3 = myAId + bsig->offset[2];
00997                 if(!isAtomFixed(sAId, a1) || 
00998                    !isAtomFixed(sAId, a2) ||
00999                    !isAtomFixed(sAId, a3)) 
01000                     msg->numCalcDihedrals++;
01001             }
01002 
01003             //4. Impropers
01004             for(int j=0; j<thisSig->improperCnt; j++) {            
01005                 TupleSignature *bsig = &(thisSig->improperSigs[j]);
01006                 int a1 = myAId + bsig->offset[0];
01007                 int a2 = myAId + bsig->offset[1];
01008                 int a3 = myAId + bsig->offset[2];
01009                 if(!isAtomFixed(sAId, a1) || 
01010                    !isAtomFixed(sAId, a2) ||
01011                    !isAtomFixed(sAId, a3)) 
01012                     msg->numCalcImpropers++;
01013             }
01014 
01015             //5. Crossterms
01016             for(int j=0; j<thisSig->crosstermCnt; j++) {            
01017                 TupleSignature *bsig = &(thisSig->crosstermSigs[j]);
01018                 int a1 = myAId + bsig->offset[0];
01019                 int a2 = myAId + bsig->offset[1];
01020                 int a3 = myAId + bsig->offset[2];
01021                 int a4 = myAId + bsig->offset[3];
01022                 int a5 = myAId + bsig->offset[4];
01023                 int a6 = myAId + bsig->offset[5];
01024                 int a7 = myAId + bsig->offset[6];
01025 
01026                 if(!isAtomFixed(sAId, a1) || 
01027                    !isAtomFixed(sAId, a2) ||
01028                    !isAtomFixed(sAId, a3) ||
01029                    !isAtomFixed(sAId, a4) ||
01030                    !isAtomFixed(sAId, a5) ||
01031                    !isAtomFixed(sAId, a6) ||
01032                    !isAtomFixed(sAId, a7)) 
01033                     msg->numCalcDihedrals++;
01034             }
01035             
01036             //6: Exclusions            
01037             //this atom is fixed, check atoms in the exclusion set
01038             for(int j=0; j<exclSig->fullExclCnt; j++) {
01039                 int thisAId = exclSig->fullOffset[j]+myAId;
01040                 if(!isAtomFixed(sAId, thisAId)) { msg->numCalcExclusions++; msg->numCalcFullExclusions++; }
01041             }
01042             for(int j=0; j<exclSig->modExclCnt; j++) {
01043                 int thisAId = exclSig->modOffset[j]+myAId;
01044                 if(!isAtomFixed(sAId, thisAId)) msg->numCalcExclusions++;
01045             }
01046 
01047             //7: GromacsPair
01048             for(int j=0; j<thisSig->gromacsPairCnt; j++) {
01049                 TupleSignature *bsig = &(thisSig->gromacsPairSigs[j]);
01050                 int a1 = myAId + bsig->offset[0];
01051                 int a2 = myAId + bsig->offset[1];
01052                 if(!isAtomFixed(sAId, a1) || 
01053                    !isAtomFixed(sAId, a2))
01054                     msg->numCalcLJPairs++;
01055             }
01056         }
01057 #if COLLECT_PERFORMANCE_DATA
01058         printf("Num fixedAtom lookup on proc %d is %d\n", CkMyPe(), numFixedAtomLookup);
01059 #endif
01060     } else {
01061         //no fixed atoms, numCalc* is same with numExclusions
01062         msg->numCalcBonds = msg->numBonds;
01063         msg->numCalcAngles = msg->numAngles;
01064         msg->numCalcDihedrals = msg->numDihedrals;
01065         msg->numCalcImpropers = msg->numImpropers;
01066         msg->numCalcCrossterms = msg->numCrossterms;
01067         msg->numCalcExclusions = msg->numExclusions;
01068         msg->numCalcFullExclusions = numFullExclusions;
01069     }
01070 
01071 
01072     if(!simParameters->comMove) {
01073         //to remove the center of mass motion from a molecule.
01074         //first calculate the values on every input proc, then reduce.
01075         //For more info, refer to WorkDistrib::remove_com_motion
01076         //-Chao Mei
01077         (msg->totalMV).x = 0.0;
01078         (msg->totalMV).y = 0.0;
01079         (msg->totalMV).z = 0.0;
01080         for (int i=0; i<initAtoms.size(); i++) {            
01081             msg->totalMV += initAtoms[i].mass * initAtoms[i].velocity;
01082         }
01083     }
01084 
01085     //always send to the master processor (proc 0)
01086     pIO[0].recvMolInfo(msg);
01087 #endif
01088 }

void ParallelIOMgr::wrapCoor ( int  seq,
Lattice  lat 
)

Definition at line 1841 of file ParallelIOMgr.C.

References UniqueSet< Elem >::add(), UniqueSetIter< T >::begin(), ClusterCoorMsg::clusterId, ClusterCoorElem::clusterId, ClusterCoorMsg::dsum, ClusterCoorElem::dsum, UniqueSetIter< T >::end(), UniqueSet< Elem >::find(), recvClusterCoor(), UniqueSet< Elem >::size(), ResizeArray< Elem >::size(), and ClusterCoorMsg::srcRank.

01842 {
01843 #ifdef MEM_OPT_VERSION
01844     coorInstance = midCM->getReadyPositions(seq);
01845 
01846     coorInstance->lattice = lat; //record the lattice to use for wrapAll/Water!
01847     int fromAtomID = coorInstance->fromAtomID;
01848     int toAtomID = coorInstance->toAtomID;
01849 
01850     //only reference copies
01851     ResizeArray<Vector> &data = coorInstance->data;
01852     ResizeArray<FloatVector> &fdata = coorInstance->fdata;
01853     //if both data and fdata are not empty, they contain exact values, the only
01854     //difference lies in their precisions. Therefore, we only need to compute 
01855     //the higher precision coordinate array. -Chao Mei
01856     int dsize = data.size();    
01857     int numMyAtoms = toAtomID-fromAtomID+1;
01858     tmpCoorCon = new Vector[numMyAtoms];    
01859     ClusterCoorElem one;
01860     //1. compute wrapped coordinates locally 
01861     for(int i=0; i<numMyAtoms; i++){
01862         tmpCoorCon[i] = 0.0;
01863         int cid = clusterID[i];
01864         if(cid<fromAtomID){
01865             //on output procs ahead of me
01866             one.clusterId = cid;
01867             ClusterCoorElem *ret = remoteCoors.find(one);
01868             if(ret==NULL){
01869                 if(dsize==0) 
01870                     one.dsum = fdata[i];
01871                 else 
01872                     one.dsum = data[i];
01873                                 
01874                 remoteCoors.add(one);                 
01875             }else{
01876                 if(dsize==0) 
01877                     ret->dsum += fdata[i];
01878                 else 
01879                     ret->dsum += data[i];               
01880             }
01881         }else{
01882             if(dsize==0) 
01883                 tmpCoorCon[cid-fromAtomID] += fdata[i];
01884             else 
01885                 tmpCoorCon[cid-fromAtomID] += data[i];
01886         }
01887     }
01888 
01889     //2. Prepare to send msgs to remote output procs to reduce coordinates 
01890     //values of a cluster
01891     CmiAssert(numRemoteClusters == remoteCoors.size());
01892     numCSMAck = 0; //set to 0 to prepare recving the final coor update
01893     CProxy_ParallelIOMgr pIO(thisgroup);
01894     ClusterCoorSetIter iter(remoteCoors);
01895     for(iter=iter.begin(); iter!=iter.end(); iter++){
01896         ClusterCoorMsg *msg = new ClusterCoorMsg;
01897         msg->srcRank = myOutputRank;
01898         msg->clusterId = iter->clusterId;
01899         msg->dsum = iter->dsum;
01900         int dstRank = atomRankOnOutput(iter->clusterId);
01901         pIO[outputProcArray[dstRank]].recvClusterCoor(msg);
01902     }
01903     
01904     //Just send a local NULL msg to indicate the local wrapping
01905     //coordinates has finished.
01906     recvClusterCoor(NULL);
01907 #endif
01908 }


Member Data Documentation

Definition at line 377 of file ParallelIOMgr.h.

Referenced by ackAtomsToHomePatchProcs(), and sendAtomsToHomePatchProcs().


The documentation for this class was generated from the following files:

Generated on 21 Oct 2019 for NAMD by  doxygen 1.6.1