/* -*- Mode: C; c-basic-offset:4 ; -*- */ #include "mpi.h" #include #include #include #include #include char* TimeStamp(void) { char* Result; time_t Time; char* EndOfLine; Time = time(NULL); Result = asctime(localtime(&Time)); EndOfLine = strchr(Result, '\n'); if (EndOfLine) *EndOfLine = '\0'; return Result; } int main(int argc, char* argv[]) { int ID, NumberProcesses; char ProcessorName[MPI_MAX_PROCESSOR_NAME]; int ProcessorNameLength; int *UniverseSize, Flag; MPI_Comm InterComm, IntraComm; int Parent = 0; int NumberOfSpawns = 0; int Printed = 0; MPI_Init(&argc, &argv); MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, &UniverseSize, &Flag); do { if (Flag && (*UniverseSize > 1)) { MPI_Comm_get_parent(&InterComm); if (InterComm == MPI_COMM_NULL) { int Error; int* ErrorCodes; Parent = 1; ErrorCodes = (int*) calloc(*UniverseSize - 1, sizeof(int)); sleep(1); printf("Spawn %d children at %s. Attempt %d\n", *UniverseSize - 1, TimeStamp(), NumberOfSpawns); Error = MPI_Comm_spawn("Spawn", MPI_ARGV_NULL, *UniverseSize - 1, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &InterComm, ErrorCodes); if (Error) printf("Can't spawn child processes\n"); MPI_Intercomm_merge(InterComm, 0, &IntraComm); free(ErrorCodes); } else MPI_Intercomm_merge(InterComm, 1, &IntraComm); MPI_Comm_size(IntraComm, &NumberProcesses); MPI_Comm_rank(IntraComm, &ID); } MPI_Get_processor_name(ProcessorName, &ProcessorNameLength); if (!Printed) { printf("Start %s process %d of %d on %s in universe of %d\n", (Parent ? "parent" : "child"), ID, NumberProcesses, ProcessorName, *UniverseSize); Printed = 1; } if (Flag && (*UniverseSize > 1)) { if (Parent) { int Count = 0; while (Count < (*UniverseSize - 1)) { int Data; MPI_Status status; if (MPI_Recv(&Data, sizeof(Data), MPI_BYTE, MPI_ANY_SOURCE, 0, IntraComm, &status) == MPI_SUCCESS) { printf("Receive data from child %d\n", Data); ++Count; } } } else { int Data = ID; if (MPI_Send(&Data, sizeof(Data), MPI_BYTE, 0, 0, IntraComm) == MPI_SUCCESS) printf("Send data from child %d\n", Data); } } ++NumberOfSpawns; } while (Parent && (NumberOfSpawns < 3)); printf("Finalize process %d at %s\n", ID, TimeStamp()); MPI_Finalize(); printf("Exit from process %d at %s\n", ID, TimeStamp()); return 0; }