/* Brute-force computation of the sum of a range of integers starting at zero. * Subrange assignments are distributed by the master. * Works for input values up to 2x10^9 (long int is apparently 61 bits) * Usage: sum_b [range] */ #include #include #include #include #define HOST_NAME_MAX 127 int main (int argc, char *argv[]) { int rank, size; char hname[HOST_NAME_MAX+1]; int i; unsigned long int part, result = 0; /* partial and total result */ unsigned long int range = 1000000; /* default range */ unsigned long subrange[2]; /* upper and lower subrange limits */ MPI_Status stat; gethostname(hname, HOST_NAME_MAX); MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* get this processor's unique ID */ MPI_Comm_size(MPI_COMM_WORLD, &size); /* get total number of processors available */ if (argc > 1) range = (unsigned long int) strtol(argv[1], (char **)NULL, 10); if (rank == 0) { // Master distributes subranges for (i = 1; i < size; i++) { subrange[0] = range/(size - 1)*(i - 1) + 1; // lower limit subrange[1] = range/(size - 1)*i; // upper limit MPI_Send(&subrange, 2, MPI_UNSIGNED_LONG, i, i, MPI_COMM_WORLD); } for (i = subrange[1] + 1; i <= range; i++) // master sums partial subrange (if any) result += i; for (i = 1; i < size; i++) { // master accumulates partial results MPI_Recv(&part, 1, MPI_UNSIGNED_LONG, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat); // printf("partial result %d from node %d of %d\n", part, stat.MPI_SOURCE, size); result += part; } printf ("%s, node %d of %d - Sum of integers from 0 to %ld = %ld\n", hname, rank, size, range, result); } else { // Slave nodes MPI_Recv(&subrange, 2, MPI_UNSIGNED_LONG, 0, rank, MPI_COMM_WORLD, &stat); for (i = subrange[0]; i <= subrange[1]; i++) { result += i; } printf("%s, node %d of %d - partial result %ld to %ld = %ld\n", hname, rank, size, subrange[0], subrange[1], result); MPI_Send(&result, 1, MPI_UNSIGNED_LONG, 0, rank, MPI_COMM_WORLD); } MPI_Finalize();