/*
* dotprod.c
* Εσωτερικό γινόμενο δύο διανυσμάτων χρησιμοποιώντας MPI
* Created on: 31 Οκτ 2011
* Author: Kostas Diamantaras
*/
#include "mpi.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
int main(int argc, char **argv) {
int procs, rank;
double x[1000], y[1000];
double local_x[1000], local_y[1000];
int i, n;
int partSize;
FILE *fid;
char *sFileName, defaultName[] = "dotprod.dat";
double local_prod, prod, trueProd;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &procs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank==0) {
if (argc==2) {
/* The filename is the first argument of the program */
sFileName = argv[1];
} else {
/* Default file name */
sFileName = defaultName;
}
printf("Opening file: %s\n", sFileName);
fid = fopen(sFileName,"r");
/* Read vector dimensions */
fscanf(fid, "%d", &n);
printf("Vector dimensions: %d\n", n);
/* Read vector x */
for (i=0; i<n; i++) {
fscanf(fid, "%lf", &(x[i]));
}
/* Read vector y */
for (i=0; i<n; i++) {
fscanf(fid, "%lf", &(y[i]));
}
/* Read true inner product */
fscanf(fid, "%lf", &trueProd);
fclose(fid);
} /* end if rank == 0 */
/* Broadcast n */
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
/* Partition x[] and y[] into "procs"-many parts
* of size ceil(n / procs) each.
*/
partSize = ceil(n / procs);
MPI_Scatter(x, partSize, MPI_DOUBLE, local_x, partSize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
MPI_Scatter(y, partSize, MPI_DOUBLE, local_y, partSize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
/* Partial Inner Product */
local_prod = 0;
for (i=0; i<partSize; i++) {
local_prod += local_x[i] * local_y[i];
}
MPI_Reduce(&local_prod, &prod, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if (rank==0) {
printf("Computed Inner Product\t=\t%.6f\n", prod);
printf("True Inner Product\t=\t%.6f\n", trueProd);
fflush(stdout);
}
MPI_Finalize();
return(0);
}