簡體   English   中英

MPI_聚集接收緩沖區中的垃圾(MPI + C)

[英]MPI_Gather junk in receiving buffer (MPI+C)

我是MPI的新手,正在嘗試並行化多個線程上的代碼。 我需要將大量數據傳遞回主線程,並且無法清除MPI_Gather之后收到的內存垃圾。 這是示例代碼:

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

int main (int argc, char *argv[]) {

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

double *total=NULL;
double parcial[15000];
int W=world_size*15000;

if (rank == 0) {
    total=malloc(sizeof(double) * world_size*15000);
}
else if (rank != 0) {
    for(int i=0; i<15000; i++)parcial[i] = rank*i*0.1;
}
MPI_Barrier(MPI_COMM_WORLD);

if(rank==0) for(int ii=0; ii<W; ii++)total[ii]=0.;

MPI_Gather(parcial,15000,MPI_DOUBLE,total,15000,MPI_DOUBLE,0,MPI_COMM_WORLD);

if (rank == 0) {
    int N=world_size*15000;
    for(int i=0; i<N; i++) printf("%f ", total[i]);
}

free(total);
MPI_Finalize();

}

如果您使用多個線程運行代碼(我嘗試過3,4,5 ...),則即使在調用MPI_Gather並設置a之前將total [ii]顯式設置為零,它也始終在接收緩沖區的開頭出現垃圾。屏障。 是因為我實際上只有兩個內核嗎? 但是我讀過MPI仍然會創建一個虛擬機。 有沒有辦法清潔它並獲得可靠的聚集物?

加成:

我認為,該垃圾可能是從第零線程來的。 為什么在第25行之后它不為零?

MPI手冊頁的MPI_Gather摘錄:

每個進程(包括根進程)將其發送緩沖區的內容發送到根進程。

因此,recv緩沖區total的前15000個元素將在根進程上包含parcial元素。 這已在您的代碼中統一了。

編輯:@Gilles評論說,可以使用MPI_IN_PLACE來避免在根進程上進行初始化。 這是顯示其效果的示例:

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


int main(int argc, char *argv[])
{
    int rank, size;

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

    int *in_place_total = calloc(sizeof(int), size);
    int *total = calloc(sizeof(int), size);

    int sendval = rank-5000;

    MPI_Gather(&sendval, 1, MPI_INT,
           total, 1, MPI_INT, 0, MPI_COMM_WORLD);

    if (rank == 0)
        assert(total[0] == -5000);

    if (rank)
        MPI_Gather(&sendval, 1, MPI_INT,
           in_place_total, 1, MPI_INT, 0, MPI_COMM_WORLD);
    else
        MPI_Gather(MPI_IN_PLACE, 1, MPI_INT,
           in_place_total, 1, MPI_INT, 0, MPI_COMM_WORLD);

    if (rank == 0)
        assert(in_place_total[0] == 0);

    free(total);
    free(in_place_total);

    MPI_Finalize();

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM