MPI连续类型示例给出了致命错误

时间:2014-03-19 13:36:26

标签: c mpi

我是MPI的初学者,我正在关注此链接以了解:https://computing.llnl.gov/tutorials/mpi/#Derived_Data_Types。在本节的最后,有一个例子。我在这里添加了代码。区别仅在于第30行和第33行中的两个printf函数。

问题是代码不起作用。它提供Fatal error,以便:

MPI_Send(173): MPI_Send(buf=0x7fff20072940, count=1, dtype=USER<contig>, dest=4, tag=1, 
MPI_COMM_WORLD) failed
MPI_Send(98).: Invalid rank has value 4 but must be nonnegative and less than 4

我认为它试图发送处理器4,但它不存在。它为什么这样做? 此外,当我删除printf函数时,程序没有显示任何内容,我只看到命令行的光标。

我用以下代码编译它:

mpicc mpi_contigous_data.cpp -o contigous_type

我用:

运行它
mpirun -np 4 ./contigous_type

代码在这里:

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

#define SIZE 4

int main (int argc, char *argv[])
{
int numtasks, rank, source=0, dest, tag=1, i;
float a[SIZE][SIZE] =
  {1.0, 2.0, 3.0, 4.0,
   5.0, 6.0, 7.0, 8.0,
   9.0, 10.0, 11.0, 12.0,
   13.0, 14.0, 15.0, 16.0};
float b[SIZE];

MPI_Status stat;
MPI_Datatype rowtype;

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

MPI_Type_contiguous(SIZE, MPI_FLOAT, &rowtype);
MPI_Type_commit(&rowtype);

if (numtasks == SIZE) {
 if (rank == 0) {
  for (i=0; i<numtasks; i++)
   printf("From root, sending to %d\n",i);
   MPI_Send(&a[i][0], 1, rowtype, i, tag, MPI_COMM_WORLD);
 }
printf("My rank is %d,waiting message\n",rank);
MPI_Recv(b, SIZE, MPI_FLOAT, source, tag, MPI_COMM_WORLD, &stat);
printf("rank= %d  b= %3.1f %3.1f %3.1f %3.1f\n",
     rank,b[0],b[1],b[2],b[3]);
}
else
 printf("Must specify %d processors. Terminating.\n",SIZE);

MPI_Type_free(&rowtype);
MPI_Finalize();
}

2 个答案:

答案 0 :(得分:0)

请记住,排名编号从0开始。所以,如果你这样开始你的程序:

mpirun -np 4 ./contigous_type

你的等级将是0,1,2,3。没有4。

更具体地针对您的问题,您需要在第29行的for循环周围添加花括号。您将执行print语句4次,MPI_Send执行一次。使用一个好的编辑器会自动为你提供帮助。

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

#define SIZE 4

int main (int argc, char *argv[])
{
int numtasks, rank, source=0, dest, tag=1, i;
float a[SIZE][SIZE] =
  {1.0, 2.0, 3.0, 4.0,
   5.0, 6.0, 7.0, 8.0,
   9.0, 10.0, 11.0, 12.0,
   13.0, 14.0, 15.0, 16.0};
float b[SIZE];

MPI_Status stat;
MPI_Datatype rowtype;

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

MPI_Type_contiguous(SIZE, MPI_FLOAT, &rowtype);
MPI_Type_commit(&rowtype);

if (numtasks == SIZE) {
 if (rank == 0) {
  for (i=0; i<numtasks; i++) { /*<--- HERE!*/
   printf("From root, sending to %d\n",i);
   MPI_Send(&a[i][0], 1, rowtype, i, tag, MPI_COMM_WORLD);
  } /*<--- HERE!*/
 }
printf("My rank is %d,waiting message\n",rank);
MPI_Recv(b, SIZE, MPI_FLOAT, source, tag, MPI_COMM_WORLD, &stat);
printf("rank= %d  b= %3.1f %3.1f %3.1f %3.1f\n",
     rank,b[0],b[1],b[2],b[3]);
}
else
 printf("Must specify %d processors. Terminating.\n",SIZE);

MPI_Type_free(&rowtype);
MPI_Finalize();
}

但您的代码中还有很多其他问题。我不打算在这里修复所有这些,因为这对你没有多大帮助。最明显的是你的发送和接收不匹配。您有每个进程发送4条消息但只接收一条消息。

答案 1 :(得分:0)

我更改了代码以获得预期的结果。我更改了发送和接收到非阻塞版本。这是https://computing.llnl.gov/tutorials/mpi/#Derived_Data_Types中示例的最后一个版本。

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

#define SIZE 4

int main (int argc, char *argv[]) {
int numtasks, rank, source=0, dest, tag=1, i;
float a[SIZE][SIZE] =
     {1.0, 2.0, 3.0, 4.0,
      5.0, 6.0, 7.0, 8.0,
      9.0, 10.0, 11.0, 12.0,
      13.0, 14.0, 15.0, 16.0};
float b[SIZE];

MPI_Status stat[SIZE];
MPI_Request send_req[SIZE], recv_req[SIZE];
MPI_Datatype rowtype;

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

MPI_Type_contiguous(SIZE, MPI_FLOAT, &rowtype);
MPI_Type_commit(&rowtype);

if (numtasks == SIZE) {
  if (rank == 0) {
   for (i=0; i<numtasks; i++) {
   printf("From root, sending to %d\n",i);
   // MPI_Send was changed to non-blocking version
   MPI_Isend(&a[i][0], 1, rowtype, i, tag, MPI_COMM_WORLD,&send_req[i]);
 }
// root waits until sending all messages
MPI_Waitall(numtasks-1,&send_req[1],&stat[1]);
 }
// I changed MPI_Recv to non-blocking version
MPI_Irecv(&b, SIZE, MPI_FLOAT, source, tag, MPI_COMM_WORLD, &recv_req[0]);
// A processor also waits for request to end
MPI_Wait(&recv_req[0],&stat[0]);
printf("rank= %d  b= %3.1f %3.1f %3.1f %3.1f\n",
 rank,b[0],b[1],b[2],b[3]); }
else
 printf("Must specify %d processors. Terminating.\n",SIZE);

MPI_Type_free(&rowtype);
MPI_Finalize(); }

我编译并运行:

mpicc mpi_contigous_data.cpp -o contigous_type
mpirun -np 4 ./contigous_type

结果如下:

From root, sending to 0
From root, sending to 1 
From root, sending to 2
From root, sending to 3
rank= 1  b= 5.0 6.0 7.0 8.0
rank= 2  b= 9.0 10.0 11.0 12.0
rank= 3  b= 13.0 14.0 15.0 16.0
rank= 0  b= 1.0 2.0 3.0 4.0