使用电子围栏时,Openmpi会出现segfault错误

3

我正在尝试使用电子围栏来查找程序中的一些内存错误。我的程序使用OpenMPI,当我尝试运行它时,它会崩溃并显示以下回溯信息:

Program received signal SIGSEGV, Segmentation fault.
2001    ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S: No such file or directory.
__memcpy_ssse3_back () at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:2001
(gdb) bt
#0  __memcpy_ssse3_back ()
    at ../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:2001
#1  0x00007ffff72d6b7f in ompi_ddt_copy_content_same_ddt ()
   from /usr/lib/libmpi.so.0
#2  0x00007ffff72d4d0d in ompi_ddt_sndrcv () from /usr/lib/libmpi.so.0
#3  0x00007ffff72dd5b3 in PMPI_Allgather () from /usr/lib/libmpi.so.0
#4  0x00000000004394f1 in ppl::gvec<unsigned int>::gvec (this=0x7fffffffdd60, 
    length=1) at qppl/gvec.h:32
#5  0x0000000000434a35 in TreeBuilder::TreeBuilder (this=0x7fffffffdc60, 
    octree=..., mygbodytab=..., mylbodytab=..., cellpool=0x7fffef705fc8, 
---Type <return> to continue, or q <return> to quit---
    leafpool=0x7fffef707fc8, bodypool=0x7fffef6bdfc0) at treebuild.cxx:93
#6  0x000000000042fb6b in BarnesHut::BuildOctree (this=0x7fffffffde50)
    at barnes.cxx:155
#7  0x000000000042af52 in BarnesHut::Run (this=0x7fffffffde50)
    at barnes.cxx:386
#8  0x000000000042b164 in main (argc=1, argv=0x7fffffffe118) at barnes.cxx:435

我的代码中相关部分如下:

代码片段:

   me = spr_locale_id();
   world_size = spr_num_locales();
   my_elements = std::shared_ptr<T>(new T[1]);

   world_element_pointers = std::shared_ptr<T*>(new T*[world_size]);

   MPI_Allgather(my_elements.get(), sizeof(T*), MPI_BYTE,
       world_element_pointers.get(), sizeof(T*), MPI_BYTE,
       MPI_COMM_WORLD);

我不确定为什么__memcpy_ssse3_back会导致段错误。当我不使用电子围栏运行程序时,这部分程序不会发生段错误。有人知道发生了什么吗?我正在使用openmpi 1.4.3版本。


你的代码对我来说毫无意义 - 你从本地的my_elements数组发送了总共4或8个数据字节(取决于指针在你的架构中的大小),并将所有这些字节收集到一个指针数组中?!不过没关系,如果你能提供使用的Open MPI库的版本,那会有所帮助。 - Hristo Iliev
@HristoIliev 我更新了我的答案,包括我正在使用的OpenMPI版本。我在传递指针,因为我将来要进行RDMAs操作,最坏情况是每个人都必须知道其他人的起始地址。 - Kurtis Nusbaum
现在它更有意义了。这是旧版Open MPI中已知的错误 - 这里是票证。我建议您安装新版本的Open MPI或使用票证中的补丁来修补您的1.4.3版本。 - Hristo Iliev
@HristoIliev 你应该把那个发表为答案,这样我就可以标记为正确并给你信用。 - Kurtis Nusbaum
1个回答

4

出现错误的可能原因有两个:

第一个可能是数据复制例程中存在bug,这个问题在早期版本的Open MPI中存在,但在1.4.4版本中已经得到了解决。如果是这种情况,升级Open MPI库到新版本即可解决问题。

另一个可能的原因是,my_elements 是类型为 T 的单个项目数组。在 MPI_Allgather 调用中,您传递了指向此元素的指针,但指定发送的字节数为 sizeof(T*)。默认情况下,Electric Fence 将新分配的内存放置在内存页的末尾,然后立即插入一个无法访问的内存页。如果 T 比指针类型短(例如,Tint,并且您正在运行 64 位 LP64 平台),则会发生对无法访问的内存页的访问,从而导致段错误。由于您的意图实际上是发送数据的指针,则应将 MPI_Allgather 传递给指向 my_elements.get() 返回值的指针。
顺便说一下,传递指针并不是一件好事。MPI 提供了自己的可移植 RDMA 实现。请参阅 MPI 标准的One-sided Communications章节。这有点繁琐,但至少应该是可移植的。

1
问题在于我发送的是T*,而我需要发送的是T**。如果我的目的不是使用一种新的实验性RDMA,我完全可以使用MPI的RDMA :) 感谢您的所有帮助! - Kurtis Nusbaum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接