1

MPI ユーザー定義データ型関数の練習用に簡単な MPI プログラムを作成しました。以下は、segfault をスローするバージョンです。

    #include <mpi.h>
    #include <iostream>

    using namespace std;

    int main( int argc , char ** argv )
    {
        int rank;

        MPI_Datatype newtype;
        MPI_Datatype newertype;

        MPI_Init(&argc,&argv);

        MPI_Comm_rank(MPI_COMM_WORLD,&rank);

        MPI_Type_contiguous(2,MPI_INT,&newtype);
        MPI_Type_commit(&newtype);
        MPI_Type_vector(3,2,3,newtype,&newertype);
        MPI_Type_commit(&newertype);    



        int * buffer = new int[16];

        for( int i=0 ; i<16 ; i++ )
        {
            buffer[i] = 0;
        }

        if(rank==0)
        {
            for( int i=0 ; i<16 ; i++ )
            {
                buffer[i] = 9;
            }

            MPI_Send(buffer,3,newertype,1,0,MPI_COMM_WORLD);        

        }else if(rank==1)
        {
            MPI_Recv(buffer,3,newertype,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

            for( int i=0 ; i<16 ; i++ )
            {
                cout << buffer[i] << " ";
            }

            cout << endl;

        }

        MPI_Type_free(&newertype);
        MPI_Type_free(&newtype);

        MPI_Finalize();

        return 0;
    }

ただし、配列宣言が MPI_Init の前に移動されると、すべて正常に動作します。

#include <mpi.h>
#include <iostream>

using namespace std;

int main( int argc , char ** argv )
{
    int rank;

    **int * buffer = new int[16];

    for( int i=0 ; i<16 ; i++ )
    {
            buffer[i] = 0;
    }**

    MPI_Datatype newtype;
    MPI_Datatype newertype;

    MPI_Init(&argc,&argv);

    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    MPI_Type_contiguous(2,MPI_INT,&newtype);
    MPI_Type_commit(&newtype);
    MPI_Type_vector(3,2,3,newtype,&newertype);
    MPI_Type_commit(&newertype);    

    if(rank==0)
    {
        for( int i=0 ; i<16 ; i++ )
        {
            buffer[i] = 9;
        }

        MPI_Send(buffer,3,newertype,1,0,MPI_COMM_WORLD);        

    }else if(rank==1)
    {
        MPI_Recv(buffer,3,newertype,0,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);

        for( int i=0 ; i<16 ; i++ )
        {
            cout << buffer[i] << " ";
        }

        cout << endl;

    }

    MPI_Type_free(&newertype);
    MPI_Type_free(&newtype);

    MPI_Finalize();

    return 0;
}

MPI_Init 呼び出しの後に配列を宣言することの何が問題なのか、誰か説明できますか?

For your information, below is the error message

9 9 9 9 0 0 9 9 9 9 0 0 9 9 9 9 
[linuxscc003:10019] *** Process received signal ***
[linuxscc003:10019] Signal: Segmentation fault (11)
[linuxscc003:10019] Signal code: Address not mapped (1)
[linuxscc003:10019] Failing at address: 0x7fa00d0b36c8 
[linuxscc003:10019] [ 0] /lib64/libpthread.so.0() [0x3abf80f500]
[linuxscc003:10019] [ 1] /opt/MPI/openmpi-1.5.3/linux/gcc/lib/libmpi.so.1(opal_memory_ptmalloc2_int_free+0x299) [0x7f980ce46509]
[linuxscc003:10019] [ 2] /opt/MPI/openmpi-1.5.3/linux/gcc/lib/libmpi.so.1(+0xe7b2b) [0x7f980ce46b2b]                            
[linuxscc003:10019] [ 3] /opt/MPI/openmpi-1.5.3/linux/gcc/lib/libmpi.so.1(+0xf0a60) [0x7f980ce4fa60]                            
[linuxscc003:10019] [ 4] /opt/MPI/openmpi-1.5.3/linux/gcc/lib/libmpi.so.1(mca_base_param_finalize+0x41) [0x7f980ce4f731]        
[linuxscc003:10019] [ 5] /opt/MPI/openmpi-1.5.3/linux/gcc/lib/libmpi.so.1(opal_finalize_util+0x1b) [0x7f980ce3f53b]             
[linuxscc003:10019] [ 6] /opt/MPI/openmpi-1.5.3/linux/gcc/lib/libmpi.so.1(+0x4ce35) [0x7f980cdabe35]                            
[linuxscc003:10019] [ 7] type_contiguous(main+0x1aa) [0x408f2e]                                                                 
[linuxscc003:10019] [ 8] /lib64/libc.so.6(__libc_start_main+0xfd) [0x3abec1ecdd]                                                
[linuxscc003:10019] [ 9] type_contiguous() [0x408cc9]                                                                           
[linuxscc003:10019] *** End of error message ***                                                                                
--------------------------------------------------------------------------                                                      
mpiexec noticed that process rank 1 with PID 10019 on node linuxscc003 exited on signal 11 (Segmentation fault).                
--------------------------------------------------------------------------                                                      
Failure executing command /opt/MPI/openmpi-1.5.3/linux/gcc/bin/mpiexec -x  LD_LIBRARY_PATH -x  PATH -x  OMP_NUM_THREADS -x  MPI_NAME --hostfile /tmp/hostfile-9252 -np 2 type_contiguous                     
4

1 に答える 1

4

newertypeには、ストライド 3 の の 2 つの要素で構成される 3 つのセグメントがnewtypeあります。そのタイプの 3 つの要素を送信しています。これは、送信または受信操作中にアクセスされる最初の要素から最後の要素までのメモリ内のスパンが3*3*3 - 1(3 つの要素の 3 つのセグメントをそれぞれ持つ 3 つの要素から 1 を引いたものです。最後のセグメントでは 3 つのうち 2 つの要素しか取得しないためです) ) またはタイプ の 26 要素newtype。それぞれnewtypeが 2 つの連続しMPI_INTた要素です。送信バッファーまたは受信バッファーは少なくとも52整数である必要がありますが、ランク 1 の が割り当てられたバッファーの末尾を超えて書き込み、ヒープ制御構造を上書きする可能性がある16ように割り当てるだけです。MPI_Recvへの呼び出しの前に割り当てを移動するMPI_Initメモリ内のこれらの構造の順序を変更すると、コードは別のものを上書きしますが、重要ではありません。コードはまだ正しくありません。セグメンテーション フォールトが発生していないのは幸運です。より大きなバッファー (少なくとも 52 要素) を使用します。

于 2012-09-01T12:43:18.820 に答える