我是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();
}
答案 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