#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MATRIX_SIZE 100
#define VECTOR_SIZE 100
int main(int argc, char** argv) {
int rank, size;
int matrix[MATRIX_SIZE][MATRIX_SIZE];
int vector[VECTOR_SIZE];
int local_matrix[MATRIX_SIZE / size][MATRIX_SIZE];
int local_vector[VECTOR_SIZE / size];
int local_result[MATRIX_SIZE / size];
int result[MATRIX_SIZE];
// Initialize MPI
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Generate matrix and vector
if (rank == 0) {
for (int i = 0; i < MATRIX_SIZE; i++) {
for (int j = 0; j < MATRIX_SIZE; j++) {
matrix
[i
][j
] = rand() % 100; }
}
for (int i = 0; i < VECTOR_SIZE; i++) {
vector
[i
] = rand() % 100; }
}
// Scatter matrix and vector
MPI_Scatter(matrix, MATRIX_SIZE * MATRIX_SIZE / size, MPI_INT, local_matrix,
MATRIX_SIZE * MATRIX_SIZE / size, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Scatter(vector, VECTOR_SIZE / size, MPI_INT, local_vector,
VECTOR_SIZE / size, MPI_INT, 0, MPI_COMM_WORLD);
// Perform local matrix-vector multiplication
for (int i = 0; i < MATRIX_SIZE / size; i++) {
local_result[i] = 0;
for (int j = 0; j < MATRIX_SIZE; j++) {
local_result[i] += local_matrix[i][j] * local_vector[j];
}
}
// Gather local results to obtain final result
MPI_Gather(local_result, MATRIX_SIZE / size, MPI_INT, result,
MATRIX_SIZE / size, MPI_INT, 0, MPI_COMM_WORLD);
// Print result
if (rank == 0) {
for (int i = 0; i < MATRIX_SIZE; i++) {
for (int j = 0; j < MATRIX_SIZE; j++) {
}
}
for (int i = 0; i < VECTOR_SIZE; i++) {
}
for (int i = 0; i < MATRIX_SIZE; i++) {
}
}
// Finalize MPI
MPI_Finalize();
return 0;
}
I2luY2x1ZGUgPG1waS5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dGltZS5oPgoKI2RlZmluZSBNQVRSSVhfU0laRSAxMDAKI2RlZmluZSBWRUNUT1JfU0laRSAxMDAKCmludCBtYWluKGludCBhcmdjLCBjaGFyKiogYXJndikgewogICAgaW50IHJhbmssIHNpemU7CiAgICBpbnQgbWF0cml4W01BVFJJWF9TSVpFXVtNQVRSSVhfU0laRV07CiAgICBpbnQgdmVjdG9yW1ZFQ1RPUl9TSVpFXTsKICAgIGludCBsb2NhbF9tYXRyaXhbTUFUUklYX1NJWkUgLyBzaXplXVtNQVRSSVhfU0laRV07CiAgICBpbnQgbG9jYWxfdmVjdG9yW1ZFQ1RPUl9TSVpFIC8gc2l6ZV07CiAgICBpbnQgbG9jYWxfcmVzdWx0W01BVFJJWF9TSVpFIC8gc2l6ZV07CiAgICBpbnQgcmVzdWx0W01BVFJJWF9TSVpFXTsKCiAgICAvLyBJbml0aWFsaXplIE1QSQogICAgTVBJX0luaXQoJmFyZ2MsICZhcmd2KTsKICAgIE1QSV9Db21tX3JhbmsoTVBJX0NPTU1fV09STEQsICZyYW5rKTsKICAgIE1QSV9Db21tX3NpemUoTVBJX0NPTU1fV09STEQsICZzaXplKTsKCiAgICAvLyBHZW5lcmF0ZSBtYXRyaXggYW5kIHZlY3RvcgogICAgaWYgKHJhbmsgPT0gMCkgewogICAgICAgIHNyYW5kKHRpbWUoTlVMTCkpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTUFUUklYX1NJWkU7IGkrKykgewogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IE1BVFJJWF9TSVpFOyBqKyspIHsKICAgICAgICAgICAgICAgIG1hdHJpeFtpXVtqXSA9IHJhbmQoKSAlIDEwMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IFZFQ1RPUl9TSVpFOyBpKyspIHsKICAgICAgICAgICAgdmVjdG9yW2ldID0gcmFuZCgpICUgMTAwOwogICAgICAgIH0KICAgIH0KCiAgICAvLyBTY2F0dGVyIG1hdHJpeCBhbmQgdmVjdG9yCiAgICBNUElfU2NhdHRlcihtYXRyaXgsIE1BVFJJWF9TSVpFICogTUFUUklYX1NJWkUgLyBzaXplLCBNUElfSU5ULCBsb2NhbF9tYXRyaXgsCiAgICAgICAgICAgICAgICBNQVRSSVhfU0laRSAqIE1BVFJJWF9TSVpFIC8gc2l6ZSwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwogICAgTVBJX1NjYXR0ZXIodmVjdG9yLCBWRUNUT1JfU0laRSAvIHNpemUsIE1QSV9JTlQsIGxvY2FsX3ZlY3RvciwKICAgICAgICAgICAgICAgIFZFQ1RPUl9TSVpFIC8gc2l6ZSwgTVBJX0lOVCwgMCwgTVBJX0NPTU1fV09STEQpOwoKICAgIC8vIFBlcmZvcm0gbG9jYWwgbWF0cml4LXZlY3RvciBtdWx0aXBsaWNhdGlvbgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNQVRSSVhfU0laRSAvIHNpemU7IGkrKykgewogICAgICAgIGxvY2FsX3Jlc3VsdFtpXSA9IDA7CiAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBNQVRSSVhfU0laRTsgaisrKSB7CiAgICAgICAgICAgIGxvY2FsX3Jlc3VsdFtpXSArPSBsb2NhbF9tYXRyaXhbaV1bal0gKiBsb2NhbF92ZWN0b3Jbal07CiAgICAgICAgfQogICAgfQoKICAgIC8vIEdhdGhlciBsb2NhbCByZXN1bHRzIHRvIG9idGFpbiBmaW5hbCByZXN1bHQKICAgIE1QSV9HYXRoZXIobG9jYWxfcmVzdWx0LCBNQVRSSVhfU0laRSAvIHNpemUsIE1QSV9JTlQsIHJlc3VsdCwKICAgICAgICAgICAgICAgTUFUUklYX1NJWkUgLyBzaXplLCBNUElfSU5ULCAwLCBNUElfQ09NTV9XT1JMRCk7CgogICAgLy8gUHJpbnQgcmVzdWx0CiAgICBpZiAocmFuayA9PSAwKSB7CiAgICAgICAgcHJpbnRmKCJNYXRyaXg6XG4iKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE1BVFJJWF9TSVpFOyBpKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBNQVRSSVhfU0laRTsgaisrKSB7CiAgICAgICAgICAgICAgICBwcmludGYoIiVkICIsIG1hdHJpeFtpXVtqXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgICAgIH0KICAgICAgICBwcmludGYoIlZlY3RvcjpcbiIpOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgVkVDVE9SX1NJWkU7IGkrKykgewogICAgICAgICAgICBwcmludGYoIiVkICIsIHZlY3RvcltpXSk7CiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG5SZXN1bHQ6XG4iKTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IE1BVFJJWF9TSVpFOyBpKyspIHsKICAgICAgICAgICAgcHJpbnRmKCIlZCAiLCByZXN1bHRbaV0pOwogICAgICAgIH0KICAgICAgICBwcmludGYoIlxuIik7CiAgICB9CgogICAgLy8gRmluYWxpemUgTVBJCiAgICBNUElfRmluYWxpemUoKTsKCiAgICByZXR1cm4gMDsKfQoK