--- trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2002/10/16 20:02:05 137 +++ trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2003/01/24 21:25:08 245 @@ -1,14 +1,192 @@ +i#include +#include #include -#include -mpiSimulation::mpiSimulation(void) +#include "mpiSimulation.hpp" +#include "simError.h" + +extern "C"{ + void wrapsimparallelmod_( void (*wrapFunction)(void (*fSub)( mpiSimData*, + int*, int*, + int*))); +} + +void wrapSimParallel((void (*fSub)(mpiSimData*, int*, int*, int*))); + + +mpiSimulation* mpiSim; + +mpiSimulation::mpiSimulation(SimInfo* the_entryPlug) { + entryPlug = the_entryPlug; + mpiPlug = new MpiSimData; + + mpiPlug->numberProcessors = MPI::COMM_WORLD.Get_size(); + mpiPlug->myNode = worldRank; + + mpiSim = this; + wrapMe(); -// MPI::Init(); +} - numberProcessors = MPI::COMM_WORLD.Get_size(); - myNode = MPI::COMM_WORLD.Get_rank(); - // MPI::Get_processor_name(processorName,processorNameLen); + +mpiSimulation::~mpiSimulation(){ + + delete mpiPlug; + // perhaps we should let fortran know the party is over. + } +void mpiSimulation::wrapMe(){ + wrapsimparallelmod_( wrapSimParallel ); +} + + + +void mpiSimulation::divideLabor( void ){ + + int nComponents; + MoleculeStamp** compStamps; + int* componentsNmol; + + double numerator; + double denominator; + double precast; + + int nTarget; + int molIndex, atomIndex, compIndex, compStart; + int done; + int nLocal, molLocal; + int i; + int smallDiff, bigDiff; + + int testSum; + + nComponents = entryPlug->nComponents; + compStamps = entryPlug->compStamps; + componentsNmol = entryPlug->componentsNmol; + + mpiPlug->nAtomsGlobal = entryPlug->n_atoms; + mpiPlug->nBondsGlobal = entryPlug->n_bonds; + mpiPlug->nBendsGlobal = entryPlug->n_bends; + mpiPlug->nTorsionsGlobal = entryPlug->n_torsions; + mpiPlug->nSRIGlobal = entryPlug->n_SRI; + mpiPlug->nMolGlobal = entryPlug->n_nmol; + + numerator = (double) entryPlug->n_atoms; + denominator = (double) mpiPlug->numberProcessors; + precast = numerator / denominator; + nTarget = (int)( precast + 0.5 ); + + molIndex = 0; + atomIndex = 0; + compIndex = 0; + compStart = 0; + for( i=0; i<(mpiPlug->numberProcessors-1); i++){ + + done = 0; + nLocal = 0; + molLocal = 0; + + if( i == mpiPlug->myNode ){ + mpiPlug->myMolStart = molIndex; + mpiPlug->myAtomStart = atomIndex; + } + + while( !done ){ + + if( (molIndex-compStart) >= componentsNmol[compIndex] ){ + compStart = molIndex; + compIndex++; + continue; + } + + nLocal += compStamps[compIndex]->getNAtoms(); + atomIndex += compStamps[compIndex]->getNAtoms(); + molIndex++; + molLocal++; + + if ( nLocal == nTarget ) done = 1; + + else if( nLocal < nTarget ){ + smallDiff = nTarget - nLocal; + } + else if( nLocal > nTarget ){ + bigDiff = nLocal - nTarget; + + if( bigDiff < smallDiff ) done = 1; + else{ + molIndex--; + molLocal--; + atomIndex -= compStamps[compIndex]->getNAtoms(); + nLocal -= compStamps[compIndex]->getNAtoms(); + done = 1; + } + } + } + + if( i == mpiPlug->myNode ){ + mpiPlug->myMolEnd = (molIndex - 1); + mpiPlug->myAtomEnd = (atomIndex - 1); + mpiPlug->myNlocal = nLocal; + mpiPlug->myMol = molLocal; + } + + numerator = (double)( entryPlug->n_atoms - atomIndex ); + denominator = (double)( mpiPlug->numberProcessors - (i+1) ); + precast = numerator / denominator; + nTarget = (int)( precast + 0.5 ); + } + + if( mpiPlug->myNode == mpiPlug->numberProcessors-1 ){ + mpiPlug->myMolStart = molIndex; + mpiPlug->myAtomStart = atomIndex; + + nLocal = 0; + molLocal = 0; + while( compIndex < nComponents ){ + + if( (molIndex-compStart) >= componentsNmol[compIndex] ){ + compStart = molIndex; + compIndex++; + continue; + } + + nLocal += compStamps[compIndex]->getNAtoms(); + atomIndex += compStamps[compIndex]->getNAtoms(); + molIndex++; + molLocal++; + } + + mpiPlug->myMolEnd = (molIndex - 1); + mpiPlug->myAtomEnd = (atomIndex - 1); + mpiPlug->myNlocal = nLocal; + mpiPlug->myMol = molLocal; + } + + + MPI_Allreduce( &nLocal, &testSum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); + + if( mpiPlug->myNode == 0 ){ + if( testSum != entryPlug->n_atoms ){ + sprintf( painCave.errMsg, + "The summ of all nLocals, %d, did not equal the total number of atoms, %d.\n", + testSum, entryPlug->n_atoms ); + painCave.isFatal = 1; + simError(); + } + } + + sprintf( checkPointMsg, + "Successfully divided the molecules among the processors.\n" ); + MPIcheckPoint(); + + // lets create the identity array +} + + +void wrapSimParallel((void (*fSub)(mpiSimData*, int*, int*, int*))){ + + mpiSim->setInternal( fSub ); +}