2015-05-05 3 views
-1

Я довольно новичок в MPI, поэтому я пытался сделать метод вычисления 0 в 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 , вот мой код: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, он должен иметь точно такой же результат, но результат действительно меняется. Кроме того, некоторые данные, присланные работнику, равны 0, что приводит к ошибке вычисления.

Если вы заметили ошибку, пожалуйста, укажите ее. Заранее спасибо :)

+3

Если вам нужна помощь в поиске ошибки, вам нужно на самом деле описать проблему, показать нам, что о выходе неверно, описать, что вы ожидаете, и т. Д. Вы можете смело предположить, что остальной мир не знает, что расстояние Хаверсина от верхней части головы. –

+1

В качестве отправной точки вы можете посмотреть, что «MPI_Bcast» и «MPI_Gather» распространяют и извлекают данные от ваших сотрудников. –

ответ

0

Проблема приходит от:

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); 

если rows==4 первого вызова MPI_Send() отправит destination[offset][0],destination[offset][1],destination[offset+1][0],destination[offset+1][1], так как эти элементы соответствуют массиву 1D, который будет отправлен. Второй звонок MPI_Send посылает destination[offset][1],destination[offset+1][0],destination[offset+1][1],destination[offset+2][0]. Это значит, что destination[offset+3][1] никогда не отправляется!

кажется, что вы хотите выполнить:

MPI_Send(&destination[offset][0], 2*rows, MPI_DOUBLE, dest, mtype, MPI_COMM_WORLD); 

Эта операция будет выполнять обе строки сразу: вторая операция должна быть прокомментированы. Приемной операция должна быть изменена, а также:

MPI_Recv(&destination[offset][0],2*rows, MPI_DOUBLE, MASTER, mtype, MPI_COMM_WORLD, &status); 

Посмотрите на функции MPI_Scatterv(): это именно то, что вы хотите сделать. Посмотрите на MPI_Bcast() и MPI_Gatherv()

Смежные вопросы