2011-02-24 106 views
8

我想通過一個動態二維數組與bcast到所有的行列。 我有以下代碼。MPI_Bcast一個動態二維數組

#include <stdlib.h> 
#include <mpi.h> 

int main(int argc, char **argv) 
{ 
    float **array; 
    int rank,size,i,j; 

    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD,&rank); 
    MPI_Comm_size(MPI_COMM_WORLD,&size); 

    if(rank==0) 
    { 
     array = (float **)malloc(10*sizeof(float)); 
     for(i=0;i<10;i++) 
      array[i] = (float *)malloc(10*sizeof(float)); 

     for(i=0;i<10;i++) 
     for(j=0;j<10;j++) 
      array[i][j]=i+j; 
    } 
    MPI_Bcast(array,10*10,MPI_FLOAT,0,MPI_COMM_WORLD); 
    MPI_Finalize(); 
} 

由於某種原因,我不能理解我得到分段錯誤。 任何知道問題出在哪裏的人?

+1

@davidb和@jackn:傢伙,他希望與指針數組10個陣列(這些數組應包含然後彩車),如果你告訴他malloc的100 *的sizeof(浮動),你也應該告訴他如何設定爲行主或列爲主排序的指針。 – 2011-02-24 13:35:35

回答

6

array應該是100,而不是10,因爲你每次分配每行10輛彩車。 JackN的回答有執行此操作的代碼。

然而,在除了秩0以外的任何過程中,指針陣列將是null。 您需要初始化所有進程的數組,然後在根上填充數組。

你可以只移動的malloc碼出if (rank ==0)塊的,它應該工作,你如何期望。

2

陣列應該是100,而不是10

array = (float **)malloc(100*sizeof(float)); 
+0

你的意思是,如果我想的10×10的二維數組我有分配的100X1的數組?我可以像2d數組那樣訪問它? – faulpin 2011-02-24 13:19:31

+0

是的。並且擺脫'爲(I = 0; I <10;我++)的陣列[I] =(浮子*)malloc的(10 *的sizeof(浮動));'試圖訪問的存儲器位置時,會發生一個分割的錯不允許。 – jacknad 2011-02-24 14:10:40

1

你可能想第一的malloc改變

malloc(10*sizeof(void*)) 

因爲數組存儲指針和商店浮動,而不是整數:

array[i][j]=1.0; 
22

這裏有三個問題 - 一個涉及分配,一個涉及到在那裏的分配,以及一個涉及MPI是如何工作的,並沒有其他的答案對所有的人都相當碰。

第一個也是最嚴重的問題是分配東西的地方。正如@davidb指出的那樣,你只是在任務零分配內存,所以其他任務沒有內存來接收廣播。

就像在C一般2D分配,你的代碼幾乎是完全正確的。在這個代碼塊:

 array = (float **)malloc(10*sizeof(float)); 
    for(i=0;i<10;i++) 
     array[i] = (float *)malloc(10*sizeof(float)); 

唯一真正的問題是,第一malloc的應該是10浮子指針,沒有花車:

 array = (float **)malloc(10*sizeof(float *)); 
    for(i=0;i<10;i++) 
     array[i] = (float *)malloc(10*sizeof(float)); 

這是由@eznme指出。第一種方式可能取決於你在什麼編譯內存模型/與鏈接等實際工作,並會在32位操作系統/機器幾乎可以肯定的工作 - 但只是因爲它的工作原理並不總是意味着它是正確的:)

現在,最後一個問題是你已經在C中聲明瞭一個完美的2d數組,但這不是MPI期望的。當你撥打這個電話

MPI_Bcast(array,10*10,MPI_FLOAT,0,MPI_COMM_WORLD); 

你告訴MPI通過array送100輛連續花車指出。您注意到庫例程無法知道數組是否是指向2d或3d或12d數組的開始處的指針,或者各個維度是什麼;它不知道它是否必須遵循指針,如果它確實,它不知道要遵循多少指針。

所以,你想一個浮動指針發送到100輛連續的花車 - 在分配僞多維數組(*)的普通C的方式,你不一定有。你不一定知道的第二排有多遠從第1行中此佈局 - 甚至是在哪個方向。所以你真正想要做的是這樣的:

int malloc2dfloat(float ***array, int n, int m) { 

    /* allocate the n*m contiguous items */ 
    float *p = (float *)malloc(n*m*sizeof(float)); 
    if (!p) return -1; 

    /* allocate the row pointers into the memory */ 
    (*array) = (float **)malloc(n*sizeof(float*)); 
    if (!(*array)) { 
     free(p); 
     return -1; 
    } 

    /* set up the pointers into the contiguous memory */ 
    for (int i=0; i<n; i++) 
     (*array)[i] = &(p[i*m]); 

    return 0; 
} 

int free2dfloat(float ***array) { 
    /* free the memory - the first element of the array is at the start */ 
    free(&((*array)[0][0])); 

    /* free the pointers into the memory */ 
    free(*array); 

    return 0; 
} 

這樣,只有這樣,你保證內存是連續的。然後,你可以做

float **array; 
/* ... */ 
malloc2dfloat(&array, 10, 10); 
if (rank == 0) { 
    for(i=0;i<10;i++) 
     for(j=0;j<10;j++) 
       array[i][j]=i+j; 
} 
MPI_Bcast(&(array[0][0]), 10*10, MPI_FLOAT, 0, MPI_COMM_WORLD); 

注意,對於任意數據結構,則可以仍然通過定義所描述的2D陣列是如何實際上在存儲器佈局的MPI的數據類型執行Bcast;但是這更簡單,更接近你想要的東西。 (*)這裏真正的問題是,C和C派生語言沒有真正的多維數組作爲第一類對象 - 這對於系統編程語言來說是很好的,但是在進行科學編程時卻不可避免地令人不快。

+0

優秀的答案,謝謝。 – Samizdis 2011-11-13 13:02:12

0

,如果你想用10 * 10分配數組,你的代碼:

array = (float **)malloc(10*sizeof(float)) 

應該

array = (float **)malloc(10*sizeof(float*))