--- branches/mmeineke/OOPSE/libmdtools/InitializeFromFile.cpp 2003/03/21 17:42:12 377 +++ trunk/OOPSE/libmdtools/InitializeFromFile.cpp 2003/03/28 21:45:03 436 @@ -12,9 +12,15 @@ #include "simError.h" #ifdef IS_MPI +#include +#include #include "mpiSimulation.hpp" +#define TAKE_THIS_TAG_CHAR 0 +#define TAKE_THIS_TAG_INT 1 -#define TAKE_THIS_TAG 0 +void nodeZeroError( void ); +void anonymousNodeDie( void ); + #endif // is_mpi InitializeFromFile :: InitializeFromFile( char *in_name ){ @@ -62,7 +68,7 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr void InitializeFromFile :: read_xyz( SimInfo* the_entry_plug ){ - int i; // loop counter + int i, j, done, which_node, which_atom; // loop counter const int BUFFERSIZE = 2000; // size of the read buffer int n_atoms; // the number of atoms @@ -138,20 +144,24 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr // MPI Section of code.......... #else //IS_MPI - int masterIndex; - int nodeAtomsStart; - int nodeAtomsEnd; - int mpiErr; - int sendError; + // first thing first, suspend fatalities. + painCave.isEventLoop = 1; - MPI_Status istatus[MPI_STATUS_SIZE]; + int myStatus; // 1 = wakeup & success; 0 = error; -1 = AllDone + int haveError; + + MPI::Status istatus; + int *AtomToProcMap = mpiSim->getAtomToProcMap(); + + haveError = 0; if (worldRank == 0) { + eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); if( eof_test == NULL ){ sprintf( painCave.errMsg, "Error reading 1st line of %d \n ",c_in_name); - painCave.isFatal = 1; + haveError = 1; simError(); } @@ -168,7 +178,7 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr "Initialize from File error. %s n_atoms, %d, " "does not match the BASS file's n_atoms, %d.\n", c_in_name, n_atoms, entry_plug->n_atoms ); - painCave.isFatal = 1; + haveError= 1; simError(); } @@ -178,14 +188,14 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr if(eof_test == NULL){ sprintf( painCave.errMsg, "error in reading commment in %s\n", c_in_name); - painCave.isFatal = 1; + haveError= 1; simError(); } - // Read Proc 0 share of the xyz file... - masterIndex = 0; - for( i=0; i <= mpiSim->getMyAtomEnd(); i++){ - + if(haveError) nodeZeroError(); + + for (i=0 ; i < mpiSim->getTotAtoms(); i++) { + eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); if(eof_test == NULL){ sprintf(painCave.errMsg, @@ -193,115 +203,82 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr "natoms = %d; index = %d\n" "error reading the line from the file.\n", c_in_name, n_atoms, i ); - painCave.isFatal = 1; + haveError= 1; simError(); } - parseErr = parseDumpLine( read_buffer, i ); - if( parseErr != NULL ){ - strcpy( painCave.errMsg, parseErr ); - painCave.isFatal = 1; - simError(); - } - masterIndex++; - } - } + if(haveError) nodeZeroError(); - sprintf(checkPointMsg, - "Node 0 has successfully read positions from input file."); - MPIcheckPoint(); - - for (procIndex = 1; procIndex < mpiSim->getNumberProcessors(); - procIndex++){ - if (worldRank == 0) { - - mpiErr = MPI_Recv(&nodeAtomsStart,1,MPI_INT,procIndex,TAKE_THIS_TAG,MPI_COMM_WORLD, - istatus); - - mpiErr = MPI_Recv(&nodeAtomsEnd,1,MPI_INT,procIndex,TAKE_THIS_TAG,MPI_COMM_WORLD, - istatus); - // Make sure where node 0 is reading from, matches where the receiving node - // expects it to be. - - if (masterIndex != nodeAtomsStart){ - sendError = 1; - mpiErr = MPI_Send(&sendError,1,MPI_INT,procIndex,TAKE_THIS_TAG,MPI_COMM_WORLD); - sprintf(painCave.errMsg, - "Initialize from file error: atoms start index (%d) for " - "node %d not equal to master index (%d)",nodeAtomsStart,procIndex,masterIndex ); - painCave.isFatal = 1; - simError(); - } - sendError = 0; - mpiErr = MPI_Send(&sendError,1,MPI_INT,procIndex,TAKE_THIS_TAG,MPI_COMM_WORLD); + // Get the Node number which wants this atom: + which_node = AtomToProcMap[i]; + if (which_node == 0) { + parseErr = parseDumpLine( read_buffer, i ); + if( parseErr != NULL ){ + strcpy( painCave.errMsg, parseErr ); + haveError = 1; + simError(); + } + if(haveError) nodeZeroError(); + } - for ( i = nodeAtomsStart; i <= nodeAtomsEnd; i++){ - eof_test = fgets(read_buffer, sizeof(read_buffer), c_in_file); - if(eof_test == NULL){ - - sprintf(read_buffer,"ERROR"); - mpiErr = MPI_Send(read_buffer,BUFFERSIZE,MPI_CHAR,procIndex,TAKE_THIS_TAG,MPI_COMM_WORLD); - - sprintf(painCave.errMsg, - "error in reading file %s\n" - "natoms = %d; index = %d\n" - "error reading the line from the file.\n", - c_in_name, n_atoms, i ); - painCave.isFatal = 1; - simError(); - } + else { + + myStatus = 1; + MPI::COMM_WORLD.Send(&myStatus, 1, MPI_INT, which_node, + TAKE_THIS_TAG_INT); + MPI::COMM_WORLD.Send(read_buffer, BUFFERSIZE, MPI_CHAR, which_node, + TAKE_THIS_TAG_CHAR); + MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT); + MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, which_node, TAKE_THIS_TAG_INT, istatus); - mpiErr = MPI_Send(read_buffer,BUFFERSIZE,MPI_CHAR,procIndex,TAKE_THIS_TAG,MPI_COMM_WORLD); - mpiErr = MPI_Recv(&sendError,1,MPI_INT,procIndex,TAKE_THIS_TAG,MPI_COMM_WORLD, - istatus); - if (sendError) MPIcheckPoint(); - - masterIndex++; + if(!myStatus) nodeZeroError(); } } + myStatus = -1; + for (j = 0; j < mpiSim->getNumberProcessors(); j++) { + MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, j, + TAKE_THIS_TAG_INT); + } + + } else { + + done = 0; + while (!done) { - - else if(worldRank == procIndex){ - nodeAtomsStart = mpiSim->getMyAtomStart(); - nodeAtomsEnd = mpiSim->getMyAtomEnd(); - mpiErr = MPI_Send(&nodeAtomsStart,1,MPI_INT,0,TAKE_THIS_TAG,MPI_COMM_WORLD); - mpiErr = MPI_Send(&nodeAtomsEnd,1,MPI_INT,0,TAKE_THIS_TAG,MPI_COMM_WORLD); + MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT, istatus); - mpiErr = MPI_Recv(&sendError,1,MPI_INT,0,TAKE_THIS_TAG,MPI_COMM_WORLD, - istatus); - if (sendError) MPIcheckPoint(); + if(!myStatus) anonymousNodeDie(); + + if(myStatus < 0) break; - for ( i = 0; i < entry_plug->n_atoms; i++){ - - mpiErr = MPI_Recv(&read_buffer,BUFFERSIZE,MPI_CHAR,0,TAKE_THIS_TAG,MPI_COMM_WORLD, - istatus); - - if(!strcmp(read_buffer, "ERROR")) MPIcheckPoint(); - - parseErr = parseDumpLine( read_buffer, i ); - if( parseErr != NULL ){ - sendError = 1; - mpiErr = MPI_Send(&sendError,1,MPI_INT,0,TAKE_THIS_TAG,MPI_COMM_WORLD); - - - strcpy( painCave.errMsg, parseErr ); - painCave.isFatal = 1; - simError(); - } - sendError = 0; - mpiErr = MPI_Send(&sendError,1,MPI_INT,0,TAKE_THIS_TAG,MPI_COMM_WORLD); + MPI::COMM_WORLD.Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0, + TAKE_THIS_TAG_CHAR, istatus); + MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT, istatus); + + myStatus = 1; + parseErr = parseDumpLine( read_buffer, which_atom ); + if( parseErr != NULL ){ + strcpy( painCave.errMsg, parseErr ); + myStatus = 0;; + simError(); } - } - sprintf(checkPointMsg,"Node %d received initial configuration.",procIndex); - MPIcheckPoint(); + + MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT); + + } } - + + // last thing last, enable fatalities. + painCave.isEventLoop = 0; + #endif } +char* InitializeFromFile::parseDumpLine(char* readLine, int globalIndex){ -char* InitializeFromFile::parseDumpLine(char* readLine, int atomIndex){ - char *foo; // the pointer to the current string token double rx, ry, rz; // position place holders @@ -313,15 +290,26 @@ char* InitializeFromFile::parseDumpLine(char* readLine Atom **atoms = entry_plug->atoms; DirectionalAtom* dAtom; - int n_atoms; + int j, n_atoms, atomIndex; #ifdef IS_MPI n_atoms = mpiSim->getTotAtoms(); + atomIndex=-1; + for (j=0; j < mpiSim->getMyNlocal(); j++) { + if (atoms[j]->getGlobalIndex() == globalIndex) atomIndex = j; + } + if (atomIndex == -1) { + sprintf( painCave.errMsg, + "Initialize from file error. Atom at index %d " + "in file %s does not exist on processor %d .\n", + globalIndex, c_in_name, mpiSim->getMyNode() ); + return strdup( painCave.errMsg ); + } #else n_atoms = entry_plug->n_atoms; + atomIndex = globalIndex; #endif // is_mpi - // set the string tokenizer foo = strtok(readLine, " ,;\t"); @@ -512,3 +500,31 @@ char* InitializeFromFile::parseDumpLine(char* readLine return NULL; } + + +#ifdef IS_MPI + +// a couple of functions to let us escape the read loop + +void nodeZeroError( void ){ + int j, myStatus; + + myStatus = 0; + for (j = 0; j < mpiSim->getNumberProcessors(); j++) { + MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, j, + TAKE_THIS_TAG_INT); + } + + + MPI_Finalize(); + exit (0); + +} + +void anonymousNodeDie( void ){ + + MPI_Finalize(); + exit (0); +} + +#endif //is_mpi