Bu Blogda Ara

7 Şubat 2010 Pazar

Computes a parallel dot product. Uses MPI_Allreduce.

/* parallel_dot1.c -- Computes a parallel dot product. Uses MPI_Allreduce.
*
* Input:
* n: order of vectors
* x, y: the vectors
*
* Output:
* the dot product of x and y as computed by each process.
*
* Note: Arrays containing vectors are statically allocated. Assumes that
* n, the global order of the vectors, is evenly divisible by p, the
* number of processes.
*
* See Chap 5, pp. 76 & ff in PPMPI.
*/
#include
#include "mpi.h"

#define MAX_LOCAL_ORDER 100

main(int argc, char* argv[]) {
float local_x[MAX_LOCAL_ORDER];
float local_y[MAX_LOCAL_ORDER];
int n;
int n_bar; /* = n/p */
float dot;
int p;
int my_rank;

void Read_vector(char* prompt, float local_v[], int n_bar, int p,
int my_rank);
float Parallel_dot(float local_x[], float local_y[], int n_bar);
void Print_results(float dot, int my_rank, int p);

MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

if (my_rank == 0) {
printf("Enter the order of the vectors\n");
scanf("%d", &n);
}
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
n_bar = n/p;

Read_vector("the first vector", local_x, n_bar, p, my_rank);
Read_vector("the second vector", local_y, n_bar, p, my_rank);

dot = Parallel_dot(local_x, local_y, n_bar);

Print_results(dot, my_rank, p);

MPI_Finalize();
} /* main */


/*****************************************************************/
void Read_vector(
char* prompt /* in */,
float local_v[] /* out */,
int n_bar /* in */,
int p /* in */,
int my_rank /* in */) {
int i, q;
float temp[MAX_LOCAL_ORDER];
MPI_Status status;

if (my_rank == 0) {
printf("Enter %s\n", prompt);
for (i = 0; i < n_bar; i++)
scanf("%f", &local_v[i]);
for (q = 1; q < p; q++) {
for (i = 0; i < n_bar; i++)
scanf("%f", &temp[i]);
MPI_Send(temp, n_bar, MPI_FLOAT, q, 0, MPI_COMM_WORLD);
}
} else {
MPI_Recv(local_v, n_bar, MPI_FLOAT, 0, 0, MPI_COMM_WORLD,
&status);
}
} /* Read_vector */


/*****************************************************************/
float Serial_dot(
float x[] /* in */,
float y[] /* in */,
int n /* in */) {

int i;
float sum = 0.0;

for (i = 0; i < n; i++)
sum = sum + x[i]*y[i];
return sum;
} /* Serial_dot */


/*****************************************************************/
float Parallel_dot(
float local_x[] /* in */,
float local_y[] /* in */,
int n_bar /* in */) {

float local_dot;
float dot = 0.0;
float Serial_dot(float x[], float y[], int m);

local_dot = Serial_dot(local_x, local_y, n_bar);
MPI_Allreduce(&local_dot, &dot, 1, MPI_FLOAT,
MPI_SUM, MPI_COMM_WORLD);
return dot;
} /* Parallel_dot */


/*****************************************************************/
void Print_results(
float dot /* in */,
int my_rank /* in */,
int p /* in */) {
int q;
float temp;
MPI_Status status;

if (my_rank == 0) {
printf("dot = \n");
printf("Process 0 > %f\n", dot);
for (q = 1; q < p; q++) {
MPI_Recv(&temp, 1, MPI_FLOAT, q, 0, MPI_COMM_WORLD,
&status);
printf("Process %d > %f\n", q, temp);
}
} else {
MPI_Send(&dot, 1, MPI_FLOAT, 0, 0, MPI_COMM_WORLD);
}

} /* Print_results */

Hiç yorum yok:

Yorum Gönder