2017-04-20 86 views
0

我想調用一個庫,該庫使用自身通過MPI並行運行的程序中的OpenMP並行化。如果我只使用一個進程來運行我的MPI程序,那麼當需要調用OpenMP庫時,會有7個附加線程(對應於我的機器上的核心數)正確生成,並且任務將並行執行。如果我在2個進程上運行我的MPI程序,並讓每個進程調用OpenMP程序,它們每個都會產生自己的線程,而不像以前一樣工作,從而使計算時間更長。在MPI程序中啓動OpenMP程序

我試圖讓MPI主進程在其他進程等待時調用OpenMP庫,但這些進程(物理內核)根本不參與OpenMP計算。

我必須告訴MPI程序它現在應該集體啓動OpenMP程序嗎?另一個複雜的事實是,我在具有多個節點的集羣上運行MPI程序。僅在包含MPI主進程的節點上啓動OpenMP程序纔是可以接受的。

具體來說,我的MPI程序是用Cython編寫的,並使用mpi4py。我使用MPICH作爲MPI實現,但希望這不重要。 OpenMP程序是用C編寫的,我通過Cython包裝器調用它。

+3

你的問題很混亂。標題提到了「OpenMP程序」,但是從文本中可以看出您正在調用使用OpenMP的庫函數。請澄清,因爲兩者都是非常不同的東西。 –

+0

您選擇的MPI很重要,因爲更廣泛使用的MPI選擇(至少在Linux上)提供了將OpenMP線程固定到獨立內核的自動方法。否則,OpenMP進程可能需要在單獨的節點上運行,除非您遇到了編寫腳本以設置親和性以及使用支持親緣關係的OpenMP的麻煩。 – tim18

+0

@HristoIliev我想我正在使用一個使用OpenMP的庫。 –

回答

0

我找到了解決方案。

對OpenMP庫的調用只能由單個MPI進程完成。在這次調用之後插入標準MPI屏障並不好,因爲這樣的屏障佔用了從屬進程的100%的CPU時間,不會爲OpenMP庫帶來額外的勞動力。相反,我們必須編寫自己的屏障功能,定期ping主進程以詢問OpenMP調用是否已完成。在兩個這樣的ping之間,從屬進程會在給定的時間間隔內休眠,這意味着它們可以自由地參與OpenMP計算。

這個邏輯的一個例子在Python中實現如下,希望具有明顯的變量名稱的含義。

def sleeping_barrier(sleep_time=0.1): 
    if master: 
     # Signal slaves to continue 
     for slave in range(1, nprocs): 
      isend(True, dest=slave) 
    else: 
     # Wait for master 
     while True: 
      sleep(sleep_time) 
      if iprobe(): 
       recv() # Remember to receive the message 
       break 

# Do OpenMP library call 
if master: 
    call_openmp_lib() 
sleeping_barrier()