2016-03-30 7 views
0
#include<stdio.h> 
#include<mpi.h> 

int main() 
{ 
     int a_r = 0, a_c = 0, v_s = 0, i = 0, rank = 0, size = 0; 
     int local_row = 0, partial_sum = 0, sum = 0, j = 0; 
     int my_first_ele = 0, my_last_ele = 0; 
     int a[10][10], v[10], partial_mul[10] = {0}, mul[10] = {0}; 

     MPI_Init(NULL, NULL); 
     MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
     MPI_Comm_size(MPI_COMM_WORLD, &size); 

     if(rank == 0) 
     { 
       printf("Enter the row of array A: "); 
       scanf("%d", &a_r); 
       printf("Enter the column of array A: "); 
       scanf("%d", &a_c); 
       printf("Enter the array A: "); 

       for(i = 0; i < a_r; i++) 
       { 
         for(j = 0; j < a_c; j++) 
           scanf("%d", &a[i][j]); 
       } 

       printf("Enter the size of vector array: "); 
       scanf("%d", &v_s); 
       printf("Enter the vector array: "); 
       for(i = 0; i < v_s; i++) 
       { 
         scanf("%d", &v[i]); 
       } 

       MPI_Bcast(&a_r, 1, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(&a_c, 1, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(&v_s, 1, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(a, a_r*a_c, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(v, v_s, MPI_INT, 0, MPI_COMM_WORLD); 

       local_row = a_r/size; 
       my_first_ele = rank * local_row; 
       my_last_ele = (rank+1) * local_row; 

       if(a_c == v_s) 
       {  
         for(i = my_first_ele; i < my_last_ele; i++) 
         { 
           for(j = 0; j < a_c; j++) 
           { 
             partial_mul[i] = partial_mul[i] + (a[i][j]*v[j]); 
           } 
         } 
         printf("\nPartial multiplication in Rank 0: \n"); 
         for(i = my_first_ele; i < my_last_ele; i++) 
           printf("%d \n", partial_mul[i]); 

         MPI_Gather(partial_mul, local_row, MPI_INT, mul, local_row, MPI_INT, 0, MPI_COMM_WORLD); 

         printf("\n \nGlobal Multiplication: \n"); 
         for(i = 0; i < a_r; i++) 
         { 
           printf("%d \n", mul[i]); 
         } 
       } 
       else 
         printf("\nCan't multiply. \n"); 
     } 

     else 
     { 
       MPI_Bcast(&a_r, 1, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(&a_c, 1, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(&v_s, 1, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(a, a_r*a_c, MPI_INT, 0, MPI_COMM_WORLD); 
       MPI_Bcast(v, v_s, MPI_INT, 0, MPI_COMM_WORLD); 

       local_row = a_r/size; 
       my_first_ele = rank * local_row; 
       my_last_ele = (rank+1) * local_row; 
       if(a_c == v_s) 
       {  
         for(i = my_first_ele; i < my_last_ele; i++) 
         { 
           for(j = 0; j < a_c; j++) 
           { 
             partial_mul[i] = partial_mul[i] + (a[i][j]*v[j]); 
           } 
         } 
         printf("\nPartial multiplication in Rank %d: \n", rank); 
         for(i = my_first_ele; i < my_last_ele; i++) 
           printf("%d \n", partial_mul[i]); 

         MPI_Gather(partial_mul, local_row, MPI_INT, mul, local_row, MPI_INT, 0, MPI_COMM_WORLD); 

       } 
       else 
         printf("\nCan't multiply. \n"); 
     } 
     MPI_FINALIZE(); 
} 

У меня проблема с кодом выше. Значение моего частичного умножения верное. Но в моем общем умножении я могу собрать только элементы ранга 0, остальные значения печатаются как 0. В чем проблема, которую можно объяснить.MPI Векторное умножение

ответ

0

Глядя на ваш макет данных, я думаю, что вы неправильно понимаете структуры данных в MPI: все данные хранятся отдельно в каждом ранге, нет совместного использования или распространения импликации. Ваш вектор partial_sum является отдельным для каждого ранга, каждый из которых содержит 10 элементов. Так предполагая size=2, a_r=10 и нулевой инициализацию, после вычисления содержимое будет выглядеть следующим образом:

  • Оценка 0: {x0,x1,x2,x3,x4,0,0,0,0,0}
  • ранг 1: {0,0,0,0,0,x5,x6,x7,x8,x9}

где х является правильным вычисленным значением. Соберите, затем соберете первые local_row=5 элементов из каждого ранга, в результате получится {x0,x1,x2,x3,x4,0,0,0,0,0}.

Вы могли просто исправить это, добавив правильное смещение:

MPI_Gather(&partial_mul[my_first_ele], local_row, MPI_INT, mul, local_row, MPI_INT, 0, MPI_COMM_WORLD); 

Но, пожалуйста, не делайте этого. Вместо этого вы должны пересмотреть свои структуры данных, чтобы действительно распределить данные, зарезервировать правильные размеры для каждой части вектора/массива. Чтобы отправить часть данных в каждый ранг, используйте MPI_Scatter (напротив MPI_Gather). Самое сложное - получить матрицу правильно. Это подробно объясняется this excellent answer.

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