Второй MPI_Send зависает, если размер буфера больше 256

int n, j, i, i2, i3, rank, size,  rowChunk,  **cells, **cellChunk;


MPI_Status status;

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


if(!rank){
    printf("\nEnter board size:\n");
    fflush(stdout);
    scanf("%d", &n);

    printf("\nEnter the total iterations to play:\n");
    fflush(stdout);
    scanf("%d", &j);


    srand(3);

    rowChunk = n/size; //how many rows each process will get

    for(i=1; i<size; i++){

        MPI_Send(&n,1, MPI_INT, i, 0, MPI_COMM_WORLD);
        MPI_Send(&j,1, MPI_INT, i, 7, MPI_COMM_WORLD);
    }

    cells = (int**) malloc(n*sizeof(int*));    //create main 2D array

    for(i=0; i<n; i++){

        cells[i] = (int*) malloc(n*sizeof(int));
    }

    for(i=0; i<n; i++){
        for(i2=0; i2<n; i2++){           //fill array with random data

            cells[i][i2] = rand() % 2;
        }
    }       

    for(i=1; i<size; i++){        //send blocks of rows to each process
        for(i2=0; i2<rowChunk; i2++){ //this works for all n

            MPI_Send(cells[i2+(rowChunk*i)], n, MPI_INT, i, i2, MPI_COMM_WORLD);
        }
    }

    cellChunk = (int**) malloc(rowChunk*sizeof(int*));

    for(i=0; i<rowChunk; i++){    //declare 2D array for process zero's array chunk

        cellChunk[i] = (int*) malloc(n*sizeof(int));
    }

    for(i=0; i<rowChunk; i++){   //give process zero it's proper chunk of the array
        for(i2=0; i2<n; i2++){

            cellChunk[i][i2] = cells[i][i2];
        }
    }


    for(i3=1; i3<=j; i3++){

        MPI_Send(cellChunk[0], n, MPI_INT, size-1,1,MPI_COMM_WORLD); //Hangs here if n >256
        MPI_Send(cellChunk[rowChunk-1], n, MPI_INT, 1,2,MPI_COMM_WORLD); //also hangs if n > 256

            ... //Leaving out code that works

Этот код отлично работает, если n (размер массива) меньше или равен 256. Если больше, он зависает на первом MPI_Send. Кроме того, при отправке фрагментов строк массива другим процессам (сначала MPI_Send) другие процессы получают свои данные безошибочно, даже если n > 256. Что может привести к зависанию только этого MPI_Send, если размер буфера превышает 256?


c mpi
person Drew    schedule 01.03.2011    source источник
comment
Можете ли вы опубликовать полный код? Я не вижу никаких проблем с фрагментом, который вы разместили.   -  person powerrox    schedule 14.07.2011


Ответы (3)


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

person Jeremiah Willcock    schedule 01.03.2011
comment
Код неполный. MPI_Send вызывается только корнем. Он пропустил остальную часть кода, как вы можете видеть в последней строке. Вы можете перефразировать свой ответ. - person powerrox; 14.07.2011

MPI_Send — это блокирующий вызов. Стандарт предписывает, что MPI_Send может вернуть управление, как только буфер сообщения может быть безопасно изменен. В качестве альтернативы, MPI_Send может ждать возврата до тех пор, пока некоторое время ПОСЛЕ запуска или завершения MPI_Recv.

Реализация MPI, которую вы используете, скорее всего, выполняет "нетерпеливое" продвижение сообщения, если сообщение составляет ‹256 счетчиков (с типом данных MPI_INT это будет сообщение размером 1k). Сообщение копируется в другой буфер, и управление возвращается "рано". Для больших (r) сообщений вызов MPI_Send не возвращается до тех пор, пока (по крайней мере) не будет выполнен соответствующий вызов MPI_Recv.

Если вы разместите полный репродуктор, вы, вероятно, получите лучший ответ.

person Stan Graves    schedule 24.08.2011

MPI_Send "может блокироваться до тех пор, пока сообщение не будет получено", поэтому, скорее всего, соответствующий прием не будет достигнут. Вы должны убедиться, что MPI_Recv расположены в правильном порядке. Поскольку вы не разместили свою часть получения, невозможно сообщить подробности.

Вы можете реструктурировать свое приложение, чтобы убедиться, что соответствующие приемы в порядке. Вам также может быть удобно использовать комбинированный MPI_Sendrecv или неблокирующие MPI_Isend, MPI_Irecv и MPI_Wait.

person Zulan    schedule 01.03.2011