我很新的MPI,所以我試圖做Haversine distance在C中的計算方法,到目前爲止它似乎工作,但我注意到結果是不正確的,也許錯誤,我用MPI方法,這裏是我的代碼:MPI Haversine在C中的距離計算
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define ROW 10 /* number of rows in matrix */
#define COLUMN 2 /* number of columns in matrix */
#define R 6371 /* averange radius of Earth */
#define MASTER 0 /* taskid of first task */
#define FROM_MASTER 1 /* setting a message type */
#define FROM_WORKER 2 /* setting a message type */
int main(int argc, char *argv[])
{
int numtasks, /* number of tasks in partition */
taskid, /* a task identifier */
numworkers, /* number of worker tasks */
source, /* task id of message source */
dest, /* task id of message destination */
mtype, /* message type */
rows, /* rows of matrix A sent to each worker */
averow, extra, offset, /* used to determine rows sent to each worker */
i, j, rc; /* misc */
double target[1][COLUMN], /* longitude and latitude of target */
dlat, dlon, /* longitude and latitude of destination */
a, c, d, /* variable for calculation */
destination[ROW][COLUMN], /* matrix dest for listed destination */
result[ROW]; /* result in matrix */
const char *name[ROW]; /* name of destination */
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &taskid);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
if (numtasks < 2) {
printf("Memerlukan minimal dua MPI tasks. Membatalkan...\n");
MPI_Abort(MPI_COMM_WORLD, rc);
exit(1);
}
numworkers = numtasks - 1;
/**************************** master task ************************************/
if (taskid == MASTER)
{
printf("MPI dengan %d tasks.\n", numtasks);
printf("Memulai...\n");
target[0][0] = -6.9167;
target[0][1] = 107.6000;
destination[0][0] = -6.1745;
destination[0][1] = 106.8227;
name[0] = "Jakarta";
destination[1][0] = -6.9167;
destination[1][1] = 107.6000;
name[1] = "Bandung";
destination[2][0] = -7.8014;
destination[2][1] = 110.3644;
name[2] = "Jogja";
destination[3][0] = -7.2653;
destination[3][1] = 112.7425;
name[3] = "Surabaya";
destination[4][0] = -5.5500;
destination[4][1] = 95.3167;
name[4] = "Aceh";
destination[5][0] = 3.5833;
destination[5][1] = 98.6667;
name[5] = "Medan";
destination[6][0] = -5.1333;
destination[6][1] = 119.4167;
name[6] = "Makassar";
destination[7][0] = -0.9500;
destination[7][1] = 100.3531;
name[7] = "Padang";
destination[8][0] = -8.6500;
destination[8][1] = 115.2167;
name[8] = "Denpasar";
destination[9][0] = -0.8667;
destination[9][1] = 134.0833;
name[9] = "Irian Jaya";
/* Send matrix data to the worker tasks */
averow = ROW/numworkers;
extra = ROW%numworkers;
offset = 0;
mtype = FROM_MASTER;
for (dest = 1; dest <= numworkers; dest++)
{
rows = (dest <= extra) ? averow + 1 : averow;
MPI_Send(&offset, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
MPI_Send(&rows, 1, MPI_INT, dest, mtype, MPI_COMM_WORLD);
MPI_Send(&target[0][0], 1, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
MPI_Send(&target[0][1], 1, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
MPI_Send(&destination[offset][0], rows, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
MPI_Send(&destination[offset][1], rows, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD);
offset = offset + rows;
}
/* Receive results from worker tasks */
mtype = FROM_WORKER;
for (i = 1; i <= numworkers; i++)
{
source = i;
MPI_Recv(&offset, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&rows, 1, MPI_INT, source, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&result[offset], rows, MPI_DOUBLE, source, mtype, MPI_COMM_WORLD, &status);
}
/* Print results */
printf("******************************************************\n");
printf("Hasil:\n");
for (i = 0; i<ROW; i++)
{
printf("Jarak ke %s: ", name[i]);
printf("%f", result[i]);
printf(" km\n");
}
printf("\n******************************************************\n");
printf("Selesai.\n");
}
/**************************** worker task ************************************/
if (taskid > MASTER)
{
mtype = FROM_MASTER;
MPI_Recv(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&target[0][0], 1, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&target[0][1], 1, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&destination[offset][0], rows, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status);
MPI_Recv(&destination[offset][1], rows, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status);
for (j = offset; j<offset + rows; j++)
{
dlon = destination[j][1] - target[0][1];
/* printf("dlon ke %i : %f \n", j, dlon); */
dlat = destination[j][0] - target[0][0];
/* printf("dlat ke %i : %f \n", j, dlat); */
a = pow((sin(dlat/2)), 2) + (cos(target[0][0]) * cos(destination[j][0]) * pow((sin(dlon/2)), 2));
/* printf("a ke %i : %f \n", j, a); */
c = 2 * atan2(sqrt(a), sqrt(1 - a));
/* printf("c ke %i : %f \n", j, c); */
d = R * c;
/* printf("d ke %i : %f \n", j, d); */
result[j] = d;
}
mtype = FROM_WORKER;
MPI_Send(&offset, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
MPI_Send(&rows, 1, MPI_INT, MASTER, mtype, MPI_COMM_WORLD);
MPI_Send(&result[offset], rows, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD);
}
MPI_Finalize();
}
此代碼應顯示各地方的距離,因爲它是MPI,它應該有完全相同的結果,但結果卻改變。 此外,發送給worker的一些數據等於0,這會導致計算錯誤。
如果您發現一些錯誤,請指出。 感謝提前:)
如果你想找到一個bug的幫助,你需要真正描述問題,告訴我們輸出是錯誤的,描述你期望的等等。你可以放心地假設世界其他地方不知道什麼Haversine距離我們的頭頂。 –
但是,作爲一個起點,您可以查看'MPI_Bcast'和'MPI_Gather'確實分發並檢索您的工作人員的數據。 –