1
#include <iostream>
#include "mpi.h"
#include <chrono>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
int main(int argc, char* argv[]) {
const int ROOT = 0;
int rank, size, n_rows, n_cols;
double start_time, end_time;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// get file name from command line argument
string filename = argv[1];
ifstream data_file;
if (rank == ROOT) {
data_file.open(filename);
if (!data_file.is_open()) {
cerr << "Failed to open file: " << filename << endl;
exit(1);
}
// read number of rows and columns
data_file >> n_rows >> n_cols;
}
// broadcast number of rows and columns to all processes
MPI_Bcast(&n_rows, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
MPI_Bcast(&n_cols, 1, MPI_INT, ROOT, MPI_COMM_WORLD);
// calculate number of rows for each process
int rows_per_process = n_rows / size;
int remainder = n_rows % size;
if (rank < remainder) {
rows_per_process++;
}
vector<double> row_values(n_cols, 0);
// read data rows and calculate average for each row
MPI_Barrier(MPI_COMM_WORLD);
start_time = MPI_Wtime();
for (int i = 0; i < rows_per_process; i++) {
if (rank == ROOT) {
// read row from file
for (int j = 0; j < n_cols; j++) {
data_file >> row_values[j];
}
}
// broadcast row values to the other processes
MPI_Bcast(row_values.data(), n_cols, MPI_DOUBLE, ROOT, MPI_COMM_WORLD);
// calculate average for each row
double sum = 0;
for (int j = 0; j < n_cols; j++) {
sum += row_values[j];
}
double avg = sum / n_cols;
if (rank == ROOT) {
cout << "Average of row " << i << ": " << avg << endl;
}
}
MPI_Barrier(MPI_COMM_WORLD);
end_time = MPI_Wtime();
// get total time and output to console
double total_time = end_time - start_time;
if (rank == ROOT) {
cout << "Total time: " << total_time << " seconds" << endl;
}
// close file and finalize MPI
if (rank == ROOT) {
data_file.close();
}
MPI_Finalize();
return 0;
}
mpicxx -o average.exe average.cpp
mpirun -np <number of processes> ./average.exe <filename>