--- trunk/OOPSE/libmdtools/InitializeFromFile.cpp 2003/03/27 15:07:29 419 +++ trunk/OOPSE/libmdtools/InitializeFromFile.cpp 2003/03/28 21:45:03 436 @@ -15,7 +15,12 @@ #include #include #include "mpiSimulation.hpp" -#define TAKE_THIS_TAG 0 +#define TAKE_THIS_TAG_CHAR 0 +#define TAKE_THIS_TAG_INT 1 + +void nodeZeroError( void ); +void anonymousNodeDie( void ); + #endif // is_mpi InitializeFromFile :: InitializeFromFile( char *in_name ){ @@ -139,15 +144,24 @@ void InitializeFromFile :: read_xyz( SimInfo* the_entr // MPI Section of code.......... #else //IS_MPI + // first thing first, suspend fatalities. + painCave.isEventLoop = 1; + + 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(); } @@ -164,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(); } @@ -174,10 +188,11 @@ 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(); } + if(haveError) nodeZeroError(); for (i=0 ; i < mpiSim->getTotAtoms(); i++) { @@ -188,54 +203,77 @@ 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(); } + if(haveError) nodeZeroError(); + // Get the Node number which wants this atom: which_node = AtomToProcMap[i]; - if (which_node == mpiSim->getMyNode()) { + if (which_node == 0) { parseErr = parseDumpLine( read_buffer, i ); if( parseErr != NULL ){ strcpy( painCave.errMsg, parseErr ); - painCave.isFatal = 1; + haveError = 1; simError(); } - } else { + if(haveError) nodeZeroError(); + } + + 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); - MPI::COMM_WORLD.Send(&i, 1, MPI_INT, which_node, TAKE_THIS_TAG); + 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); + + if(!myStatus) nodeZeroError(); } } - sprintf(read_buffer, "GAMEOVER"); + myStatus = -1; for (j = 0; j < mpiSim->getNumberProcessors(); j++) { - MPI::COMM_WORLD.Send(read_buffer, BUFFERSIZE, MPI_CHAR, j, - TAKE_THIS_TAG); + MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, j, + TAKE_THIS_TAG_INT); } } else { done = 0; while (!done) { + + MPI::COMM_WORLD.Recv(&myStatus, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT, istatus); + + if(!myStatus) anonymousNodeDie(); + + if(myStatus < 0) break; + MPI::COMM_WORLD.Recv(read_buffer, BUFFERSIZE, MPI_CHAR, 0, - TAKE_THIS_TAG, istatus); - if (strcmp(read_buffer, "GAMEOVER")) { - done = 1; - continue; - } else { - MPI::COMM_WORLD.Recv(&which_atom, 1, MPI_INT, 0, - TAKE_THIS_TAG, istatus); - - parseErr = parseDumpLine( read_buffer, which_atom ); - if( parseErr != NULL ){ - strcpy( painCave.errMsg, parseErr ); - painCave.isFatal = 1; - simError(); - } + 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(); } + + MPI::COMM_WORLD.Send( &myStatus, 1, MPI_INT, 0, + TAKE_THIS_TAG_INT); + } } - + + // last thing last, enable fatalities. + painCave.isEventLoop = 0; + #endif } @@ -462,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