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. Это немного громоздко, но, по крайней мере, оно должно быть портативным.