2016-05-14 76 views
0

我有一個動態二維數組,它是在連續的內存空間中分配的,但是如果我試圖將這個數組分散到兩個使用MPI_Scatter的MPI進程中將會導致分段錯誤,粘貼在這裏:MPI_Scatter動態二維數組行導致分段錯誤

dynamic_2d_array.h

#ifndef _DYNAMIC_2D_ARRAY_H_ 
#define _DYNAMIC_2D_ARRAY_H_ 

#include <stdio.h> 
#include <stdlib.h> 

//typedef double real; 
typedef float real; 

real **allocate_dynamic_2d_array(int nrows, int ncols); 
void free_dynamic_2d_array(real** array_dynamic); 
void print_matrix(real** array_dynamic, int nrows, int ncols, char* fmt_string); 

real** allocate_dynamic_2d_array(int nrows, int ncols) { 
    /* here is the method to correct the non-contiguous memory problem */ 
    int i; 
    real** array_dynamic=(real**)malloc(nrows*sizeof(real*)); 
    real* data=(real*)malloc(nrows*ncols*sizeof(real)); 
    for (i=0; i<nrows; i++){ 
     array_dynamic[i]=&(data[ncols*i]); 
    } 
    return array_dynamic; 
} 

void free_dynamic_2d_array(real** array_dynamic){ 
    free((void*)array_dynamic[0]); 
    free((void*)array_dynamic); 
} 

void print_matrix(real** array_dynamic, int nrows, int ncols, char* fmt_string) { 
//void print_matrix(real array_dynamic[][4], int nrows, int ncols, char* fmt_string) { 
    int i,j; 
    for (i = 0; i < nrows; i++){ 
     for (j = 0; j < ncols; j++){ 
      printf(fmt_string, array_dynamic[i][j]); 
     } 
     printf("\n"); 
    } 
} 

#endif // #ifndef _DYNAMIC_2D_ARRAY_H_ 

這裏是scatter_mat.h:

#include <stdio.h> 
#include <stdlib.h> 
#include "mpi.h" 
#include "dynamic_2d_array.h" 

int main(int argc, char ** argv) 
{ 
    MPI_Init(&argc, &argv); 
    int rank, psize, root = 0; 
    int i,j; 
    int ncols; 
    int M=48,N=3; 
    real *sub_mat; 
    real **A; 

    MPI_Comm_size(MPI_COMM_WORLD, &psize); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    if (rank==0) { 
     A = allocate_dynamic_2d_array(M,N);   
     printf("before scatter:\n"); 
     int idx=0; 
     for (i=0;i<M;i++){ 
      for (j=0;j<N;j++) { 
       A[i][j]=idx++; 
       printf("%4.1f\t",A[i][j]); 
      } 
      printf("\n"); 
     } 
    } 

    ncols = M/psize; 
    sub_mat = (real*)malloc(N*ncols*sizeof(real)); 

    MPI_Scatter(&(A[0][0]),N*ncols,MPI_FLOAT,sub_mat,N*ncols,MPI_FLOAT,root,MPI_COMM_WORLD); 

    for (i=0;i<ncols*N;i++) 
     printf("%3.1f\t",sub_mat[i]); 
    printf("\n"); 

    if (rank==0) { 
     free_dynamic_2d_array(A); 
    } 

    free(sub_mat); 
    MPI_Finalize(); 
    return 0; 
} 

如果我編譯使用mpicc一個nd使用mpirun -np 2運行它,它會導致rank 1的分段錯誤,更讓我困惑的是它使用調試模式(mpicc -g)很好,但是在釋放模式下崩潰,我想必須有一些內存訪問問題,但我無法弄清楚,有沒有人可以提供一些建議?

下面是MPI編譯器的信息:

$ mpiexec --version 
mpiexec (OpenRTE) 1.6.2 

Report bugs to http://www.open-mpi.org/community/help/ 
$ mpicc -show 
icc -I/usr/local/packages/openmpi/1.6.2/Intel-13.0.0/include -L/usr/local/packages/openmpi/1.6.2/Intel-13.0.0/lib -lmpi -ldl -lm -Wl,--export-dynamic -lrt -lnsl -libverbs -libumad -lpthread -lutil 

非常感謝!

+0

昨天晚上我發現它似乎MPI有一些問題驅散動態二維數組指針,所以目前的解決方法是在開始時通過定義一個「float * sendp;」來使用另一個float *指針指向A然後在'A = allocate_dynamic_2d_array(M,N);'後面添加'sendp =&(A [0] [0])',然後用MPI_Scatter中的sendp替換'&(A [0] [0])'至少不會返回分段錯誤。 –

回答

1

問題是,您在所有等級中取消&(A[0][0]),但它僅在根級別中分配。將NULL作爲第一個參數傳遞到MPI_Scatter除了在根目錄之外的所有等級中。

您還應該將ncols重命名爲nrows(語義上)。

+0

感謝您的回答,但它似乎不是原因,實際上我已經嘗試在if(rank == 0)之前添加'A = NULL',這仍然會導致分段錯誤。在MPI_Scatter中,除根之外的所有A指針都被忽略,對嗎? –

+0

另外,Scatter是一個集體操作,我們不能這樣做:'if(rank == 0)MPI_Scatter(xxx)',你如何做出判斷? –

+0

這是行不通的? 'MPI_Scatter(rank == root?&(A [0] [0]):NULL,...)' – gudok