2016-05-27 19 views
0

私は最近、MPIの学習を始めました。あなたが推測しているように、私は自分で解決できないエラーに遭遇しました!MPIで行列を掛ける(セグメンテーションフォールト)

2つの行列を乗算するプログラムを作成したいと思います。しかし、私はあまりそれを持っていない、実際には、私は最初の場所で行列を放送に立ち往生しています。

void matMulMPI(long N, double *a, double *b, double *c) { 
    long i, j, k; 
    int rank, size; 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 

    MPI_Bcast(&N, 1, MPI_LONG, MASTER, MPI_COMM_WORLD); 

    MPI_Bcast(b, N*N, MPI_DOUBLE, MASTER, MPI_COMM_WORLD); 

    printMatrix(N, b); 

    //TO-DO: Broadcast A 
    //TO-DO: Do Math 
} 

をそして、この放送は動作しません:以下のように(理論的に)数学を行い

#define MASTER 0 
if (rank == MASTER) { 
     A = (double *) malloc(N * N * sizeof(double)); 
     B = (double *) malloc(N * N * sizeof(double)); 
     matFillRand(N, A); 
     matFillRand(N, B); 
    } 

if (rank == MASTER) { 
     P = (double *) malloc(N * N * sizeof(double)); 
    } 

matMulMPI(N, A, B, P); 

if (rank == MASTER) { 
     printMatrix(N, P); 
} 

の機能があります。私は、次のメッセージを取得する:セグメンテーションフォールト(11)信号コード:無効なアクセス許可が(2)のアドレスに失敗:0x401560信号: セグメンテーション障害(11)信号コード:

*プロセス信号受信信号無効なアクセス許可(2) アドレス:0x401560 [0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x10340)[0x7fc3ede6b340] [1] /lib/x86_64-linux-gnu/libc .so.6(+ 0x981c0)0x7fc3edb2e1c0] [2] /usr/lib/libmpi.so.1(opal_convertor_unpack+0x105)0x7fc3ee1788d5] [ 3] の/ usr/LIB/OpenMPIの/ LIB/OpenMPIの/ mca_pml_ob1 .so(mca _pml_ob1_recv_frag_callback_match + 0x460) [0x7fc3e6587630] [4] /usr/lib/openmpi/lib/openmpi/mca_btl_sm.so(mca_btl_sm_component_progress+0x487) [0x7fc3e572a137] [5] /usr/lib/libmpi.so.1(opal_progress + 0x5a) [0x7fc3ee1849ea] [6] /usr/lib/libmpi.so.1(ompi_request_default_wait+0x16d)0x7fc3ee0d1c0d] [7] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(ompi_coll_tuned_bcast_intra_generic + 0x49e) [0x7fc3e486da9e] [8] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(ompi_coll_tuned_bcast_intra_binomial+0xb7) [0x7fc3e486df27] [9] の/ usr/LIB/OpenMPIの/ LIB/OpenMPIの/ mca_coll_tuned .so(ompi_coll_tuned_bcast_intra_dec_fixed + 0xcc) [0x7fc3e486573c] [10] /usr/lib/openmpi/lib/openmpi/mca_coll_sync.so(mca_coll_sync_bcast+0x64) [0x7fc3e4a7d6a4] [11] /usr/lib/libmpi.so.1(MPI_Bcast+0x13d) [0x7fc3ee0df78d] [12] ./matMul()[0x4011a9] [13] ./matMul()[0x401458] [14] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [エラーメッセージの0x7fc3edab7ec5] [15] ./matMul()[0x400b49] エンド [0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x10340)0x7fa4a1fe5340] [1] /lib/x86_64-linux-gnu/libc.so.6(+0x981c0)[2] /usr/lib/libmpi.so.1(opal_convertor_unpack+0x105)[0x7fa4a22f28d5] [ 3] /usr/lib/openmpi/lib/openmpi/mca_pml_ob1.so(mca_pml_ob1_recv_frag_callback_match+0x460) [0x7fa49a701630] [4] /usr/lib/openmpi/lib/openmpi/mca_btl_sm.so(mca_btl_sm_component_progress+0x487) [0x7fa4998a4137 ] [5] /usr/lib/libmpi.so.1(opal_progress+0x5a) [0x7fa4a22fe9ea] [6] /usr/lib/libmpi.so.1(ompi_request_default_wait+0x16d)0x7fa4a224bc0d] [7] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(ompi_coll_tuned_bcast_intra_generic+0x4e0) [0x7fa4989e7ae0] [8] /usr/lib/openmpi/lib/openmpi/mca_coll_tunedです。そう(0xb7 + ompi_coll_tuned_bcast_intra_binomial) [0x7fa4989e7f27] [9] /usr/lib/openmpi/lib/openmpi/mca_coll_tuned.so(ompi_coll_tuned_bcast_intra_dec_fixed+0xcc) [0x7fa4989df73c] [10] の/ usr/LIB/OpenMPIの/ LIB/OpenMPIの/ mca_coll_sync.so(mca_coll_sync_bcast + 0x64) [0x7fa498bf76a4] [11] /usr/lib/libmpi.so.1(MPI_Bcast+0x13d) [0x7fa4a225978d] [12] ./matMul()[0x4011a9] [13] ./matMul()[0x401458] [14] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5) [0x7fa4a1c31ec5] [15] ./matMul()[0x400b49] エンドエラーメッセージ* -------------------------------------------- ------------------------------ mp irunはノード rtidev5.etf.bg.ac.rsのPID 12466を持つプロセスランク2がシグナル11(セグメンテーションフォルト)で終了したことに気付きました。 ------------------------------------------------- ------------------------- 2つのプロセス全体が殺されました(クリーンアップ中にmpirunによって可能性があります)

答えて

2

私はそれを理解しました。すべてのプロセス(マスタだけでなく)が最初にメモリを割り当てる必要があります。放送は、放送後のすべてのプロセスがMPI_Bcast` `の最初の引数にデータを格納することを意味する:

ので、不足している行が

void matMulMPI(long N, double *a, double *b, double *c) { 
    ... 

    MPI_Bcast(&N, 1, MPI_LONG, MASTER, MPI_COMM_WORLD); 

    b = (double *) malloc(N * N * sizeof(double)); 

    MPI_Bcast(b, N*N, MPI_DOUBLE, MASTER, MPI_COMM_WORLD); 

    ... 
} 
+0

そして、このようなケースである理由だけで明確にしました。マスタープロセスでは送信バッファですが、他のプロセスでは受信バッファです。それにもかかわらず、 'MPI_Bcast'を呼び出す前にすべてのプロセスに割り当てられていなければ、割り当てられていないバッファにデータを格納しようとします。 – NoseKnowsAll

関連する問題