2012-08-31 34 views
1

我寫了一個簡單的MPI程序,用於練習MPI用戶定義的數據類型函數。以下是拋出segfault的版本。MPI奇怪的分割錯誤

#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      
+0

我認爲這只是你如何MPI_Send在第一個例子中的緩衝區 – pyCthon

+0

我懷疑這是由0級的MPI_Send引起的。 輸出正確打印輸出。此外,我上面發佈的錯誤表明錯誤來自等級1。 –

回答

3

newertype有3個路段由具有爲3的步幅您正在發送該類型的3種元素的newtype 2個元件。這意味着從發送或接收操作期間訪問的第一個元素到最後一個元素的內存跨度爲3*3*3 - 1(3個元素,每個元素都有3個元素的3個元素,減1,因爲最後一個元素只佔用3個元素中的2個元素段)或者newtype類型的26個元素。每個newtype是兩個連續的MPI_INT元素。您的發送緩衝區或接收緩衝區應至少爲52整數,但您只分配16,因此排名1中的MPI_Recv正在寫入超出分配緩衝區的末端,可能會覆蓋堆控制結構。在調用MPI_Init之前移動分配會改變內存中這些結構的順序,您的代碼現在覆蓋了一些不同但不重要的東西。該代碼仍然不正確,你只是幸運,它不會段錯誤。使用更大的緩衝區(至少52個元素)。