2017-01-10 2 views
0

초보자 용 mpi 프로그래밍입니다. 행렬 곱셈을 쓰려고했습니다. scatter 및 gather 루틴을 사용하여 행렬 곱셈에 관한 게시물 MPI Matrix Multiplication with scatter gather을 보았습니다. 내가Mpi_Scatter 및 Mpi_Gather를 사용한 행렬 곱셈

나는 다음과 같은 잘못된 출력을 얻고있다 위의 프로그램에 대한
$mpirun -np 4 ./a.out 

으로 위의 프로그램 실행

#define N 4 
#include <stdio.h> 
#include <math.h> 
#include <sys/time.h> 
#include <stdlib.h> 
#include <stddef.h> 
#include "mpi.h" 


void print_results(char *prompt, int a[N][N]); 

int main(int argc, char *argv[]) 
{ 
    int i, j, k, rank, size, tag = 99, blksz, sum = 0; 
    int a[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}}; 
    int b[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}}; 
    int c[N][N]; 
    int aa[N],cc[N]; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    //scatter rows of first matrix to different processes  
    MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD); 

    //broadcast second matrix to all processes 
    MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD); 

    MPI_Barrier(MPI_COMM_WORLD); 

      //perform vector multiplication by all processes 
      for (i = 0; i < N; i++) 
      { 
        for (j = 0; j < N; j++) 
        { 
          sum = sum + aa[j] * b[i][j];     
        } 
        cc[i] = sum; 
        sum = 0; 
      } 

    MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD); 

    MPI_Barrier(MPI_COMM_WORLD);   
    MPI_Finalize(); 
    print_results("C = ", c); 
} 

void print_results(char *prompt, int a[N][N]) 
{ 
    int i, j; 

    printf ("\n\n%s\n", prompt); 
    for (i = 0; i < N; i++) { 
      for (j = 0; j < N; j++) { 
        printf(" %d", a[i][j]); 
      } 
      printf ("\n"); 
    } 
    printf ("\n\n"); 
} 

나는 다음과 같이 위의 포스트에서 사용할 수있는 코드를 수정 시도 ... ..

C = 
0 0 -562242168 32766 
1 0 4197933 0 
-562242176 32766 0 0 
4197856 0 4196672 0 

C = 
0 0 -1064802792 32765 
1 0 4197933 0 
-1064802800 32765 0 0 
4197856 0 4196672 0 

C = 
30 70 29 60 
70 174 89 148 
29 89 95 74 
60 148 74 126 

C = 
0 0 -1845552920 32765 
1 0 4197933 0 
-1845552928 32765 0 0 
4197856 0 4196672 0 

다음 쿼리가 있습니다 1. 결과 행렬 C가 모든 프로세스에서 인쇄되는 이유. 주 처리만으로 인쇄되는 것은 입니다. 2. 잘못된 결과가 인쇄되는 이유는 무엇입니까?

수정 사항과 관련하여 도움을 받으실 수 있습니다.

답변

5

모든 프로세스가 void print_results(char *prompt, int a[N][N]) 함수를 실행하기 때문에 결과 행렬 c이 모든 프로세스에서 인쇄됩니다. 순위 0의 프로세스에서 수집 중이므로 print_results(...) 함수를 호출하기 전에 문 if (rank == 0)을 추가하십시오. 이것은해야

   for (j = 0; j < N; j++) 
       { 
         sum = sum + aa[j] * b[i][j];     
       } 

:

   for (j = 0; j < N; j++) 
       { 
         sum = sum + aa[j] * b[j][i];     
       } 

또한 그것의 사본을 이미 이미 모든 프로세스로 b을 방송 할 필요가 없습니다 또한, 결과 때문에에 잘못된 루프 로직의 잘못 MPI_Barrier()을 피할 수 있습니다. 전체 프로그램은된다 : 다음

#define N 4 
#include <stdio.h> 
#include <math.h> 
#include <sys/time.h> 
#include <stdlib.h> 
#include <stddef.h> 
#include "mpi.h" 


void print_results(char *prompt, int a[N][N]); 

int main(int argc, char *argv[]) 
{ 
    int i, j, k, rank, size, tag = 99, blksz, sum = 0; 
    int a[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}}; 
    int b[N][N]={{1,2,3,4},{5,6,7,8},{9,1,2,3},{4,5,6,7,}}; 
    int c[N][N]; 
    int aa[N],cc[N]; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    //scatter rows of first matrix to different processes  
    MPI_Scatter(a, N*N/size, MPI_INT, aa, N*N/size, MPI_INT,0,MPI_COMM_WORLD); 

    //broadcast second matrix to all processes 
    MPI_Bcast(b, N*N, MPI_INT, 0, MPI_COMM_WORLD); 

    MPI_Barrier(MPI_COMM_WORLD); 

      //perform vector multiplication by all processes 
      for (i = 0; i < N; i++) 
      { 
        for (j = 0; j < N; j++) 
        { 
          sum = sum + aa[j] * b[j][i]; //MISTAKE_WAS_HERE    
        } 
        cc[i] = sum; 
        sum = 0; 
      } 

    MPI_Gather(cc, N*N/size, MPI_INT, c, N*N/size, MPI_INT, 0, MPI_COMM_WORLD); 

    MPI_Barrier(MPI_COMM_WORLD);   
    MPI_Finalize(); 
    if (rank == 0)       //I_ADDED_THIS 
     print_results("C = ", c); 
} 

void print_results(char *prompt, int a[N][N]) 
{ 
    int i, j; 

    printf ("\n\n%s\n", prompt); 
    for (i = 0; i < N; i++) { 
      for (j = 0; j < N; j++) { 
        printf(" %d", a[i][j]); 
      } 
      printf ("\n"); 
    } 
    printf ("\n\n"); 
} 

c =

C = 
54 37 47 57 

130 93 119 145 

44 41 56 71 

111 79 101 123