#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)
,行可能出错了答案 0 :(得分:0)
count
和Stat
仅在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)
不要犹豫尝试代码,因为它会帮助您掌握 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();