--- trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2002/09/30 19:36:20 122 +++ trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2002/12/05 21:37:51 196 @@ -1,25 +1,153 @@ -#include -#include +i#include +#include +#include -mpiSimulation::mpiSimulation() +#include "mpiSimulation.hpp" +#include "simError.h" + + + +mpiSimulation::mpiSimulation(SimInfo* the_entryPlug) { - int mpi_error; + entryPlug = the_entryPlug; + + numberProcessors = MPI::COMM_WORLD.Get_size(); + myNode = worldRank; + + // let the simulation know were there. + entryPlug->mpiSim = this; +} - MPI::Init(); - numberProcessors = MPI::Comm::Get_size(); - myNode = MPI::Comm::Get_rank(); - MPI::Get_processor_name(processorName,&processorNameLen); +mpiSimulation::~mpiSimulation(){ + + // empty for now + } -mpiSimulation::mpiInitSimulation(SimInfo* entry_plug) -{ - // need to get nmol here...... +void mpiSimulation::divideLabor(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; - myMolStart = nint(float(node)/numberProcessors*entry_plug->n_mol); - myMolEnd = nint(float(node + 1)/numberProcessors*entry_plug->n_mol;); - nMolLocal = myMolEnd - myMolStart + 1 + numerator = (double) entryPlug->n_atoms; + denominator = (double) numberProcessors; + precast = numerator / denominator; + nTarget = (int)( precast + 0.5 ); + + molIndex = 0; + atomIndex = 0; + compIndex = 0; + compStart = 0; + for( i=0; i<(numberProcessors-1); i++){ + + done = 0; + nLocal = 0; + molLocal = 0; + + if( i == myNode ){ + myMolStart = molIndex; + 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 == myNode ){ + myMolEnd = (molIndex - 1); + myAtomEnd = (atomIndex - 1); + myNlocal = nLocal; + myMol = molLocal; + } + + numerator = (double)( entryPlug->n_atoms - atomIndex ); + denominator = (double)( numberProcessors - (i+1) ); + precast = numerator / denominator; + nTarget = (int)( precast + 0.5 ); + } + + if( myNode == numberProcessors-1 ){ + myMolStart = molIndex; + 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++; + } + + myMolEnd = (molIndex - 1); + myAtomEnd = (atomIndex - 1); + myNlocal = nLocal; + myMol = molLocal; + } + + + MPI_Allreduce( &Nlocal, &testSum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); + + if( 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 }