2017-01-03 9 views
0

MPI_Get_address(&member, &offset[0]);offset[0] = 0;に置き換えられた場合、コードは以下のように出力されます。私の知る限りでは、MPI_BOTTOMの絶対メモリアドレスが必要であり、そのためにMPI_Get_address()が使用されています。構造体MemberMPI_Get_address()に問題ありませんが、構造体Familyは機能しませんでした。何が問題ですか?派生データ型のMPI_Sendのセグメンテーションフォルト

コマンド:

mpirun -n 2 ./out 

出力:

Signal: Segmentation fault (11) 
Signal code: (128) 
Failing at address: (nil) 
mpirun noticed that process rank 0... 

コード:

#include <mpi.h> 

struct Member 
{ 
    double height; 
    MPI_Datatype mpi_dtype; 
    Member() { make_layout(); } 
    void make_layout() 
    { 
     int nblock = 1; 
     int block_count[nblock] = {1}; 
     MPI_Aint offset[nblock]; 
     MPI_Get_address(&height, &offset[0]); 
     MPI_Datatype block_type[nblock] = {MPI_DOUBLE}; 
     MPI_Type_create_struct(nblock, block_count, offset, block_type, &mpi_dtype); 
     MPI_Type_commit(&mpi_dtype); 
    } 
}; 

struct Family 
{ 
    Member member; 
    MPI_Datatype mpi_dtype; 
    Family() { make_layout(); } 
    void make_layout() 
    { 
     int nblock = 1; 
     int block_count[nblock] = {1}; 
     MPI_Aint offset[nblock]; 
     MPI_Get_address(&member, &offset[0]); 
     //offset[0] = 0; <-- HERE!!!!!!! 
     MPI_Datatype block_type[nblock] = {member.mpi_dtype}; 
     MPI_Type_create_struct(nblock, block_count, offset, block_type, &mpi_dtype); 
     MPI_Type_commit(&mpi_dtype); 
    } 
}; 

int main() 
{ 
    int rank; 

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

    if (rank == 0) 
    { 
     Family f; 
     MPI_Send(MPI_BOTTOM, 1, f.mpi_dtype, 1, 0, MPI_COMM_WORLD); 
    } 
    else if (rank == 1) 
    { 
     Family f; 
     MPI_Recv(MPI_BOTTOM, 1, f.mpi_dtype, 0, 0, MPI_COMM_WORLD, NULL); 
    } 

    MPI_Finalize(); 

    return 0; 
} 
+1

C++はCではなく、あなたのコードは*間違いなく* Cである。 –

+0

代わりに、C++インターフェイス 'MPI :: Get_address(void *) 'を代わりに使用することを検討したことがありますか? –

+0

@JohnBollinger C++バインディングは償却されていませんか? ([リンク](http://blogs.cisco.com/performance/the-mpi-c-bindings-what-happened-and-why))を参照してください。 – Shibli

答えて

0

member.mpi_dtype alrea dyは絶対アドレスがMember::heightであり、その型マップにオフセットがあります。 Family::make_layout()memberのアドレスと等しいoffset[0]を指定すると、両方のオフセットが合計され、オフセットが非常に間違っています。そのため、絶対アドレスを持つMPIデータ型は、他のデータ型の構築には使用しないでください。

この場合、MPI_BOTTOMを使用する理由は絶対にありません。構造体には動的に割り当てられたフィールドがなく、相対オフセット付きのMPIデータ型で十分です。

+0

実際に私のコードでは、ほぼすべての構造体にSTLオブジェクトがあります。これが絶対アドレスを使用する理由です。私はあなたの助言[ここ](http://stackoverflow.com/questions/40069267/segmentation-fault-when-sending-struct-having-stdvector-member)に従った。 – Shibli

+0

おそらく私は、そのようなデータ型を他の派生データ型にさらに構成すべきではないことを明確にしていないでしょう。 –

+0

送信/受信操作では、高速化のために動的に割り当てられたフィールドで構成されるデータ型をグループ化したいと考えています。これらの動的データ型をグループ化する別のデータ型を作成したいと思います。動的オブジェクトからなる他のデータ型からデータ型を作成しているので、これは不可能ですか? – Shibli

関連する問題