MPI发送接收

时间:2017-10-01 05:21:31

标签: c parallel-processing tags mpi send

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

int main(argc,argv)
int argc;
char *argv[];  {
int numtasks, rank, dest, source, rc, count, tag=1;
MPI_Status Stat;

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

if (rank%2 == 1) {
dest = (rank+1)%numtasks;
  source = (rank-1+numtasks)%numtasks;
  rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD);
  rc = MPI_Recv(&inmsg, 1, MPI_CHAR, source, tag,MPICOMM_WORLD, &Stat);
}

else  {
  dest   = (rank-1+numtasks)%numtasks;
  source = (rank+1)%numtasks;
  rc = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
  rc = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
}
rc = MPI_Get_count(&Stat, MPI_CHAR, &count);
printf("Task %d: Received %d char(s) from task %d with tag %d\n",
   rank, count, Stat.MPI_SOURCE, Stat.MPI_TAG);

MPI_Finalize();
}

结果:

Task 2: Received 1 char(s) from task 3 with a tag 1
Task 0: Received 1 char(s) from task 1 with a tag 1

为什么任务无法识别2个以上的处理器? 我想在超过2个处理器上运行它 我用环模式更新了mpi程序,我认为如果(排名%2 == 1)

,行可能出错了

3 个答案:

答案 0 :(得分:0)

countStat仅在0级和1级初始化,因此您基本上在第2和第3级上打印垃圾。

你的程序是硬编码的,可以在2个任务上运行(它会在1个任务上崩溃,并且打印3个或更多任务的垃圾)。

我建议您使用MPI_Sendrecv()进行调查,以便在一次MPI通话中发送和接收无死锁。

不确定您要实现的目标,请详细说明并更新您的问题。话虽这么说,您可以考虑使用响铃模式,以便您的程序可以在任意数量的MPI任务上运行(例如发送到(rank+1)%numtasks并从(rank+numtasks-1)%numtasks接收)

根据您编辑的问题,所有MPI等级的通信模式可以如下所示

dest = (rank+1)%numtasks;
source = (rank-1+numtasks)%numtasks;
MPI_Sendrecv(&outmsg, 1, MPI_CHAR, dest, tag,
             &inmsg, 1, MPI_CHAR, source, tag,
             MPI_COMM_WORLD, &Stat);

答案 1 :(得分:0)

可能会尝试更好地调查MPI机制:

不要犹豫尝试代码,因为它会帮助您掌握 numtasks rank -ID的概念并将其关联起来运行时操作。编译错误将在上面发布的代码中报告快捷方式。要获得更多与MPI相关的做法和见解,还应从相应的rc调用

分配和评估 MPI_<fun>() 返回代码

问:为什么任务无法识别2个以上的处理器? 答: 可以,,但if(){..}else if(){..}代码块不允许其他人产生任何可见的输出。

问:我想将4197005的结果更改为2,3 - 如何?
A:有人无法更改MPI报告的数字,但您可以更改代码的行为(请参见下文),并在可行的情况下进行更多输出正在执行什么 时, 实际上是什么。这样我们就可以学习理解MPI概念并验证实际的MPI代码执行。

随意提出更多问题。

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

int main( int   argc,
          char *argv[]
          ) {
   int        numtasks, rank, dest, source, rc, count, tag = 1;
   MPI_Status Stat;

   printf( "(INF) will MPI_Init()...\n" );

   MPI_Init( &argc, &argv );
   printf( "(INF)      MPI_Init() done.\n" );

   MPI_Comm_size( MPI_COMM_WORLD, &numtasks );
   MPI_Comm_rank( MPI_COMM_WORLD, &rank );
   printf( "(INF) I am MPI[%d of %d]\n",
            rank,
            numtasks
            );

   if ( rank  == 0 ) {
        dest   = 1;
        source = 1;
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Send( ->MPI[%d] ) + MPI_Recv( <-MPI[%d] ). Last RetCODE == %d.\n",
                 rank,
                 numtasks,
                 dest,
                 source,
                 rc
                 );
   }
   else
   if ( rank  == 1 ) {
        dest   = 0;
        source = 0;
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Recv( <-MPI[%d] ) + MPI_Send( ->MPI[%d] ). Last RetCODE == %d\n",
                 rank,
                 numtasks,
                 source,
                 dest,
                 rc
                 );
   }
   else
   if ( rank  == 2 ) {
        dest   = 3;
        source = 3;
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Recv( <-MPI[%d] ) + MPI_Send( ->MPI[%d] ). Last RetCODE == %d\n",
                 rank,
                 numtasks,
                 source,
                 dest,
                 rc
                 );
   }
   else
   if ( rank  == 3 ) {
        dest   = 2;
        source = 2;
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Send( ->MPI[%d] ) + MPI_Recv( <-MPI[%d] ). Last RetCODE == %d\n",
                 rank,
                 numtasks,
                 dest,
                 source,
                 rc
                 );
   }
   else {
        printf( "(INF) I am MPI[%d of %d] will NOP...\n",
                 rank,
                 numtasks
                 );

   }
   rc = MPI_Get_count( &Stat, MPI_CHAR, &count );
   /*
            Task  3: Received  1 char(s) from task 4197005 with a tag 0
            Task  2: Received  1 char(s) from task 4197005 with a tag 0
            Task  1: Received  1 char(s) from task 0       with a tag 1
            Task  0: Received  1 char(s) from task 1       with a tag 1                        */
   printf( "Task %d: Received %d char(s) from task %d with tag %d\n",
            rank,
            count,
            Stat.MPI_SOURCE,
            Stat.MPI_TAG
            );

   printf( "(INF) I am MPI[%d of %d]: will MPI_Finalize()...\n",
            rank,
            numtasks
            );
   MPI_Finalize();

   printf( "(INF) I am MPI[%d of %d]:      MPI_Finalize() done, will exit()...\n",
            rank,
            numtasks
            );
}

答案 2 :(得分:0)

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

int main (argc,argv)
int argc;
char *argv[]; {
int numtasks, rank, dest, source, rc, count, tag=1;
char inmsg, outmsg='x';
MPI_Status Stat;

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

if (rank%2 == 0)
{
dest=(rank+1)%numtasks;
source=(rank+1)%numtasks;

rc = MPI_Send(&outmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD);
rc = MPI_Recv(&inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat);
}

else {
dest = (rank-1+numtasks)%numtasks;
source = (rank-1+numtasks)%numtasks;
rc = MPI_Recv (&inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat);
rc = MPI_Send (&outmsg, 1, MPI_CHAR, dest,  tag, MPI_COMM_WORLD);
}

{
rc = MPI_Get_count (&Stat, MPI_CHAR, &count);
printf ("Task %d: Received %d char(s) from task %d with a tag %d \n", rank, count, Stat.MPI_SOURCE, Stat.MPI_TAG);
}
MPI_Finalize();