Тупик MPI (интерфейс передачи сообщений)

Я новичок в кодировании MPI, я пытался передать сообщение, используя простой двумерный массив, разделив процесс на два элемента процесса... но код застревает при передаче сообщений... код выглядит следующим образом... я отредактировал как отправка и получение заказа

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

double a[15][15];

int main(int argc, char **argv)
{
    int process_id,nprocess;
    int i,j;
    int Nxl=5,Nx=10,Ny=10;
    MPI_Status status;
    MPI_Datatype line;
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&nprocess);
    MPI_Comm_rank(MPI_COMM_WORLD,&process_id);
    //Nxl=((Nx-2)/nprocess)+2;
    //printf("NXL=%d\n",Nxl);
    //  printf("process_id=%d\n",process_id);
    if(process_id==0)
    {
        for(i=1;i<=5;i++)
        {
            for(j=1;j<=Ny;j++)
            {
                a[i][j]=3*2*i;
                MPI_Send(&a[Nxl-1][j],1,MPI_DOUBLE,0,1,MPI_COMM_WORLD);
            }
        }
        for(i=1;i<=5;i++)
        {
            for(j=1;j<=Ny;j++)
            {
                printf("matrices=%f\n",a[i][j]);
                MPI_Recv(&a[1][j],1,MPI_DOUBLE,1,1,MPI_COMM_WORLD,&status);
                printf("PROCESS_ID=%d\n",process_id);
            }
        }
    }
    if(process_id==1)
    {
        for(i=6;i<=10;i++)
        {
            for(j=1;j<Ny;j++)
            {
                a[i][j]=4*2;
                MPI_Send(&a[2][j],1,MPI_DOUBLE,1,2,MPI_COMM_WORLD);
            }
        }
        for(i=6;i<=10;i++)
        {
            for(j=1;j<Ny;j++)
            {
                MPI_Recv(&a[Nxl][j],1,MPI_DOUBLE,0,1,MPI_COMM_WORLD,&status);
                printf("PROCESS_ID=%d\n",process_id);
            }
        }
    }
    MPI_Finalize();
}

mpi
person Ankit    schedule 30.01.2014    source источник
comment
MPI_Sendrecv в таком случае твой лучший друг.   -  person Hristo Iliev    schedule 30.01.2014


Ответы (2)


(Я собираюсь написать этот ответ, как если бы у вас было более двух процессов, чтобы быть более общим для потомков, но вы можете переосмыслить его, чтобы он означал только два.)

Христо и Джон правы. Проблема в том, что все ваши процессы отправляют сообщение до того, как кто-либо его получит. Это означает, что посылки могут никогда не вернуться. Каким-то образом вам нужно убедиться, что приемы также доступны. Вы можете сделать это одним из двух способов:

Преобразование блокирующих вызовов в неблокирующие

Если вы преобразуете блокирующие (MPI_SEND/MPI_RECV) вызовы в неблокирующие вызовы и добавите MPI_WAITALL в конец кода, это позволит всем процессам одновременно отправлять и получать сообщения. Затем, после ожидания, вы можете делать все, что хотите, с полученными данными.

Преобразовать MPI_SEND/MPI_RECV в MPI_SENDRECV

Эта опция имеет практически тот же результат, что и отправка и получение одновременно, но вам все равно нужно следить за тем, чтобы все входили в обмены с одними и теми же процессами. Например, если у вас есть все, кто пытается установить связь в кольце, вам нужно убедиться, что все они отправляют направо и получают слева (или наоборот), а не отправляют и получают на кольцо. правильно (что все равно было бы тупиком).

person Wesley Bland    schedule 30.01.2014

Вы заставляете обоих участников разговора говорить, а затем слушать. Нужно сделать так, чтобы один говорил, а другой слушал, а потом наоборот.

person John Zwinck    schedule 30.01.2014
comment
Даже после редактирования и самостоятельной отправки и получения не помогает - person Ankit; 30.01.2014
comment
Можете ли вы заставить работать даже тривиальную программу MPI? Тот, который просто отправляет один раз в одном процессе и получает в другом? - person John Zwinck; 30.01.2014