使用电围栏时的Openmpi段错误

时间:2013-01-16 21:07:08

标签: segmentation-fault mpi openmpi electric-fence

我正在尝试使用电围栏在我的程序中找到一些内存错误。我的程序使用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版

1 个答案:

答案 0 :(得分:2)

错误有两个可能的原因:

数据复制例程中有一个bug,存在于早期的Open MPI版本中,似乎已在1.4.4版本中修复。如果是这种情况,将Open MPI库升级到更新版本将解决问题。

另一个可能的原因是my_elementsT类型的单个项目的数组。在MPI_Allgather调用中,您传递了一个指向此元素的指针,但您指定sizeof(T*)作为要发送的字节数。默认情况下,Electric Fence将新分配的内存放在内存页的末尾,然后立即插入一个不可访问的内存页。如果T恰好比指针类型短(例如Tint并且您在64位LP64平台上运行),则会发生对无法访问的内存页面的访问,因此,段错误。由于您的目的是实际发送指向数据的指针,因此您应该将MPI_Allgather指针传递给my_elements.get()返回的值。

顺便说一句,传递指针并不是一件好事。 MPI提供自己的便携式RDMA实现。请参阅MPI标准的One-sided Communications章节。它有点麻烦,但至少应该是便携式的。