2017-05-02 18 views
0

所以我得扔在一起這個簡單的MPI例子。我在測試boost :: mpi :: request時看到一些奇怪的行爲,我無法解釋。具體來說,如果您刪除了對第二個循環的評論,它將永遠旋轉。在boost :: mpi :: request上測試是否只返回true?如果是這樣,什麼狀態正在更新?我通過Boost的MPI和可選代碼進行了探索,但我無法解釋我所看到的。我對boost :: mpi :: request缺少什麼?測試似乎改變狀態

(當然,對於新手來說,你需要使用mpiexec的兩個節點,以這種自己跑。)

# include "stdafx.h" 
# include <boost/serialization/string.hpp> 
# include <boost/mpi.hpp> 
# include <windows.h> 
# include <iostream> 
# include <boost/mpi.hpp> 
# include <boost/optional.hpp> 

int main(int argc, char *argv[]); 

int main(int argc, char *argv[]) 

{ 
    boost::mpi::environment m_env; 
    boost::mpi::communicator m_world; 

    if (m_world.rank() == 0) 
    { 
     m_world.send(1,0, std::string("hi!")); 
    } 
    else 
    { 

     std::shared_ptr<std::string> rcv = std::shared_ptr<std::string>(new std::string()); 
     boost::mpi::request x = m_world.irecv(0, 0, *rcv); 
     while (!x.test()) 
     { 
      Sleep(10); 
     } 
     //while (!x.test()) 
     //{ 
     // Sleep(10); 
     //} 
     std::cout << *rcv; 
    } 
} 

回答

1

答案是在文檔中,排序:

/** 
    * Determine whether the communication associated with this request 
    * has completed successfully. If so, returns the @c status object 
    * describing the communication. Otherwise, returns an empty @c 
    * optional<> to indicate that the communication has not completed 
    * yet. Note that once @c test() returns a @c status object, the 
    * request has completed and @c wait() should not be called. 
    */ 
    optional<status> test(); 

然後看docs for the underlying MPI_Test function

到MPI_TEST調用返回flag = true,如果通過請求標識的操作完成。在這種情況下,狀態對象被設置爲包含關於完成的操作的信息;如果通信對象是由一個非阻塞發送創建或接收,那麼它被重新分配並且請求手柄設置爲MPI_REQUEST_NULL。

一個被允許調用MPI_TEST用空或不活動的請求的參數。在這種情況下,操作返回標誌=真和空狀態。

所以我們看到的是,升壓MPI的test()方法返回一個optional<status>,並MPI_Test()只能返回一個狀態一次(在此之後,該請求被破壞)。 MPI_Test()一再呼籲將返回flag = true,但是這不是你檢查什麼。如果你真的需要這種模式,你可以自己調用MPI_Test()並使用返回的標誌而不是狀態。或者只是在您的應用程序中進行簿記,並且不要在相同請求中撥打boost::mpi::request::test()兩次。

另一種方式來看待這個問題是您正在使用的test()結果在布爾上下文,你希望它像MPI_Test()flag工作,但實際上它的工作方式類似於status,並且它的布爾性質只是一種幻覺。

+0

是的,這就是我最終做的 - 只是書寫我自己的布爾。我沒有考慮底層的MPI_TEST - 謝謝 – Carbon

1

這與MPI標準是一致的。當MPI_TEST指示操作完成後,返回的狀態對象包含已完成操作的信息,操作對象本身被標記爲無效或取消分配(以適用者爲準)。在該操作對象上再次調用MPI_TEST將返回空狀態。

MPI標準(最新的版本)提供了一種方式來訪問非破壞性的方式狀態:MPI_REQUEST_GET_STATUS

我不知道在boost中執行此操作,但是您可以存儲返回的status對象,並在稍後引用該對象,而不是再次調用test