2012-03-30 136 views
3

我需要MPI世界通信器可以在函數/類成員函數中訪問。但通過設計/慣例,MPI環境和傳播者總是在int main()的開始處被定義和初始化。C++:MPI通信器作爲全局變量

我能想到的唯一的,簡單的解決方案使用全局指針傳播者。

有人知道更好的方法嗎?使用全局指針解決方案危險嗎?

這個問題同樣適用於裸機MPI,並提振:: MPI(其中下面我用),我所提出的解決方案的

例(未經測試):

//globals.h 
extern boost::mpi::communicator * my_MPI_world_ptr; 

//main.cpp 
... 
int main(int argc, char* argv[]) 
{   
    boost::mpi::environment my_boost_mpi_env(argc, argv); 
    boost::mpi::communicator my_MPI_world; 
    my_MPI_world_ptr = &my_MPI_world;  

    my_MPI_rank = my_MPI_world_ptr->rank(); 
    size_MPI_WORLD = my_MPI_world_ptr->size();  

    my_class an_Object; 
    an_Object.member_function_that_uses__MPI_world(); 
    ... 
} 

回答

1

你是指實際的MPI MPI_COMM_WORLD communicator(或它的Boost包裝)?這已經是全球性的。如果您使用不同的通信器將通信與正在編寫的庫分開,最好避免使用全局變量。在這種情況下,你可能只想傳遞它(或指向它的指針)並將其存儲在需要它的類中。

+0

我在談論boost的包裝器,它必須在'int main()'中定義。我想你是對的,'MPI_COMM_WORLD'已經是全球性的。 – cmo 2012-03-30 18:40:15

2

我不喜歡全局指針:誰負責刪除它們?如何確保在創建對象之前或在對象被銷燬之後不訪問指針?

我會試圖包裝指針和它的訪問類。 (警告:以下還沒有看到一個編譯器,可能有各種各樣的問題,我不熟悉MPI)

class CMPIwrapper 
{ 
public: 
    CMPIwrapper(boost::mpi::communicator& myMPIworld):myMPIworld_(myMPIworld){} 
    rank_type GetRank()const 
    { 
     return(my_MPI_world_ptr->rank()); 
    } 
private: 
    boost::mpi::communicator& myMPIworld_; 
};  

int main(int argc, char* argv[]) 
{   
    boost::mpi::environment my_boost_mpi_env(argc, argv); 
    boost::mpi::communicator my_MPI_world; 
    CMPIwrapper my_MPI_wrapper(my_MPI_world);  

    my_MPI_rank = CMPIwrapper.GetRank(); 
} 

是用來使用指針自己的對象能以相同的方式工作:它們的構造函數可以傳遞給你的boost :: mpi :: communicator的引用,或者如果boost :: mpi :: communicator的操作集定義良好,它們可以傳遞給包裝器的引用。

+0

好主意,但我的問題的全部目的是爲了避免操縱類接受溝通(雖然我沒有說,對不起)。 – cmo 2012-03-30 15:40:15

0
  1. 對於提升MPI,默認的構造(即空的初始化)通信對應MPI_COMM_WORLD,所以你可以簡單地定義另一

    mpi::communicator world; 
    

    自己的函數中使用它,就好像它是一個你外界定義。

  2. MPI_INIT在構建mpi::environment時被調用。因此,只要將它放置在主程序的開頭,就可以自由地在其他地方定義全局的mpi::communicator。沒有必要使用指針。 (其實你甚至可以把MPI_INIT也放在其他地方,見下文)。

  3. 對於純粹的MPI,我已經測試過在其他地方調用MPI_INIT除了main也是允許的。例如,您可以定義以下包裝器在頭文件中的全局工作人員,

    class MpiWorker_t 
        { 
        public: 
         int NumberOfWorkers, WorkerId, NameLen; 
         char HostName[MPI_MAX_PROCESSOR_NAME]; 
         MpiWorker_t() 
         { 
          MPI_Init(NULL, NULL); 
          MPI_Comm_size(MPI_COMM_WORLD,&NumberOfWorkers); 
          MPI_Comm_rank(MPI_COMM_WORLD,&WorkerId); 
          MPI_Get_processor_name(HostName, &NameLen); 
         } 
         ~MpiWorker_t() 
         { 
          MPI_Finalize(); 
         } 
        } 
    
        extern MpiWorker_t GlobalWorker; 
    

    ,並在源文件中,在任何地方定義之外main()全局實例:

    MpiWorker_t GlobalWorker; 
    

    建設並且全局變量的銷燬應該能夠在MPI函數調用之前和之後的MPI初始化和終結。