/* mpi.collective.example.c SJ */ #include #include #include #include #include /* these variables are used by prefix sum also, hence here */ static int P, PID; int main(int argc, char **argv) { int i, num, psum, ksum, *arr, *input; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &PID); MPI_Comm_size(MPI_COMM_WORLD, &P); arr = (int*)malloc(P*sizeof(int)); /* 0 creates input, sends */ if (PID == 0) { srand(getpid()); input = (int*)malloc(P*sizeof(int)); printf("Input is:"); for (i = 0; i < P; i++) { input[i] = rand()%10; printf(" %d", input[i]); } printf("\n"); } /* 0 sends pieces of data to everyone */ MPI_Scatter(input, 1, MPI_INT, &num, 1, MPI_INT, 0, MPI_COMM_WORLD); printf("%d: num = %d\n", PID, num); /* "compute" something */ psum = num*num /* collect the results to the first process */ MPI_Gather(&psum, 1, MPI_INT, arr, 1, MPI_INT, 0, MPI_COMM_WORLD); if (PID == 0) { printf("Gather:"); for (i = 0; i < P; i++) printf(" %d", arr[i]); printf("\n"); } /* make sum of all values to process 0 */ MPI_Reduce(&num, &ksum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if (PID == 0) { printf("Reduce: %d\n", ksum); } /* same again, but for all processes */ MPI_Allreduce(&num, &ksum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); printf("%d: Allreduce: %d\n", PID, ksum); /* prefix sum over all processes */ MPI_Scan(&num, &psum, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); /* collect result to PID 0 */ MPI_Gather(&psum, 1, MPI_INT, arr, 1, MPI_INT, 0, MPI_COMM_WORLD); if (PID == 0) { printf("Scan&Gather:"); for (i = 0; i < P; i++) printf(" %d", arr[i]); printf("\n"); } free(arr); MPI_Finalize(); exit(0); }