2013-01-16 51 views
1

我試圖在使用電圍欄的程序中發現一些內存錯誤。我的程序使用的openmpi,當我嘗試運行它,它具有以下回溯出現segfaults:當使用電圍欄時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

+0

你的代碼對我來說毫無意義 - 你從本地'my_elements'數組總共發送4或8個數據字節(取決於你的體系結構中指針的大小),並將所有這些字節收集到一個數組中指針?!沒關係,如果您至少可以提供正在使用的Open MPI庫的版本,這將會有所幫助。 –

+0

@HristoIliev我已經更新了我的答案,以包含我使用的OpenMPI版本。我正在轉移我的指針,因爲我將在稍後進行RDMA,最壞的情況是每個人都必須知道其他人的起始地址。 –

+0

現在它變得更有意義。這是舊版Open MPI版本中的一個已知錯誤 - 這是[ticket](https://svn.open-mpi.org/trac/ompi/ticket/1903)。我建議你安裝一個較新版本的Open MPI,或者在門票中使用補丁來修補你的1.4.3版本。 –

回答

2

有對錯誤兩個可能的原因:

有一個在數據bug複製程序,出現在比較老的開放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章節。這有點麻煩,但它至少應該是便攜式的。

+1

問題是當我需要發送T **時,我正在發送T *。如果我的目的不是使用新的實驗型RDMA,我會完全使用MPI的RDMA :)感謝您的幫助! –