2017-01-10 29 views
0

プログラミング初心者向け。私は行列の乗算を書こうとしていました。 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