#include <stdio.h>
#include <stdlib.h>
#include < mpi.h>
int main(int argc, char **argv)
{
int rank, size, i, j, n,
// Initialize MPI
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Take input for n
if (rank == 0)
{
printf("Enter the value of n (must be divisible by p): "); scanf_s("%d", &n);
}
// Broadcast n to all processes
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Take input for p
if (rank == 0)
{
printf("Enter the value of p (must be smaller than n): "); scanf_s("%d", &p);
}
// Broadcast p to all processes
MPI_Bcast(&p, 1, MPI_INT, 0, MPI_COMM_WORLD);
// Error handling for p and n
if (n % p != 0)
{
if (rank == 0)
printf("Error: n must be divisible by p.\n"); MPI_Finalize();
return 0;
}
if (p >= n)
{
if (rank == 0)
printf("Error: p must be smaller than n.\n"); MPI_Finalize();
return 0;
}
// Define matrices and vectors dynamically
int *A
= (int *)malloc(sizeof(int) * n
* n
); int *x
= (int *)malloc(sizeof(int) * n
); int *y
= (int *)malloc(sizeof(int) * n
); int *local_A
= (int *)malloc(sizeof(int) * (n
/ p
) * n
); int *local_x
= (int *)malloc(sizeof(int) * (n
/ p
)); int *local_y
= (int *)malloc(sizeof(int) * (n
/ p
));
// Initialize matrices and vectors with random values
if (rank == 0)
{
for (i = 0; i < n * n; i++)
{
A
[i
] = rand() % 101; // random integer between 0 and 100 if ((i + 1) % n == 0)
}
for (i = 0; i < n; i++)
{
x
[i
] = rand() % 101; // random integer between 0 and 100 }
}
// Broadcast matrices and vectors to all processes
MPI_Bcast(A, n * n, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(x, n, MPI_INT, 0, MPI_COMM_WORLD);
// Calculate the local size for each process
int local_n = n / size;
// Scatter matrix A to all processes
MPI_Scatter(A, local_n * n, MPI_INT, local_A, local_n * n, MPI_INT, 0, MPI_COMM_WORLD);
// Scatter vector x to all processes
MPI_Scatter(x, local_n, MPI_INT, local_x, local_n, MPI_INT, 0, MPI_COMM_WORLD);
// Compute local vector elements
for (i = 0; i < local_n; i++)
{
local_y[i] = 0;
for (j = 0; j < n; j++)
{
local_y[i] += local_A[i * n + j] * local_x[j];
}
}
// Gather local results back to process 0
MPI_Gather(local_y, local_n, MPI_INT, y, local_n, MPI_INT, 0, MPI_COMM_WORLD);
// Process 0 prints the result
if (rank == 0)
{
printf("\nResultant Vector y:\n"); for (i = 0; i < n; i++)
{
printf("y[%d] = %d\n", i
, y
[i
]); }
}
// Free dynamically allocated memory
// Finalize MPI
MPI_Finalize();
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPCBtcGkuaD4KaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CiAgICBpbnQgcmFuaywgc2l6ZSwgaSwgaiwgbiwgCgogICAgLy8gSW5pdGlhbGl6ZSBNUEkKICAgIE1QSV9Jbml0KCZhcmdjLCAmYXJndik7CiAgICBNUElfQ29tbV9yYW5rKE1QSV9DT01NX1dPUkxELCAmcmFuayk7CiAgICBNUElfQ29tbV9zaXplKE1QSV9DT01NX1dPUkxELCAmc2l6ZSk7CgogICAgLy8gVGFrZSBpbnB1dCBmb3IgbgogICAgaWYgKHJhbmsgPT0gMCkKICAgIHsKICAgICAgICBwcmludGYoIkVudGVyIHRoZSB2YWx1ZSBvZiBuIChtdXN0IGJlIGRpdmlzaWJsZSBieSBwKTogIik7CiAgICAgICAgc2NhbmZfcygiJWQiLCAmbik7CiAgICB9CgogICAgLy8gQnJvYWRjYXN0IG4gdG8gYWxsIHByb2Nlc3NlcwogICAgTVBJX0JjYXN0KCZuLCAxLCBNUElfSU5ULCAwLCBNUElfQ09NTV9XT1JMRCk7CgogICAgLy8gVGFrZSBpbnB1dCBmb3IgcAogICAgaWYgKHJhbmsgPT0gMCkKICAgIHsKICAgICAgICBwcmludGYoIkVudGVyIHRoZSB2YWx1ZSBvZiBwIChtdXN0IGJlIHNtYWxsZXIgdGhhbiBuKTogIik7CiAgICAgICAgc2NhbmZfcygiJWQiLCAmcCk7CiAgICB9CgogICAgLy8gQnJvYWRjYXN0IHAgdG8gYWxsIHByb2Nlc3NlcwogICAgTVBJX0JjYXN0KCZwLCAxLCBNUElfSU5ULCAwLCBNUElfQ09NTV9XT1JMRCk7CgogICAgLy8gRXJyb3IgaGFuZGxpbmcgZm9yIHAgYW5kIG4KICAgIGlmIChuICUgcCAhPSAwKQogICAgewogICAgICAgIGlmIChyYW5rID09IDApCiAgICAgICAgICAgIHByaW50ZigiRXJyb3I6IG4gbXVzdCBiZSBkaXZpc2libGUgYnkgcC5cbiIpOwogICAgICAgIE1QSV9GaW5hbGl6ZSgpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChwID49IG4pCiAgICB7CiAgICAgICAgaWYgKHJhbmsgPT0gMCkKICAgICAgICAgICAgcHJpbnRmKCJFcnJvcjogcCBtdXN0IGJlIHNtYWxsZXIgdGhhbiBuLlxuIik7CiAgICAgICAgTVBJX0ZpbmFsaXplKCk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLy8gRGVmaW5lIG1hdHJpY2VzIGFuZCB2ZWN0b3JzIGR5bmFtaWNhbGx5CiAgICBpbnQgKkEgPSAoaW50ICopbWFsbG9jKHNpemVvZihpbnQpICogbiAqIG4pOwogICAgaW50ICp4ID0gKGludCAqKW1hbGxvYyhzaXplb2YoaW50KSAqIG4pOwogICAgaW50ICp5ID0gKGludCAqKW1hbGxvYyhzaXplb2YoaW50KSAqIG4pOwogICAgaW50ICpsb2NhbF9BID0gKGludCAqKW1hbGxvYyhzaXplb2YoaW50KSAqIChuIC8gcCkgKiBuKTsKICAgIGludCAqbG9jYWxfeCA9IChpbnQgKiltYWxsb2Moc2l6ZW9mKGludCkgKiAobiAvIHApKTsKICAgIGludCAqbG9jYWxfeSA9IChpbnQgKiltYWxsb2Moc2l6ZW9mKGludCkgKiAobiAvIHApKTsKCiAgICAvLyBJbml0aWFsaXplIG1hdHJpY2VzIGFuZCB2ZWN0b3JzIHdpdGggcmFuZG9tIHZhbHVlcwogICAgaWYgKHJhbmsgPT0gMCkKICAgIHsKICAgICAgICBwcmludGYoIlxuTWF0cml4IEE6XG4iKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbiAqIG47IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIEFbaV0gPSByYW5kKCkgJSAxMDE7IC8vIHJhbmRvbSBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMTAwCiAgICAgICAgICAgIHByaW50ZigiJWRcdCIsIEFbaV0pOwogICAgICAgICAgICBpZiAoKGkgKyAxKSAlIG4gPT0gMCkKICAgICAgICAgICAgICAgIHByaW50ZigiXG4iKTsKICAgICAgICB9CgogICAgICAgIHByaW50ZigiXG5WZWN0b3IgeDpcbiIpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspCiAgICAgICAgewogICAgICAgICAgICB4W2ldID0gcmFuZCgpICUgMTAxOyAvLyByYW5kb20gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDEwMAogICAgICAgICAgICBwcmludGYoIiVkXG4iLCB4W2ldKTsKICAgICAgICB9CiAgICB9CgogICAgLy8gQnJvYWRjYXN0IG1hdHJpY2VzIGFuZCB2ZWN0b3JzIHRvIGFsbCBwcm9jZXNzZXMKICAgIE1QSV9CY2FzdChBLCBuICogbiwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwogICAgTVBJX0JjYXN0KHgsIG4sIE1QSV9JTlQsIDAsIE1QSV9DT01NX1dPUkxEKTsKCiAgICAvLyBDYWxjdWxhdGUgdGhlIGxvY2FsIHNpemUgZm9yIGVhY2ggcHJvY2VzcwogICAgaW50IGxvY2FsX24gPSBuIC8gc2l6ZTsKCiAgICAvLyBTY2F0dGVyIG1hdHJpeCBBIHRvIGFsbCBwcm9jZXNzZXMKICAgIE1QSV9TY2F0dGVyKEEsIGxvY2FsX24gKiBuLCBNUElfSU5ULCBsb2NhbF9BLCBsb2NhbF9uICogbiwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIC8vIFNjYXR0ZXIgdmVjdG9yIHggdG8gYWxsIHByb2Nlc3NlcwogICAgTVBJX1NjYXR0ZXIoeCwgbG9jYWxfbiwgTVBJX0lOVCwgbG9jYWxfeCwgbG9jYWxfbiwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIC8vIENvbXB1dGUgbG9jYWwgdmVjdG9yIGVsZW1lbnRzCiAgICBmb3IgKGkgPSAwOyBpIDwgbG9jYWxfbjsgaSsrKQogICAgewogICAgICAgIGxvY2FsX3lbaV0gPSAwOwogICAgICAgIGZvciAoaiA9IDA7IGogPCBuOyBqKyspCiAgICAgICAgewogICAgICAgICAgICBsb2NhbF95W2ldICs9IGxvY2FsX0FbaSAqIG4gKyBqXSAqIGxvY2FsX3hbal07CiAgICAgICAgfQogICAgfQoKICAgIC8vIEdhdGhlciBsb2NhbCByZXN1bHRzIGJhY2sgdG8gcHJvY2VzcyAwCiAgICBNUElfR2F0aGVyKGxvY2FsX3ksIGxvY2FsX24sIE1QSV9JTlQsIHksIGxvY2FsX24sIE1QSV9JTlQsIDAsIE1QSV9DT01NX1dPUkxEKTsKCiAgICAvLyBQcm9jZXNzIDAgcHJpbnRzIHRoZSByZXN1bHQKICAgIGlmIChyYW5rID09IDApCiAgICB7CiAgICAgICAgcHJpbnRmKCJcblJlc3VsdGFudCBWZWN0b3IgeTpcbiIpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspCiAgICAgICAgewogICAgICAgICAgICBwcmludGYoInlbJWRdID0gJWRcbiIsIGksIHlbaV0pOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBGcmVlIGR5bmFtaWNhbGx5IGFsbG9jYXRlZCBtZW1vcnkKICAgIGZyZWUoQSk7CiAgICBmcmVlKHgpOwogICAgZnJlZSh5KTsKICAgIGZyZWUobG9jYWxfQSk7CiAgICBmcmVlKGxvY2FsX3gpOwogICAgZnJlZShsb2NhbF95KTsKCiAgICAvLyBGaW5hbGl6ZSBNUEkKICAgIE1QSV9GaW5hbGl6ZSgpOwoKICAgIHJldHVybiAwOwp9