2012-03-30 22 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初始化和终结。