這裏有三個問題 - 一個涉及分配,一個涉及到在那裏的分配,以及一個涉及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派生語言沒有真正的多維數組作爲第一類對象 - 這對於系統編程語言來說是很好的,但是在進行科學編程時卻不可避免地令人不快。
@davidb和@jackn:傢伙,他希望與指針數組10個陣列(這些數組應包含然後彩車),如果你告訴他malloc的100 *的sizeof(浮動),你也應該告訴他如何設定爲行主或列爲主排序的指針。 – 2011-02-24 13:35:35