--- trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2002/12/05 18:53:40 195 +++ trunk/mdtools/mpi_implementation/mpiSimulation.cpp 2003/01/30 15:20:21 253 @@ -1,33 +1,57 @@ -i#include +#include #include #include #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; - numberProcessors = MPI::COMM_WORLD.Get_size(); - myNode = worldRank; + mpiPlug->numberProcessors = MPI::COMM_WORLD.Get_size(); + mpiPlug->myNode = worldRank; - // let the simulation know were there. - entryPlug->mpiSim = this; + mpiSim = this; + wrapMe(); + } mpiSimulation::~mpiSimulation(){ - // empty for now + delete mpiPlug; + // perhaps we should let fortran know the party is over. } +void mpiSimulation::wrapMe(){ -void mpiSimulation::divideLabor(int nComponents, MoleculeStamp** compStamps, int* componentsNmol ){ - + wrapsimparallelmod_( wrapSimParallel ); +} + + + +int* mpiSimulation::divideLabor( void ){ + + int* globalIndex; + + int nComponents; + MoleculeStamp** compStamps; + int* componentsNmol; + double numerator; double denominator; double precast; @@ -35,14 +59,25 @@ void mpiSimulation::divideLabor(int nComponents, Molec int nTarget; int molIndex, atomIndex, compIndex, compStart; int done; - int nLocal; - int i; + int nLocal, molLocal; + int i, index; 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_mol; + numerator = (double) entryPlug->n_atoms; - denominator = (double) numberProcessors; + denominator = (double) mpiPlug->numberProcessors; precast = numerator / denominator; nTarget = (int)( precast + 0.5 ); @@ -50,14 +85,15 @@ void mpiSimulation::divideLabor(int nComponents, Molec atomIndex = 0; compIndex = 0; compStart = 0; - for( i=0; i<(numberProcessors-1); i++){ + for( i=0; i<(mpiPlug->numberProcessors-1); i++){ done = 0; nLocal = 0; + molLocal = 0; - if( i == myNode ){ - myMolStart = molIndex; - myAtomStart = atomIndex; + if( i == mpiPlug->myNode ){ + mpiPlug->myMolStart = molIndex; + mpiPlug->myAtomStart = atomIndex; } while( !done ){ @@ -71,6 +107,7 @@ void mpiSimulation::divideLabor(int nComponents, Molec nLocal += compStamps[compIndex]->getNAtoms(); atomIndex += compStamps[compIndex]->getNAtoms(); molIndex++; + molLocal++; if ( nLocal == nTarget ) done = 1; @@ -83,6 +120,7 @@ void mpiSimulation::divideLabor(int nComponents, Molec if( bigDiff < smallDiff ) done = 1; else{ molIndex--; + molLocal--; atomIndex -= compStamps[compIndex]->getNAtoms(); nLocal -= compStamps[compIndex]->getNAtoms(); done = 1; @@ -90,23 +128,25 @@ void mpiSimulation::divideLabor(int nComponents, Molec } } - if( i == myNode ){ - myMolEnd = (molIndex - 1); - myAtomEnd = (atomIndex - 1); - myNlocal = nLocal; + 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)( numberProcessors - (i+1) ); + denominator = (double)( mpiPlug->numberProcessors - (i+1) ); precast = numerator / denominator; nTarget = (int)( precast + 0.5 ); } - if( myNode == numberProcessors-1 ){ - myMolStart = molIndex; - myAtomStart = atomIndex; + if( mpiPlug->myNode == mpiPlug->numberProcessors-1 ){ + mpiPlug->myMolStart = molIndex; + mpiPlug->myAtomStart = atomIndex; nLocal = 0; + molLocal = 0; while( compIndex < nComponents ){ if( (molIndex-compStart) >= componentsNmol[compIndex] ){ @@ -118,17 +158,19 @@ void mpiSimulation::divideLabor(int nComponents, Molec nLocal += compStamps[compIndex]->getNAtoms(); atomIndex += compStamps[compIndex]->getNAtoms(); molIndex++; + molLocal++; } - myMolEnd = (molIndex - 1); - myAtomEnd = (atomIndex - 1); - myNlocal = nLocal; + 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 ); + MPI_Allreduce( &nLocal, &testSum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); - if( myNode == 0 ){ + 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", @@ -141,4 +183,48 @@ void mpiSimulation::divideLabor(int nComponents, Molec sprintf( checkPointMsg, "Successfully divided the molecules among the processors.\n" ); MPIcheckPoint(); + + // lets create the identity array + + globalIndex = new int[mpiPlug->myNlocal]; + index = mpiPlug->myAtomStart; + for( i=0; imyNlocal; i++){ + globalIndex[i] = index; + index++; + } + + return globalIndex; } + + +void wrapSimParallel(void (*fSub)(mpiSimData*, int*, int*, int*)){ + + mpiSim->setInternal( fSub ); +} + + +void mpiSimulation::mpiRefresh( void ){ + + int isError, i; + int *globalIndex = new int[mpiPlug->myNlocal]; + + for(i=0; imyNlocal; i++) globalIndex[i] = entryPlug->atoms[i]->getGlobalIndex(); + + + isError = 0; + setFsimParallel( mpiPlug, &(entryPlug->n_atoms), globalIndex, &isError ); + if( isError ){ + + sprintf( painCave.errMsg, + "mpiRefresh errror: fortran didn't like something we gave it.\n" ); + painCave.isFatal = 1; + simError(); + } + + delete[] globalIndex; + + sprintf( checkPointMsg, + " mpiRefresh successful.\n" ); + MPIcheckPoint(); +} +