The Last Program
Parallel Vector Normalization with MPI
#include <mpi.h>
#include "supercomputing_simplified.hpp"
#include "ScS_functions.cpp"
int main (int argc,char *argv[])
{
int P_rank, worldsize, rootfordata=-99, i, myturn;
const int d_size=13;
int data_array[d_size];
float bigtot=0.0, sqsubtot=0.0, checklength=0.0;
float eulength[]={0.0}, data_arrayf[d_size], tempfileforworkf[d_size];
for (i = 0; i < d_size; i++){ tempfileforworkf[i] = 0.0;}
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD, &P_rank);
MPI_Comm_size(MPI_COMM_WORLD, &worldsize);
for (i = 0; i < d_size; i++)
{data_array[i] = i+10*P_rank;data_arrayf[i]=(float)data_array[i];}
ourmpi_printf(data_array, d_size, P_rank,worldsize,"Process
%i's data: ");
rootfordata = keyb_entry_nonneg_int(P_rank,worldsize,"\nChoose
data from a single Process");
MPI_Bcast(&rootfordata,1,MPI_INT,0,MPI_COMM_WORLD);
//....................partition and scatter
int* blocklengths= new int[worldsize];
int* blockoffsets= new int[worldsize];
scv_partition(worldsize, d_size,blocklengths,blockoffsets);
int rcv_count=blocklengths[P_rank];
MPI_Scatterv(data_arrayf, blocklengths, blockoffsets,
MPI_FLOAT, tempfileforworkf,rcv_count,
MPI_FLOAT, rootfordata,MPI_COMM_WORLD);
//..................local sum of squares
sqsubtot=innerprod(tempfileforworkf,tempfileforworkf,blocklengths[P_rank]);
// option to print local sum of squares
ourmpi_printf(&sqsubtot,1,P_rank,worldsize,
"Sum of squares at Process %d: ");
MPI_Barrier(MPI_COMM_WORLD);
//............gather subtotals and extract
square root of total........
int* rcv_singletons= new int[worldsize];
for (i=0;i<worldsize;i++) {rcv_singletons[i]=1; }
int* rcv_offsets = new int[worldsize];
for (i=0;i<worldsize;i++) {rcv_offsets[i]=i;}
float* subtot = new float[worldsize];
for (i = 0; i < worldsize; i++){
subtot[i] = 0.0; }
MPI_Gatherv(&sqsubtot, 1, MPI_FLOAT,
subtot, rcv_singletons, rcv_offsets,
MPI_FLOAT, 0, MPI_COMM_WORLD);
delete [] rcv_singletons;
delete [] rcv_offsets;
if (P_rank==0)
{
for (i=0;i<worldsize;i++){bigtot = bigtot + subtot[i];}
eulength[0]=sqrt(bigtot);
printf("\nTotal sum of squares %d\n",(int) bigtot);
printf("Euclidean
length of Process %d's data_array %f \n\n",//
rootfordata,eulength[0]);
}
delete []subtot;
//....broadcast euclidean length and
normalize scattered elements....
MPI_Bcast(eulength, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);
for (i=0;i<blocklengths[P_rank];i++ )
{tempfileforworkf[i] = tempfileforworkf[i]/eulength[0];}
//the
printing below is from zero
//...........gather normalized elements and
concatenate...........
MPI_Gatherv(tempfileforworkf, rcv_count, MPI_FLOAT,
data_arrayf, blocklengths, blockoffsets,
MPI_FLOAT, 0, MPI_COMM_WORLD);
delete []blocklengths;
delete []blockoffsets;
checklength=innerprod(data_arrayf, data_arrayf, d_size);
printf_oneP_nobarrier(0, P_rank, data_arrayf, d_size, "Process %d's normalized array:\n", rootfordata);
if (P_rank==0)
{
printf("\n normalized array length check (is it
1?); uses innerprod(): \n %f\n",
checklength);
}
MPI_Finalize();
return 0;
}