2012-11-29 160 views
0

我確信MPI_Gather收集來自所有進程的數據,包括根進程本身。mpi收集數據

如何讓MPI_Gather從所有進程收集數據,不包括根進程本身? 還是有其他功能嗎?

回答

6

使用MPI_Gatherv複製MPI_Gather的功能,但將0指定爲根級別的塊大小。事情是這樣的:

int rank, size, disp = 0; 
int *cnts, *displs; 

MPI_Comm_size(MPI_COMM_WORLD, &size); 

cnts = malloc(size * sizeof(int)); 
displs = malloc(size * sizeof(int)); 
for (rank = 0; rank < size; rank++) 
{ 
    cnts[i] = (rank != root) ? count : 0; 
    displs[i] = disp; 
    disp += cnts[i]; 
} 

MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

MPI_Gatherv(data, cnts[rank], data_type, 
      bigdata, cnts, displs, data_type, 
      root, MPI_COMM_WORLD); 

free(displs); free(cnts); 

注意MPI_Gatherv可能比MPI_Gather顯著比較慢,因爲MPI實現將是最有可能無法優化的通信路徑,並會回落到一些愚蠢的線性執行聚集操作的。因此,仍然可以使用MPI_Gather並在根進程中提供一些虛擬數據。

您也可以提供MPI_IN_PLACE作爲根進程發送緩衝區的值,它不會將數據發送給自己,但是接下來您必須爲接收緩衝區中的根數據保留位置(就地操作期望根將其數據直接放置在接收緩衝區內的正確位置):

if (rank != root) 
    MPI_Gather(data, count, data_type, 
       NULL, count, data_type, root, MPI_COMM_WORLD); 
else 
    MPI_Gather(MPI_IN_PLACE, count, data_type, 
       big_data, count, data_type, root, MPI_COMM_WORLD);