-2

使用@GillesGouaillardet的评论进行编辑:

我正在使用 MPI 在 C++ 中编写一个简单的代码来进行并行处理。我从进程 4 到 5 发送 char 消息,并 'nothing'为所有其他进程初始化消息。

所以,我想收集每个进程的所有消息('nothing'对于所有进程,但接收进程 4 发送的 char 消息的第 5 个进程除外)并为每个进程打印出来,例如

Hello from process 0 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
Hello from process 1 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
...
Hello from process 5 among 8 of the machine jeremy-SATELLITE-P50-C
received
...

例如,我尝试了几件事:https://stackoverflow.com/a/31932283/14901229,(您可以在下面的代码中看到)但它会逐字打印...

也许有人可以帮助我?提前致谢!

这是我的代码:


int rank,nbproc, taille;
    char name[80];
    
    char message[] = "preceived";
    int longueur = strlen(message); 
    int len_buffer = 200;
    char Buffer_Hello[len_buffer];
    char receive[] = "nothing";    
    
 MPI_Init(&argc, &argv);

    MPI_Comm_size(MPI_COMM_WORLD, &nbproc); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);  
    MPI_Get_processor_name(name, &taille);
    
    sprintf(Buffer_Hello,"Hello from process %d among %d of the machine %s",rank,nbproc,name);
    
    MPI_Send(Buffer_Hello,len_buffer,MPI_CHAR,0,rank+10,MPI_COMM_WORLD);

 if (rank == 4)
    {
        MPI_Send(&message[1],longueur+1,MPI_CHAR,5,2,MPI_COMM_WORLD);
 // sends the message from the second element
    }
 
    if (rank == 5)
    {   
        MPI_Recv(&receive,longueur+1,MPI_CHAR,4,2,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
    }

    int mylen = strlen(receive);
    int* recvcounts = new int[nbproc*sizeof(int)]; 

    
    MPI_Gather(&mylen,1,MPI_INT,recvcounts,1,MPI_INT,0,MPI_COMM_WORLD); 
    
    int totlen = 0; 
    int* displs = new int[nbproc*sizeof(int)];


    if(rank == 0)
    {
        displs[0] = 0;
        totlen += recvcounts[0] + 1; 

        for(int i=1; i < nbproc; i++)
        {
            totlen += recvcounts[i]+1; 
            displs[i] = displs[i-1] + recvcounts[i-1] + 1; 
        }
    }


    char* totalstring = new char[totlen*sizeof(char)]; 

    if(rank == 0)
    {
        for (int i=0; i<totlen; i++) 
            totalstring[i] = ' '; 
        
        totalstring[totlen] = '\0'; 
    }
  
       MPI_Gatherv(&receive, mylen, MPI_CHAR,
                totalstring, recvcounts, displs, MPI_CHAR,
                0, MPI_COMM_WORLD);

  
   if(rank == 0)
   {
       cout << Buffer_Hello << endl;
       
        for(int i = 1; i < nbproc; i++)
        {
            MPI_Recv(Buffer_Hello,len_buffer,MPI_CHAR,i,i+10,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
            cout << Buffer_Hello << endl;
           cout << totalstring[i] << endl;
       
        }
   }

    MPI_Finalize(); 
    return 0;
}

我的输出:

Hello from process 0 among 8 of the machine jeremy-SATELLITE-P50-C
Hello from process 1 among 8 of the machine jeremy-SATELLITE-P50-C
o
Hello from process 2 among 8 of the machine jeremy-SATELLITE-P50-C
t
Hello from process 3 among 8 of the machine jeremy-SATELLITE-P50-C
h
Hello from process 4 among 8 of the machine jeremy-SATELLITE-P50-C
i
Hello from process 5 among 8 of the machine jeremy-SATELLITE-P50-C
n
Hello from process 6 among 8 of the machine jeremy-SATELLITE-P50-C
g
Hello from process 7 among 8 of the machine jeremy-SATELLITE-P50-C
4

1 回答 1

0

这是我最终找到的一种方法来收集这些字符数组并为每个进程打印出来。

首先,我从每个进程中取回所有长度不同的消息,并用它们之间的所有单词和空格制作一个大字符串。可能不是更好的方法,但如果有人有更好的主意,请告诉我!


 int mylen = strlen(receive); 
    int* recvcounts = new int[nbproc*sizeof(int)]; 

    
    MPI_Gather(&mylen,1,MPI_INT,recvcounts,1,MPI_INT,0,MPI_COMM_WORLD); 
    
    int totlen = 0; 
    int* space = new int[nbproc*sizeof(int)]; 


    if(rank == 0)
    {
        displs[0] = 0; 
        totlen += recvcounts[0] + 1; 
        for(int i=1; i < nbproc; i++)
        {
            totlen += recvcounts[i]+1; 
            space[i] = space[i-1] + recvcounts[i-1] + 1; 
        }
    }


    char* totalstring = new char[totlen*sizeof(char)]; 

    if(rank == 0)
    {
        for (int i=0; i<totlen; i++) 
            totalstring[i] = ' '; 
        
        totalstring[totlen] = '\0'; 
    }
  
  
       MPI_Gatherv(&receive, mylen, MPI_CHAR,
                totalstring, recvcounts, space, MPI_CHAR,
                0, MPI_COMM_WORLD);

然后我将它们totalstring分成几块,并在过程 0 中以正确的顺序打印出来。


    char* piece = strtok(totalstring," "); 
  
   if(rank == 0)
   {
       cout << Buffer_Hello << endl;
        cout << piece << endl;
        for(int i = 1; i < nbproc; i++)
        {
            MPI_Recv(Buffer_Hello,len_buffer,MPI_CHAR,i,i+10,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
            cout << Buffer_Hello << endl;
           
            if(piece != NULL)  
            {
                piece = strtok(NULL," "); 
          
                cout << piece << endl;
            }
           
        }
   }

结果如下:

Hello from process 0 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
Hello from process 1 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
Hello from process 2 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
Hello from process 3 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
Hello from process 4 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
Hello from process 5 among 8 of the machine jeremy-SATELLITE-P50-C
received
Hello from process 6 among 8 of the machine jeremy-SATELLITE-P50-C
nothing
Hello from process 7 among 8 of the machine jeremy-SATELLITE-P50-C
nothing

所以,正如你所看到的,它有效,但它可能不是最好的方法,所以如果有人有更好的主意,不要犹豫!

于 2021-08-22T15:58:21.700 回答