m = (N + myid) / (np -1)とすることで、うまく各ノードにデータを配布している。
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include "mpi.h"
#define N 1000
int main(int argc, char **argv){
int myid, np;
double *x, *y, *z;
double *parx, *pary, *parz; // each PEs data
double wtime, timer;
MPI_Status st;
int i, j, k, m, offset;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &np);
/* Data Initialize */
if(myid == 0){
x = (double *)malloc(sizeof(double) * N);
y = (double *)malloc(sizeof(double) * N);
z = (double *)malloc(sizeof(double) * N);
for(i = 0; i < N; i++)
x[i] = y[i] = 0.00001 * i;
}
/* timer start */
MPI_Barrier(MPI_COMM_WORLD);
if(myid == 0){
wtime = MPI_Wtime();
}
/* Calc datasize of each PEs by itself */
m = (N + myid) / (np -1);
parx = (double *)malloc(sizeof(double) * m);
pary = (double *)malloc(sizeof(double) * m);
parz = (double *)malloc(sizeof(double) * m);
/* send data from PE0 to each PEs */
if(myid == 0){
/* selfcopy PE0 to PE0 */
memcpy(parx, x, sizeof(double) * m);
memcpy(pary, y, sizeof(double) * m);
offset = 0;
for(j = 1; j < np; j++){
/* PE0 calcs other PEs datasizes */
k = (N + j) / (np - 1);
MPI_Send(&x[offset], k, MPI_DOUBLE, j, 1000, MPI_COMM_WORLD);
MPI_Send(&y[offset], k, MPI_DOUBLE, j, 2000, MPI_COMM_WORLD);
offset = offset + k;
}
/*
for(i = 0; i < m; i++){
z[i] = sqrt(parx[i] * parx[i] + pary[i] * pary[i]);
}
*/
offset = 0;
for(j = 1; j < np; j++){
k = (N + j) / (np - 1);
MPI_Recv(&z[offset], k, MPI_DOUBLE, j, 3000, MPI_COMM_WORLD, &st);
offset = offset + k;
}
}
else{
/* Each PE knows itself datasize at m */
MPI_Recv(parx, m, MPI_DOUBLE, 0, 1000, MPI_COMM_WORLD, &st);
MPI_Recv(pary, m, MPI_DOUBLE, 0, 2000, MPI_COMM_WORLD, &st);
/* calculate norm */
for(i = 0;i < m;i++){
parz[i] = sqrt(parx[i] * parx[i] + pary[i] * pary[i]);
}
MPI_Send(parz, m, MPI_DOUBLE, 0, 3000, MPI_COMM_WORLD);
}
/* for debug */
/*
for(i = 0; i < np; i++){
if(myid == i){
for(k = 0; k < m; k++)
printf("%d: (x, y) = (%10.9f, %10.9f)\n", myid, parx[k], pary[k]);
fflush(stdout);
}
}
*/
if(myid == 0){
timer = MPI_Wtime() - wtime;
/*
for(i=0;i<N;i++){
printf("norm:%d = %f\n",i,z[i]);
fflush(stdout);
}
*/
printf("time:%f\n",timer);
}
MPI_Finalize();
}