名为 connect() 的函数如何阻止 MPI C 程序运行?
Posted
技术标签:
【中文标题】名为 connect() 的函数如何阻止 MPI C 程序运行?【英文标题】:How does function named connect() prevent MPI C program from running? 【发布时间】:2015-07-25 07:19:47 【问题描述】:我正在为并行编程课程编写一个使用 MPI 的项目,并决定将我的一个函数命名为 connect()
。但每当我尝试mpirun
程序(在Linux 和OS X 上使用最新版本的Open MPI)时,我都会收到connect()
函数的输出,即使我没有从main()
调用connect()
;此外,main()
的某些输出也不会出现。
这是一个有问题的简化程序:
#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>
void connect(); //function name breaks mpi
int main(void)
int comm_sz, my_rank;
MPI_Init(NULL, NULL);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
printf("my_rank is %d\n", my_rank);
fflush(stdout);
MPI_Finalize();
return EXIT_SUCCESS;
void connect()
printf("\nNot main! \n");
return;
和输出:
[me@host ~]$ mpicc bad.c -Wall
[me@host ~]$ mpirun -n 1 a.out
Not main!
--------------------------------------------------------------------------
orterun noticed that process rank 0 with PID 17245 on node host exited on signal 13 (Broken pipe).
--------------------------------------------------------------------------
一开始我正要在 Stack Overflow 上询问问题出在哪里,直到我发现重命名函数可以解决问题。所以我现在很好奇的是为什么将函数命名为connect()
会阻止程序正常运行。 mpirun
/Open RTE 也会有问题吗?
可能的线索:
<sys/socket.h>
中有一个connect()
函数,但我还没有在 MPI 头文件中找到它。
"ompi/mpi/cxx/intracomm.h"
中还有一个 Connect()
函数(带有大写 C),它间接包含在 <mpi.h>
中,但我认为大小写在 C/C++ 中很重要,它看起来像是 C++ 类的方法。
如果我尝试像正常程序一样执行该程序,它在 OS X 上运行时可以工作,但在 Linux 上却不行:
mac:~ me$ ./a.out
my_rank is 0
对
[me@linux ~]$ ./a.out
Not main!
【问题讨论】:
【参考方案1】:我猜你调用的 MPI 函数之一是依次调用 connect()
系统调用。但由于 ELF 可执行文件具有符号的平面命名空间,因此您的 connect()
将被调用。
这个问题在 Mac OS 上不会发生,因为 Mach-O 库有一个两级命名空间,所以不同库中的符号不会相互冲突。
如果你将你的函数设为静态,那也可能会避免这个问题。
【讨论】:
命名空间万岁! 我假设main()
函数没有被调用,但在检查了这个建议之后,它似乎总是被调用;我将在 MPI 函数之前和之间添加更多 printf()
以至少识别第一个有问题的函数。此外,静态建议有效。有没有办法进一步调查connect()
系统调用是否确实被调用,或者以其他方式识别命名空间冲突?
作为 Open MPI 的作者之一,我将确认 +elbows 提供的答案是正确的:Open MPI 使用了 connect(2) 系统调用。当您有一个名为 connect(2) 的公共函数(可能是 MPI_Init 的一部分)时,链接器最终会调用 your connect() 函数而不是 connect(2)。坏事从那里发生。以上是关于名为 connect() 的函数如何阻止 MPI C 程序运行?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确设置 MPI_scatterv 中的“发送计数”和“位移”参数?