#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#define MATRIX_SIZE 1024 // Change this to 64, 128, 256, 512, 1024 as needed
void matrix_multiply(int *A, int *B, int *C, int size) {
int i, j, k;
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
C[i * size + j] = 0;
for (k = 0; k < size; k++) {
C[i * size + j] += A[i * size + k] * B[k * size + j];
}
}
}
}
int main(int argc, char *argv[]) {
int rank, size;
int nrows_per_proc;
int *A, *B, *C, *local_A, *local_C;
int i, j;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Determine the number of rows per processor
nrows_per_proc = MATRIX_SIZE / size;
// Allocate memory for matrices
if (rank == 0) {
A
= (int *)malloc(MATRIX_SIZE
* MATRIX_SIZE
* sizeof(int)); B
= (int *)malloc(MATRIX_SIZE
* MATRIX_SIZE
* sizeof(int)); C
= (int *)malloc(MATRIX_SIZE
* MATRIX_SIZE
* sizeof(int));
// Initialize matrices A and B with random values
for (i = 0; i < MATRIX_SIZE; i++) {
for (j = 0; j < MATRIX_SIZE; j++) {
A
[i
* MATRIX_SIZE
+ j
] = rand() % 10; B
[i
* MATRIX_SIZE
+ j
] = rand() % 10; }
}
}
// Allocate memory for local matrices
local_A
= (int *)malloc(nrows_per_proc
* MATRIX_SIZE
* sizeof(int)); local_C
= (int *)malloc(nrows_per_proc
* MATRIX_SIZE
* sizeof(int)); B
= (int *)malloc(MATRIX_SIZE
* MATRIX_SIZE
* sizeof(int)); // Each process needs the entire matrix B
// Scatter rows of A to different processes
MPI_Scatter(A, nrows_per_proc * MATRIX_SIZE, MPI_INT, local_A, nrows_per_proc * MATRIX_SIZE, MPI_INT, 0, MPI_COMM_WORLD);
// Broadcast matrix B to all processes
MPI_Bcast(B, MATRIX_SIZE * MATRIX_SIZE, MPI_INT, 0, MPI_COMM_WORLD);
// Perform local matrix multiplication
for (i = 0; i < nrows_per_proc; i++) {
for (j = 0; j < MATRIX_SIZE; j++) {
local_C[i * MATRIX_SIZE + j] = 0;
for (int k = 0; k < MATRIX_SIZE; k++) {
local_C[i * MATRIX_SIZE + j] += local_A[i * MATRIX_SIZE + k] * B[k * MATRIX_SIZE + j];
}
}
}
// Gather the result matrix C from all processes
MPI_Gather(local_C, nrows_per_proc * MATRIX_SIZE, MPI_INT, C, nrows_per_proc * MATRIX_SIZE, MPI_INT, 0, MPI_COMM_WORLD);
// Print result if necessary
if (rank == 0) {
printf("Result Matrix C (Showing first 5x5):\n"); for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
printf("%d ", C
[i
* MATRIX_SIZE
+ j
]); }
}
}
// Clean up memory
if (rank == 0) {
}
MPI_Finalize();
return 0;
}
I2luY2x1ZGUgPG1waS5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKI2RlZmluZSBNQVRSSVhfU0laRSAxMDI0ICAvLyBDaGFuZ2UgdGhpcyB0byA2NCwgMTI4LCAyNTYsIDUxMiwgMTAyNCBhcyBuZWVkZWQKCnZvaWQgbWF0cml4X211bHRpcGx5KGludCAqQSwgaW50ICpCLCBpbnQgKkMsIGludCBzaXplKSB7CiAgICBpbnQgaSwgaiwgazsKICAgIGZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKICAgICAgICBmb3IgKGogPSAwOyBqIDwgc2l6ZTsgaisrKSB7CiAgICAgICAgICAgIENbaSAqIHNpemUgKyBqXSA9IDA7CiAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBzaXplOyBrKyspIHsKICAgICAgICAgICAgICAgIENbaSAqIHNpemUgKyBqXSArPSBBW2kgKiBzaXplICsga10gKiBCW2sgKiBzaXplICsgal07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pIHsKICAgIGludCByYW5rLCBzaXplOwogICAgaW50IG5yb3dzX3Blcl9wcm9jOwogICAgaW50ICpBLCAqQiwgKkMsICpsb2NhbF9BLCAqbG9jYWxfQzsKICAgIGludCBpLCBqOwoKICAgIE1QSV9Jbml0KCZhcmdjLCAmYXJndik7CiAgICBNUElfQ29tbV9yYW5rKE1QSV9DT01NX1dPUkxELCAmcmFuayk7CiAgICBNUElfQ29tbV9zaXplKE1QSV9DT01NX1dPUkxELCAmc2l6ZSk7CgogICAgLy8gRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2Ygcm93cyBwZXIgcHJvY2Vzc29yCiAgICBucm93c19wZXJfcHJvYyA9IE1BVFJJWF9TSVpFIC8gc2l6ZTsKCiAgICAvLyBBbGxvY2F0ZSBtZW1vcnkgZm9yIG1hdHJpY2VzCiAgICBpZiAocmFuayA9PSAwKSB7CiAgICAgICAgQSA9IChpbnQgKiltYWxsb2MoTUFUUklYX1NJWkUgKiBNQVRSSVhfU0laRSAqIHNpemVvZihpbnQpKTsKICAgICAgICBCID0gKGludCAqKW1hbGxvYyhNQVRSSVhfU0laRSAqIE1BVFJJWF9TSVpFICogc2l6ZW9mKGludCkpOwogICAgICAgIEMgPSAoaW50ICopbWFsbG9jKE1BVFJJWF9TSVpFICogTUFUUklYX1NJWkUgKiBzaXplb2YoaW50KSk7CgogICAgICAgIC8vIEluaXRpYWxpemUgbWF0cmljZXMgQSBhbmQgQiB3aXRoIHJhbmRvbSB2YWx1ZXMKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFUUklYX1NJWkU7IGkrKykgewogICAgICAgICAgICBmb3IgKGogPSAwOyBqIDwgTUFUUklYX1NJWkU7IGorKykgewogICAgICAgICAgICAgICAgQVtpICogTUFUUklYX1NJWkUgKyBqXSA9IHJhbmQoKSAlIDEwOwogICAgICAgICAgICAgICAgQltpICogTUFUUklYX1NJWkUgKyBqXSA9IHJhbmQoKSAlIDEwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8vIEFsbG9jYXRlIG1lbW9yeSBmb3IgbG9jYWwgbWF0cmljZXMKICAgIGxvY2FsX0EgPSAoaW50ICopbWFsbG9jKG5yb3dzX3Blcl9wcm9jICogTUFUUklYX1NJWkUgKiBzaXplb2YoaW50KSk7CiAgICBsb2NhbF9DID0gKGludCAqKW1hbGxvYyhucm93c19wZXJfcHJvYyAqIE1BVFJJWF9TSVpFICogc2l6ZW9mKGludCkpOwogICAgQiA9IChpbnQgKiltYWxsb2MoTUFUUklYX1NJWkUgKiBNQVRSSVhfU0laRSAqIHNpemVvZihpbnQpKTsgIC8vIEVhY2ggcHJvY2VzcyBuZWVkcyB0aGUgZW50aXJlIG1hdHJpeCBCCgogICAgLy8gU2NhdHRlciByb3dzIG9mIEEgdG8gZGlmZmVyZW50IHByb2Nlc3NlcwogICAgTVBJX1NjYXR0ZXIoQSwgbnJvd3NfcGVyX3Byb2MgKiBNQVRSSVhfU0laRSwgTVBJX0lOVCwgbG9jYWxfQSwgbnJvd3NfcGVyX3Byb2MgKiBNQVRSSVhfU0laRSwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIC8vIEJyb2FkY2FzdCBtYXRyaXggQiB0byBhbGwgcHJvY2Vzc2VzCiAgICBNUElfQmNhc3QoQiwgTUFUUklYX1NJWkUgKiBNQVRSSVhfU0laRSwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIC8vIFBlcmZvcm0gbG9jYWwgbWF0cml4IG11bHRpcGxpY2F0aW9uCiAgICBmb3IgKGkgPSAwOyBpIDwgbnJvd3NfcGVyX3Byb2M7IGkrKykgewogICAgICAgIGZvciAoaiA9IDA7IGogPCBNQVRSSVhfU0laRTsgaisrKSB7CiAgICAgICAgICAgIGxvY2FsX0NbaSAqIE1BVFJJWF9TSVpFICsgal0gPSAwOwogICAgICAgICAgICBmb3IgKGludCBrID0gMDsgayA8IE1BVFJJWF9TSVpFOyBrKyspIHsKICAgICAgICAgICAgICAgIGxvY2FsX0NbaSAqIE1BVFJJWF9TSVpFICsgal0gKz0gbG9jYWxfQVtpICogTUFUUklYX1NJWkUgKyBrXSAqIEJbayAqIE1BVFJJWF9TSVpFICsgal07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gR2F0aGVyIHRoZSByZXN1bHQgbWF0cml4IEMgZnJvbSBhbGwgcHJvY2Vzc2VzCiAgICBNUElfR2F0aGVyKGxvY2FsX0MsIG5yb3dzX3Blcl9wcm9jICogTUFUUklYX1NJWkUsIE1QSV9JTlQsIEMsIG5yb3dzX3Blcl9wcm9jICogTUFUUklYX1NJWkUsIE1QSV9JTlQsIDAsIE1QSV9DT01NX1dPUkxEKTsKCiAgICAvLyBQcmludCByZXN1bHQgaWYgbmVjZXNzYXJ5CiAgICBpZiAocmFuayA9PSAwKSB7CiAgICAgICAgcHJpbnRmKCJSZXN1bHQgTWF0cml4IEMgKFNob3dpbmcgZmlyc3QgNXg1KTpcbiIpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCA1OyBpKyspIHsKICAgICAgICAgICAgZm9yIChqID0gMDsgaiA8IDU7IGorKykgewogICAgICAgICAgICAgICAgcHJpbnRmKCIlZCAiLCBDW2kgKiBNQVRSSVhfU0laRSArIGpdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludGYoIlxuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8vIENsZWFuIHVwIG1lbW9yeQogICAgaWYgKHJhbmsgPT0gMCkgewogICAgICAgIGZyZWUoQSk7CiAgICAgICAgZnJlZShCKTsKICAgICAgICBmcmVlKEMpOwogICAgfQogICAgZnJlZShsb2NhbF9BKTsKICAgIGZyZWUobG9jYWxfQyk7CgogICAgTVBJX0ZpbmFsaXplKCk7CiAgICByZXR1cm4gMDsKfQoKCgoK