MPI 程序在 MPI_Recv 期间冻结
MPI program freezing during MPI_Recv
我是 MPI 并行编程的初学者。我写了这段代码来绘制 Mandelbrot 分形。这个想法是第一个从节点计算前半部分,将其粘贴在一个指针中,并将其发送给等待接收指针的主节点。第二个节点也会发生同样的事情。最后,主节点应该将结果保存在 2 个不同的变量中,并将它们写入一个文件中。
......
if((itertab=malloc((sizeof(int)*sizebuffre))) == NULL) {
printf("ERREUR , errno : %d (%s) .\n",errno,strerror(errno));
return EXIT_FAILURE;
}
int rank, size,start,end;
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
MPI_Status st;
/*allocation du tableau de pixel*/
if (rank==1) {
xpixel = 0;
end = (nbpixelx/MACHINE_NUM);
Calcule(xpixel,end);
printf("rank 1 start : %d, end : %d\n",xpixel,end);
MPI_Send(&itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);
free(itertab);
printf("work done : i am rank 1 \n");
}
if (rank==2) {
xpixel = (nbpixelx/MACHINE_NUM);
end = nbpixelx;
Calcule(xpixel,end);
printf("rank 2 start : %d, end : %d\n",xpixel,end);
MPI_Send(&itertab,sizebuffre,MPI_INT,0,6,MPI_COMM_WORLD);
printf("work done : i am rank 2 \n");
free(itertab);
}
if (rank==0) {
if((itertabA=malloc((sizeof(int)*sizebuffre))) == NULL) {
printf("ERREUR d'allocation de itertabA, errno : %d (%s) .\n",errno,strerror(errno));
return EXIT_FAILURE;
}
if((itertabB=malloc((sizeof(int)*sizebuffre))) == NULL) {
printf("ERREUR d'allocation de itertabB, errno : %d (%s) .\n",errno,strerror(errno));
return EXIT_FAILURE;
}
printf("test before reciving result from first slave\n");
MPI_Recv(itertabA,sizebuffre,MPI_INT,1,5,MPI_COMM_WORLD,&st);
printf("result recived rank 1 \n");
MPI_Recv(itertabB,sizebuffre,MPI_INT,2,6,MPI_COMM_WORLD,&st);
printf("result recived rank 2 \n");
}
MPI_Finalize();
return EXIT_SUCCESS;
}
问题是我的代码在master收到first slave的结果那一行卡住了,但我不知道为什么?
我尝试调试结果。我添加了一些 printf 以查看它冻结的位置。这是结果:
test before reciving result from first slave
test in calcule function
trairment xpixel 0
trairment xpixel 1
trairment xpixel 2
...snip...
trairment xpixel 399
test after the end off calculating loop
rank 1 start : 0, end : 400
^C
您的 MPI 代码无法正常工作,因为您向 MPI_Send
传递了错误的参数。您的变量 itertab
已经是指向数据缓冲区的指针,因此您不需要再次取消引用它。
而不是:
MPI_Send(&itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);
做:
MPI_Send(itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);
另一个问题是您在 Calcule
函数和输出循环中访问未分配的内存。在 Calcule
函数中,您正在写入 itertab[xpixel*nbpixely+ypixel]=iter
。这对于进程 2
将失败,因为它只分配 itertab
缓冲区的本地部分。您需要减去 xpixel
.
的偏移量
在输出循环中,您正在使用全局索引读取 itertabB
。在这里,您还应该减去 xpixel
的偏移量,如下所示:
fprintf(file,"%f %f %d\n", x, y,itertabB[(xpixel-(nbpixelx/MACHINE_NUM))*nbpixely+ypixel]);
我是 MPI 并行编程的初学者。我写了这段代码来绘制 Mandelbrot 分形。这个想法是第一个从节点计算前半部分,将其粘贴在一个指针中,并将其发送给等待接收指针的主节点。第二个节点也会发生同样的事情。最后,主节点应该将结果保存在 2 个不同的变量中,并将它们写入一个文件中。
......
if((itertab=malloc((sizeof(int)*sizebuffre))) == NULL) {
printf("ERREUR , errno : %d (%s) .\n",errno,strerror(errno));
return EXIT_FAILURE;
}
int rank, size,start,end;
MPI_Init (&argc, &argv); /* starts MPI */
MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */
MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */
MPI_Status st;
/*allocation du tableau de pixel*/
if (rank==1) {
xpixel = 0;
end = (nbpixelx/MACHINE_NUM);
Calcule(xpixel,end);
printf("rank 1 start : %d, end : %d\n",xpixel,end);
MPI_Send(&itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);
free(itertab);
printf("work done : i am rank 1 \n");
}
if (rank==2) {
xpixel = (nbpixelx/MACHINE_NUM);
end = nbpixelx;
Calcule(xpixel,end);
printf("rank 2 start : %d, end : %d\n",xpixel,end);
MPI_Send(&itertab,sizebuffre,MPI_INT,0,6,MPI_COMM_WORLD);
printf("work done : i am rank 2 \n");
free(itertab);
}
if (rank==0) {
if((itertabA=malloc((sizeof(int)*sizebuffre))) == NULL) {
printf("ERREUR d'allocation de itertabA, errno : %d (%s) .\n",errno,strerror(errno));
return EXIT_FAILURE;
}
if((itertabB=malloc((sizeof(int)*sizebuffre))) == NULL) {
printf("ERREUR d'allocation de itertabB, errno : %d (%s) .\n",errno,strerror(errno));
return EXIT_FAILURE;
}
printf("test before reciving result from first slave\n");
MPI_Recv(itertabA,sizebuffre,MPI_INT,1,5,MPI_COMM_WORLD,&st);
printf("result recived rank 1 \n");
MPI_Recv(itertabB,sizebuffre,MPI_INT,2,6,MPI_COMM_WORLD,&st);
printf("result recived rank 2 \n");
}
MPI_Finalize();
return EXIT_SUCCESS;
}
问题是我的代码在master收到first slave的结果那一行卡住了,但我不知道为什么?
我尝试调试结果。我添加了一些 printf 以查看它冻结的位置。这是结果:
test before reciving result from first slave
test in calcule function
trairment xpixel 0
trairment xpixel 1
trairment xpixel 2
...snip...
trairment xpixel 399
test after the end off calculating loop
rank 1 start : 0, end : 400
^C
您的 MPI 代码无法正常工作,因为您向 MPI_Send
传递了错误的参数。您的变量 itertab
已经是指向数据缓冲区的指针,因此您不需要再次取消引用它。
而不是:
MPI_Send(&itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);
做:
MPI_Send(itertab,sizebuffre,MPI_INT,0,5,MPI_COMM_WORLD);
另一个问题是您在 Calcule
函数和输出循环中访问未分配的内存。在 Calcule
函数中,您正在写入 itertab[xpixel*nbpixely+ypixel]=iter
。这对于进程 2
将失败,因为它只分配 itertab
缓冲区的本地部分。您需要减去 xpixel
.
在输出循环中,您正在使用全局索引读取 itertabB
。在这里,您还应该减去 xpixel
的偏移量,如下所示:
fprintf(file,"%f %f %d\n", x, y,itertabB[(xpixel-(nbpixelx/MACHINE_NUM))*nbpixely+ypixel]);