2017-05-30 21 views
-1

大学では、並列プログラミングのための実験室を求められました。行列の乗算を並列化しました。私は例に似たアルゴリズムを書いたが、実装はブレークポイントを提供する。私に教えてください。どうしたらいいですか?行列の乗算MPI

#define _CRT_SECURE_NO_WARNINGS 
#include <cstdlib> 
#include <iostream> 
#include <math.h> 
#include "mpi.h" 
#include <stdio.h> 
const int N=4; 
int main(int argc, char *argv[]) { 
    int r,q,myid,numprocs; 
    int i0; 
    int *b,*c,*loc_a,*loc_c; 
    MPI_Init(&argc,&argv); 
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs); 
    MPI_Comm_rank(MPI_COMM_WORLD,&myid); 
    MPI_Status status; 
    q=N/numprocs; 
    b=new int [N*N]; 
    c=new int [N*N]; 
    loc_c=new int[N*N]; 
    loc_a=new int[q]; 
    for(int i=0;i<N*N;i++)  { 
     c[i]=0;  loc_c[i]=0;  
    }  
    if(myid==0)  { 
     for (int j = 0; j<numprocs; j++) { 
      for (r = 0; r<q*N; r++) { 
       loc_a[r] = 1; 
      }   
      MPI_Send(&loc_a[0], q*N, MPI_INT, j, 0, MPI_COMM_WORLD); 
     }  
     for (int i = 0; i<N*N; i++) { 
      b[i] = 1; 
     }   
    }  
    MPI_Recv(&loc_a[0], q*N, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); 
    for (r = 0; r<N; r++) { 
     MPI_Bcast(&b[r*N], N, MPI_INT, 0, MPI_COMM_WORLD); 
     i0 = myid*q; 
     for (int i = 0; i<q; i++) { 
      for (int j = 0; j<N; j++) { 
       loc_c[r*N + i0] += loc_a[i*N + j] * b[r*N + j]; 
      }  
      i0++; 
     }  
     MPI_Reduce(loc_c, c, N*N, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); 
    }  
    if (myid == 0) { 
     FILE *f = fopen("result.txt", "w"); 
     for (int i = 0; i<N; i++) { 
      for (int j = 0; j<N; j++) { 
       fprintf(f, "%d\t", c[j*N + i]); 
      }  
      fprintf(f, "\n"); 
     }  
     fclose(f); 
    } 
return 0; 
MPI_Finalize(); 
} 
+1

デバッグコード、少なくともライン – Netwave

+0

ジョブが中止さを教えて: [ランク]メッセージを [0]致命的なエラー MPI_Send関数で致命的なエラー:その他のMPIエラー、エラー・スタック: MPI_Send関数(BUF = 0x00277FE8、カウント= 16、MPI_INT、destが= 0、タグが= 0、MPI_COMM_WORLD) がDEADLOCK失敗しました:送信しようとします事前に一致することなくローカルプロセスへのメッセージを受信 –

答えて

1

あなたが得たエラーメッセージは非常に簡単そうです:

あなたはあなたのプロセスを意味し、最初の非ブロックRECVを呼び出すことなく、ターゲット(myid == 0j == 0)としての地位を持つプロセスでMPI_SENDをブロック呼んでいます続行する前にメッセージを受信するまで無限に待機し、デッドロックを引き起こします。

あなたは、あなたの目標に応じて、ここでは複数のオプションがあります:最初の

  1. コールの非ブロッキングのrecvを

  2. my_id == jとは、送信しない場合は、それ自体に送信するMPI_Send関数を使用していない(チェックtrueの場合)

+0

有用な答えのおかげで、最初の選択が働いています。 –