static int fPMI_Handle_abort(PMIProcess * pentry) { char exitcodestr[MAXVALLEN]; int exitcode = 1; /* non-zero default */ exitcode = atoi(PMIU_getval("exitcode", exitcodestr, MAXVALLEN)); /* cleanup all MPI processes */ MPIE_KillUniverse(&pUniv); exit(exitcode); /* should never reach here */ return 1; }
/* Note that envp is common but not standard */ int main( int argc, char *argv[], char *envp[] ) { int rc; int erc = 0; /* Other (exceptional) return codes */ int reason, signaled = 0; SetupInfo s; char portString[MAX_PORT_STRING]; /* MPIE_ProcessInit initializes the global pUniv */ MPIE_ProcessInit(); /* Set a default for the universe size */ pUniv.size = 64; /* Set defaults for any arguments that are options. Also check the environment for special options, such as debugging. Set some defaults in pUniv */ MPIE_CheckEnv( &pUniv, 0, 0 ); IOLabelCheckEnv( ); /* Handle the command line arguments. Use the routine from util/cmnargs.c to fill in the universe */ MPIE_Args( argc, argv, &pUniv, 0, 0 ); /* If there were any soft arguments, we need to handle them now */ rc = MPIE_InitWorldWithSoft( &pUniv.worlds[0], pUniv.size ); if (!rc) { MPL_error_printf( "Unable to process soft arguments\n" ); exit(1); } if (pUniv.fromSingleton) { /* The MPI process is already running. We create a simple entry for a single process rather than creating the process */ MPIE_SetupSingleton( &pUniv ); } rc = MPIE_ChooseHosts( &pUniv.worlds[0], MPIE_ReadMachines, 0 ); if (rc) { MPL_error_printf( "Unable to assign hosts to processes\n" ); exit(1); } if (MPIE_Debug) MPIE_PrintProcessUniverse( stdout, &pUniv ); DBG_PRINTF( ("timeout_seconds = %d\n", pUniv.timeout) ); /* Get the common port for creating PMI connections to the created processes */ rc = PMIServSetupPort( &pUniv, portString, sizeof(portString) ); if (rc) { MPL_error_printf( "Unable to setup port for listener\n" ); exit(1); } s.pmiinfo.portName = portString; #ifdef USE_MPI_STAGE_EXECUTABLES /* Hook for later use in staging executables */ if (?stageExes) { rc = MPIE_StageExecutables( &pUniv.worlds[0] ); if (!rc) ...; } #endif PMIServInit(myspawn,&s); s.pmiinfo.pWorld = &pUniv.worlds[0]; PMISetupNewGroup( pUniv.worlds[0].nProcess, 0 ); MPIE_ForwardCommonSignals(); if (!pUniv.fromSingleton) { MPIE_ForkProcesses( &pUniv.worlds[0], envp, mypreamble, &s, mypostfork, 0, mypostamble, 0 ); } else { /* FIXME: The singleton code goes here */ MPL_error_printf( "Singleton init not supported\n" ); exit(1); } reason = MPIE_IOLoop( pUniv.timeout ); if (reason == IOLOOP_TIMEOUT) { /* Exited due to timeout. Generate an error message and terminate the children */ if (pUniv.timeout > 60) { MPL_error_printf( "Timeout of %d minutes expired; job aborted\n", pUniv.timeout / 60 ); } else { MPL_error_printf( "Timeout of %d seconds expired; job aborted\n", pUniv.timeout ); } erc = 1; MPIE_KillUniverse( &pUniv ); } /* Wait for all processes to exit and gather information on them. We do this through the SIGCHLD handler. We also bound the length of time that we wait to 2 seconds. */ MPIE_WaitForProcesses( &pUniv, 2 ); /* Compute the return code (max for now) */ rc = MPIE_ProcessGetExitStatus( &signaled ); /* Optionally provide detailed information about failed processes */ if ( (rc && printFailure) || signaled) MPIE_PrintFailureReasons( stderr ); /* If the processes exited normally (or were already gone) but we had an exceptional exit, such as a timeout, use the erc value */ if (!rc && erc) rc = erc; return( rc ); }