【问题标题】:MPI send receiveMPI 发送接收
【发布时间】:2018-03-12 13:52:00
【问题描述】:
#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 程序,我认为 if(rank%2==1)

【问题讨论】:

  • 考虑在问题中添加更多细节。
  • 这个问题恐怕说明你对MPI的基础知识或编程本身没有了解。你应该更密切地关注你的课程。 SO 不能替代教学。

标签: c parallel-processing tags mpi send


【解决方案1】:
    #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();

【讨论】:

  • 如果您运行奇数个 MPI 任务,这将死锁。此外,该模式不是环,而是成对交换。
【解决方案2】:

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);

【讨论】:

  • 严格来说,这可能无法回答这个问题,但它确实解释了先验不可理解的输出。我很乐意根据用户的说明更新我的答案。
  • 是的,我尝试使用环形模式,但可能我将 (rank+1)%numtasks 放在了错误的程序行,结果仍然错误..
  • 请用环形图案的代码更新您的问题
  • 或者提出一个新问题,因为现在的问题已经完全不同了。
  • destsource 在所有等级上必须具有相同的定义(它们目前在奇数和偶数等级上交换)。那么您可以使用MPI_Sendrecv(),这样无论排名如何,您都有一个唯一的路径。
【解决方案3】:

可能会尝试更好地研究 MPI 机制:

不要犹豫,尝试代码,因为它将帮助您掌握 numtasksrank-ID 的概念和相关的运行时操作.编译错误将在上面发布的代码中报告快捷方式。对于更多与 MPI 相关的实践和见解,还应该从各自的 MPI_&lt;fun&gt;()-calls 分配和评估 rc 返回码

问:为什么任务不能识别超过 2 个处理器?
答:可以,但是@987654325 @code-blocks 不允许其他人产生任何可见的输出。

问:我想将 4197005 结果更改为 2、3 - 如何?
答:无法更改 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
            );
}

【讨论】:

    猜你喜欢
    • 2018-12-04
    • 2017-03-04
    • 2013-04-15
    • 1970-01-01
    • 2012-08-24
    • 2018-07-21
    • 2013-12-20
    • 2018-08-30
    • 2016-06-15
    相关资源
    最近更新 更多