C ++: MPI communicator as a global variable

I need an MPI world communicator to access the functions / functions of a class. But by design / convention of the environment, MPI and communicators are always defined and initialized at the beginning int main()

.

The only simple solution I can think of is using a global pointer to the communicator.

Does anyone know a better way? Is it dangerous to use a global pointer solution?

This problem applies equally well to barebone MPI and Boost :: MPI (which I use below)

An example of my suggested solution (untested):

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

      

and

//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();
   ...
}

      

+3


source to share


3 answers


Do you mean the actual MPI communicator MPI_COMM_WORLD

(or its Boost wrapper)? This is already global. If you are using a different communicator to share communication from the library you are writing, it would be best not to use a global variable at all. In this case, you can just pass it (or a pointer to it) and store it in the classes it needs.



+1


source


I don't like globals in general: who is responsible for deleting them? How do you ensure that the pointer is not available before the object is created or after the object is destroyed?

I would be tempted to wrap a pointer and its access in a class. (Warning: the following was not seen by the compiler, so all sorts of problems can occur and I am not familiar with 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();
}

      

Your own objects you used to use the pointer might work the same: their constructor might be passed a reference to your boost :: mpi :: communator, or if the set of operations on your boost :: mpi :: communator is well defined, they might be passed a reference on the wrapper.

+2


source


  • To increase the mpi, the default configured (i.e. empty initializer) communicator matches MPI_COMM_WORLD

    , so you can just define another

    mpi::communicator world;
    
          

    inside your function, use it as if it were listed outside.

  • MPI_INIT

    called at build mpi::environment

    . So while this is at the beginning of your main program, you can define the global mpi::communicator

    elsewhere. There is no need to use a pointer. (In fact, you can even post MPI_INIT

    elsewhere, see below).

  • For MPI with blue bones, I tested that calling MPI_INIT

    elsewhere than the main one is also allowed. For example, you can define the following wrapper for the global worker in the header file,

        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;
    
          

    and in your source file define a global instance anywhere outside main()

    :

      MpiWorker_t GlobalWorker;
    
          

    The construction and destruction of a global variable must be able to take care of initialization and completion MPI

    before and after any function call MPI

    .

0


source







All Articles