MPI:如何确保子例程仅在默认节点上的一个处理器上执行?
MPI: How to ensure a subroutine is executed only on one processor on the default node?
我使用的是大规模并行化代码,对MPI本身是新手
我尝试 运行 来自 Fortran 的一组 shell 命令,因此,如果在多个处理器上完成,那将是完全浪费(并导致我的结果不正确)。
我找到的最相关的命令是 MPI_gather
和 MPI_reduce
,但这些似乎有问题,因为它们试图从其他处理器获取信息并在处理器上使用它们 0
, 但我没有从其他处理器调用的信息。
基本上我想做这样的事情:
if (MPI_node = 0 .and. MPI_process = 0) then
(execute a code)
end if
我最近遇到了这样的问题。我解决它的方法是使用 MPI_Comm_split 为每个节点创建一个通信器。像这样的东西(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;
}
当然你需要知道根节点的名称。
如果它在哪个节点上执行并不重要,那么我建议如下:
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
只会在一个节点上为真。
我使用的是大规模并行化代码,对MPI本身是新手
我尝试 运行 来自 Fortran 的一组 shell 命令,因此,如果在多个处理器上完成,那将是完全浪费(并导致我的结果不正确)。
我找到的最相关的命令是 MPI_gather
和 MPI_reduce
,但这些似乎有问题,因为它们试图从其他处理器获取信息并在处理器上使用它们 0
, 但我没有从其他处理器调用的信息。
基本上我想做这样的事情:
if (MPI_node = 0 .and. MPI_process = 0) then
(execute a code)
end if
我最近遇到了这样的问题。我解决它的方法是使用 MPI_Comm_split 为每个节点创建一个通信器。像这样的东西(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;
}
当然你需要知道根节点的名称。
如果它在哪个节点上执行并不重要,那么我建议如下:
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
只会在一个节点上为真。