名为 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 也会有问题吗?

可能的线索:

&lt;sys/socket.h&gt; 中有一个connect() 函数,但我还没有在 MPI 头文件中找到它。 "ompi/mpi/cxx/intracomm.h" 中还有一个 Connect() 函数(带有大写 C),它间接包含在 &lt;mpi.h&gt; 中,但我认为大小写在 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 中的“发送计数”和“位移”参数?

如何在 Centos 7 中使用 firewalld 启用 MPI mpirun

MPI:如何启动三个将在不同线程中执行的函数

如何阻止信号到达自定义插槽

如何在运行时阻止forEach循环不执行两次?

MPI 中不同类型的点对点通信在性能方面有何不同?