#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// size of array
#define n 10
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Temporary array for slave process
int a2[1000];
int main(int argc, char* argv[])
{
int pid, np,elements_per_process,n_elements_recieved;
// np -> no. of processes
// pid -> process id
MPI_Status status;
// Creation of parallel processes
MPI_Init(&argc, &argv);
// find out process ID,
// and how many processes were started
MPI_Comm_rank(MPI_COMM_WORLD, &pid);
MPI_Comm_size(MPI_COMM_WORLD, &np);
// master process
if (pid == 0)
{
int index,i;
elements_per_process = n / np;
// check if more than 1 processes are run
if (np > 1)
{
// distributes the portion of array
// to child processes to calculate
// their partial sums
for (i = 1; i < np - 1; i++)
{
index = i * elements_per_process;
MPI_Send(&elements_per_process,1, MPI_INT, i, 0,MPI_COMM_WORLD);
MPI_Send(&a[index],elements_per_process,MPI_INT, i, 0,MPI_COMM_WORLD);
}
// last process adds remaining elements
index = i * elements_per_process;
int elements_left = n - index;
MPI_Send(&elements_left,1, MPI_INT,i, 0,MPI_COMM_WORLD);
MPI_Send(&a[index],elements_left,MPI_INT, i, 0,MPI_COMM_WORLD);
}
// master process add its own sub array
int sum = 0;
for (i = 0; i < elements_per_process; i++)
sum += a[i];
// collects partial sums from other processes
int tmp;
for (i = 1; i < np; i++)
{
MPI_Recv(&tmp, 1, MPI_INT,MPI_ANY_SOURCE, 0,MPI_COMM_WORLD,&status);
int sender = status.MPI_SOURCE;
sum += tmp;
}
// prints the final sum of array
printf("Sum of array is : %d\n", sum
); }
// slave processes
else
{
MPI_Recv(&n_elements_recieved,1, MPI_INT, 0, 0,MPI_COMM_WORLD,&status);
// stores the received array segment
// in local array a2
MPI_Recv(&a2, n_elements_recieved,MPI_INT, 0, 0,MPI_COMM_WORLD,&status);
// calculates its partial sum
int partial_sum = 0;
for (int i = 0; i < n_elements_recieved; i++)
partial_sum += a2[i];
// sends the partial sum to the root process
MPI_Send(&partial_sum, 1, MPI_INT,0, 0, MPI_COMM_WORLD);
}
// cleans up all MPI state before exit of process
MPI_Finalize();
return 0;
}
I2luY2x1ZGUgPG1waS5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiAKLy8gc2l6ZSBvZiBhcnJheQojZGVmaW5lIG4gMTAKIAppbnQgYVtdID0geyAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCB9OwogCi8vIFRlbXBvcmFyeSBhcnJheSBmb3Igc2xhdmUgcHJvY2VzcwppbnQgYTJbMTAwMF07CiAKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkKewogCiAgICBpbnQgcGlkLCBucCxlbGVtZW50c19wZXJfcHJvY2VzcyxuX2VsZW1lbnRzX3JlY2lldmVkOwogICAgLy8gbnAgLT4gbm8uIG9mIHByb2Nlc3NlcwogICAgLy8gcGlkIC0+IHByb2Nlc3MgaWQKIAogICAgTVBJX1N0YXR1cyBzdGF0dXM7CiAKICAgIC8vIENyZWF0aW9uIG9mIHBhcmFsbGVsIHByb2Nlc3NlcwogICAgTVBJX0luaXQoJmFyZ2MsICZhcmd2KTsKIAogICAgLy8gZmluZCBvdXQgcHJvY2VzcyBJRCwKICAgIC8vIGFuZCBob3cgbWFueSBwcm9jZXNzZXMgd2VyZSBzdGFydGVkCiAgICBNUElfQ29tbV9yYW5rKE1QSV9DT01NX1dPUkxELCAmcGlkKTsKICAgIE1QSV9Db21tX3NpemUoTVBJX0NPTU1fV09STEQsICZucCk7CiAKICAgIC8vIG1hc3RlciBwcm9jZXNzCiAgICBpZiAocGlkID09IDApCiAgICB7CiAgICAgICAgaW50IGluZGV4LGk7CiAgICAgICAgZWxlbWVudHNfcGVyX3Byb2Nlc3MgPSBuIC8gbnA7CiAKICAgICAgICAvLyBjaGVjayBpZiBtb3JlIHRoYW4gMSBwcm9jZXNzZXMgYXJlIHJ1bgogICAgICAgIGlmIChucCA+IDEpCiAgICAgICAgewogICAgICAgICAgICAvLyBkaXN0cmlidXRlcyB0aGUgcG9ydGlvbiBvZiBhcnJheQogICAgICAgICAgICAvLyB0byBjaGlsZCBwcm9jZXNzZXMgdG8gY2FsY3VsYXRlCiAgICAgICAgICAgIC8vIHRoZWlyIHBhcnRpYWwgc3VtcwogICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgbnAgLSAxOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGluZGV4ID0gaSAqIGVsZW1lbnRzX3Blcl9wcm9jZXNzOwogCiAgICAgICAgICAgICAgICBNUElfU2VuZCgmZWxlbWVudHNfcGVyX3Byb2Nlc3MsMSwgTVBJX0lOVCwgaSwgMCxNUElfQ09NTV9XT1JMRCk7CiAgICAgICAgICAgICAgICBNUElfU2VuZCgmYVtpbmRleF0sZWxlbWVudHNfcGVyX3Byb2Nlc3MsTVBJX0lOVCwgaSwgMCxNUElfQ09NTV9XT1JMRCk7CiAgICAgICAgICAgIH0KIAogICAgICAgICAgICAvLyBsYXN0IHByb2Nlc3MgYWRkcyByZW1haW5pbmcgZWxlbWVudHMKICAgICAgICAgICAgaW5kZXggPSBpICogZWxlbWVudHNfcGVyX3Byb2Nlc3M7CiAgICAgICAgICAgIGludCBlbGVtZW50c19sZWZ0ID0gbiAtIGluZGV4OwogCiAgICAgICAgICAgIE1QSV9TZW5kKCZlbGVtZW50c19sZWZ0LDEsIE1QSV9JTlQsaSwgMCxNUElfQ09NTV9XT1JMRCk7CiAgICAgICAgICAgIE1QSV9TZW5kKCZhW2luZGV4XSxlbGVtZW50c19sZWZ0LE1QSV9JTlQsIGksIDAsTVBJX0NPTU1fV09STEQpOwogICAgICAgfQogCiAgICAgICAgLy8gbWFzdGVyIHByb2Nlc3MgYWRkIGl0cyBvd24gc3ViIGFycmF5CiAgICAgICAgaW50IHN1bSA9IDA7CiAgICAgICAgCiAgICAgICAgZm9yIChpID0gMDsgaSA8IGVsZW1lbnRzX3Blcl9wcm9jZXNzOyBpKyspCiAgICAgICAgICAgIHN1bSArPSBhW2ldOwogCiAgICAgICAgLy8gY29sbGVjdHMgcGFydGlhbCBzdW1zIGZyb20gb3RoZXIgcHJvY2Vzc2VzCiAgICAgICAgaW50IHRtcDsKICAgICAgICAKICAgICAgICBmb3IgKGkgPSAxOyBpIDwgbnA7IGkrKykgCiAgICAgICAgewogICAgICAgICAgICBNUElfUmVjdigmdG1wLCAxLCBNUElfSU5ULE1QSV9BTllfU09VUkNFLCAwLE1QSV9DT01NX1dPUkxELCZzdGF0dXMpOwogICAgICAgICAgICAKICAgICAgICAgICAgaW50IHNlbmRlciA9IHN0YXR1cy5NUElfU09VUkNFOwogCSAgICAgc3VtICs9IHRtcDsKICAgICAgICB9CiAKICAgICAgICAvLyBwcmludHMgdGhlIGZpbmFsIHN1bSBvZiBhcnJheQogICAgICAgIHByaW50ZigiU3VtIG9mIGFycmF5IGlzIDogJWRcbiIsIHN1bSk7CiAgICB9CiAgICAKICAgIC8vIHNsYXZlIHByb2Nlc3NlcwogICAgZWxzZQogICAgewogICAgICAgIE1QSV9SZWN2KCZuX2VsZW1lbnRzX3JlY2lldmVkLDEsIE1QSV9JTlQsIDAsIDAsTVBJX0NPTU1fV09STEQsJnN0YXR1cyk7CiAKICAgICAgICAvLyBzdG9yZXMgdGhlIHJlY2VpdmVkIGFycmF5IHNlZ21lbnQKICAgICAgICAvLyBpbiBsb2NhbCBhcnJheSBhMgogICAgICAgIE1QSV9SZWN2KCZhMiwgbl9lbGVtZW50c19yZWNpZXZlZCxNUElfSU5ULCAwLCAwLE1QSV9DT01NX1dPUkxELCZzdGF0dXMpOwogCiAgICAgICAgLy8gY2FsY3VsYXRlcyBpdHMgcGFydGlhbCBzdW0KICAgICAgICBpbnQgcGFydGlhbF9zdW0gPSAwOwogICAgICAgIAogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbl9lbGVtZW50c19yZWNpZXZlZDsgaSsrKQogICAgICAgICAgICBwYXJ0aWFsX3N1bSArPSBhMltpXTsKIAogICAgICAgIC8vIHNlbmRzIHRoZSBwYXJ0aWFsIHN1bSB0byB0aGUgcm9vdCBwcm9jZXNzCiAgICAgICAgTVBJX1NlbmQoJnBhcnRpYWxfc3VtLCAxLCBNUElfSU5ULDAsIDAsIE1QSV9DT01NX1dPUkxEKTsKICAgIH0KIAogICAgLy8gY2xlYW5zIHVwIGFsbCBNUEkgc3RhdGUgYmVmb3JlIGV4aXQgb2YgcHJvY2VzcwogICAgTVBJX0ZpbmFsaXplKCk7CiAKICAgIHJldHVybiAwOwp9Cg==