Openmpi Segfault при использовании электрического забора

Я пытаюсь найти некоторые ошибки памяти в моей программе, использующей электрический забор. Моя программа использует 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 вызывает segfault. Эта часть программы не работает, когда я бегу без электрического забора. Кто-нибудь знает, что происходит? Я использую openmpi версии 1.4.3

1 ответ

Решение

Есть две возможные причины ошибки:

В подпрограммах копирования данных есть ошибка, присутствующая в более старых версиях Open MPI, которая, по-видимому, была исправлена ​​в версии 1.4.4. Если это так, то обновление библиотеки Open MPI до более новой версии решит проблему.

Другая возможная причина в том, что my_elements это массив одного элемента типа T, в MPI_Allgather при вызове вы передаете указатель на этот элемент, но вы указываете вместо sizeof(T*) как количество байтов для отправки. По умолчанию Electric Fence помещает вновь выделенную память в конец страницы памяти, а затем сразу же вставляет страницу недоступной памяти. Если T бывает короче, чем тип указателя (например, T является int и вы работаете на 64-битной платформе LP64), тогда появится доступ к странице недоступной памяти и, следовательно, к segfault. Поскольку вы намерены на самом деле отправить указатель на данные, то вы должны передать MPI_Allgather указатель на значение, возвращаемое my_elements.get() вместо.

Кстати, передача указателей вокруг не очень хорошая вещь. MPI обеспечивает собственную переносимую реализацию RDMA. См. Главу " Односторонние коммуникации" стандарта MPI. Это немного громоздко, но, по крайней мере, оно должно быть портативным.

Другие вопросы по тегам