Проблемы с памятью MPI_Gatherv (MPI + C) - PullRequest
0 голосов
/ 24 мая 2018

В качестве продолжения моего предыдущего вопроса я изменил код для переменного числа ядер.Однако способ, которым Gatherv реализован в моем коде, кажется ненадежным.После 3-4 запусков конечная последовательность в буфере сбора заканчивается повреждением, похоже, из-за утечки памяти.Пример кода:

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

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

MPI_Init(&argc, &argv);
int world_size,*sendarray;
int rank, *rbuf=NULL, count,total_counts=0;
int *displs=NULL,i,*rcounts=NULL;

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

if(rank==0){
    displs = malloc((world_size+1)*sizeof(int));
    for(int i=1;i<=world_size; i++)displs[i]=0;
    rcounts=malloc(world_size*sizeof(int));

    sendarray=malloc(1*sizeof(int));
    for(int i=0;i<1;i++)sendarray[i]=1111;
    count=1;
}

if(rank!=0){
    int size=rank*2;
    sendarray=malloc(size*sizeof(int));
    for(int i=0;i<size;i++)sendarray[i]=rank;
    count=size;
}

MPI_Barrier(MPI_COMM_WORLD);

MPI_Gather(&count,1,MPI_INT,rcounts,1,MPI_INT,0,MPI_COMM_WORLD);

MPI_Barrier(MPI_COMM_WORLD);

if(rank==0){
    displs[0]=0;
    for(int i=1;i<=world_size; i++){
        for(int j=0; j<i; j++)displs[i]+=rcounts[j];
    }

    total_counts=0;
    for(int i=0;i<world_size;i++)total_counts+=rcounts[i];
    rbuf = malloc(10*sizeof(int));
}

MPI_Gatherv(sendarray, count, MPI_INT, rbuf, rcounts,
            displs, MPI_INT, 0, MPI_COMM_WORLD);

if(rank==0){
    int SIZE=total_counts;
    for(int i=0;i<SIZE;i++)printf("(%d) %d ",i, rbuf[i]);

    free(rbuf);
    free(displs);
    free(rcounts);
}

if(rank!=0)free(sendarray);
MPI_Finalize();

}

Почему это происходит и есть ли способ это исправить?

Это становится намного хуже в моем реальном проекте.Каждый отправляющий буфер содержит 150 дублей.Приемный буфер становится очень грязным, и иногда я получаю ошибку завершения кровати с кодом выхода 6 или 11.

Может ли кто-нибудь хотя бы воспроизвести мои ошибки?

Мое предположение: Я выделяю память для sendarray в каждом потоке отдельно.Если бы моя виртуальная машина была 1-к-1 к оборудованию, то, вероятно, такой проблемы не было бы.Но у меня есть только 2 ядра и запустить процесс для 4 или более.Может ли это быть причиной?

1 Ответ

0 голосов
/ 25 мая 2018

Измените эту строку:

rbuf = malloc(10*sizeof(int));

на:

rbuf = malloc(total_counts*sizeof(int));

В качестве дополнительного примечания: каждый процесс MPI существует в своем собственном адресном пространстве процесса, и они не могут штамповать данные друг друга, кромечерез ошибочные данные, явно переданные через функции MPI_XXX, что приводит к неопределенному поведению.

...