mathishard.butweloveit
mathishard.butweloveit

Reputation: 125

MPI: How to ensure a subroutine is executed only on one processor on the default node?

I use a large-scale parallelized code, and I am new to MPI itself.

I try to run a set of shell commands from Fortran, and hence it would be entirely wasteful (and cause my results to be incorrect) if done on more than one processor.

The most relevant commands I have found are MPI_gather and MPI_reduce, but these seem problematic, because they are trying to take information from other processors and use them on the processor 0, but I have no information that I am calling from other processors.

Basically I want to do something like this :

if (MPI_node = 0 .and. MPI_process = 0) then
   (execute a code)
end if

Upvotes: 0

Views: 921

Answers (1)

wvn
wvn

Reputation: 675

I recently had an issue like this. The way I solved it was to use MPI_Comm_split to create a communicator for each node. Something like this (C++):

char node_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
int processor_hash_id;

int global_proc_id;
int global_proc_num;

int node_proc_id;
int node_proc_num;

MPI_Comm node_comm;

//Get global info
MPI_Comm_rank(MPI_COMM_WORLD, &global_proc_id);
MPI_Comm_size(MPI_COMM_WORLD, &global_proc_num);
MPI_Get_processor_name(node_name, &name_len);

//Hash the node name
processor_hash_id = get_hash_id(node_name);

//Make a new communicator for processes only on the node
// and get node info
MPI_Comm_split(MPI_COMM_WORLD, processor_hash_id, global_proc_id, &node_comm);
MPI_Comm_rank(node_comm, &node_proc_id);
MPI_Comm_size(node_comm, &node_proc_num);

//Now, if you know the name of the "root node" to execute shell commands on:
if (node_proc_id==0 && processor_hash_id == get_hash_id("name-of-root-node"))
{
    //do whatever
}

//Some hash function
int get_hash_id(const char* s)
{
    int h = 37;
    while (*s)
    {
        h = (h * 54059) ^ (s[0] * 76963);
        s++;
    }
    return h;
}

Of course you will need to know the name of the root node.

If it doesn't matter what node it executes on, then I would suggest the following:

int global_proc_id;
int global_proc_num;

//Get global info
MPI_Comm_rank(MPI_COMM_WORLD, &global_proc_id);
MPI_Comm_size(MPI_COMM_WORLD, &global_proc_num);

if (global_proc_id==0)
{
    //do whatever
}

global_proc_id==0 will only be true on one node.

Upvotes: 1

Related Questions