mpi_partition_set_custom.cpp
Go to the documentation of this file.
1 // Copyright 2019, University of Maryland and the MANGO development team.
2 //
3 // This file is part of MANGO.
4 //
5 // MANGO is free software: you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License as
7 // published by the Free Software Foundation, either version 3 of the
8 // License, or (at your option) any later version.
9 //
10 // MANGO is distributed in the hope that it will be useful, but
11 // WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with MANGO. If not, see
17 // <https://www.gnu.org/licenses/>.
18 
19 #include<iostream>
20 #include<mpi.h>
21 #include<stdexcept>
22 #include "mango.hpp"
23 
24 void mango::MPI_Partition::set_custom(MPI_Comm comm_world_in, MPI_Comm comm_group_leaders_in, MPI_Comm comm_worker_groups_in) {
25  // All processes should call this subroutine!
26 
27  int ierr;
28 
29  comm_world = comm_world_in;
30  comm_group_leaders = comm_group_leaders_in;
31  comm_worker_groups = comm_worker_groups_in;
32 
33  // Get the information about the world communicator.
34  ierr = MPI_Comm_size(comm_world, &N_procs_world);
35  if (ierr != 0) throw std::runtime_error("Error with the supplied mpi_comm_world in mango::MPI_Partition::set_custom.");
36  ierr = MPI_Comm_rank(comm_world, &rank_world);
37  proc0_world = (rank_world == 0);
38 
39  // Get the information about the worker_groups communicator.
40  MPI_Comm_rank(comm_worker_groups, &rank_worker_groups);
41  if (ierr != 0) throw std::runtime_error("Error with the supplied mpi_comm_worker_groups in mango::MPI_Partition::set_custom.");
42  MPI_Comm_size(comm_worker_groups, &N_procs_worker_groups);
43  proc0_worker_groups = (rank_worker_groups == 0);
44 
45  // Get the information about the group_leaders communicator.
46  if (proc0_worker_groups) {
47  MPI_Comm_rank(comm_group_leaders, &rank_group_leaders);
48  if (ierr != 0) throw std::runtime_error("Error with the supplied mpi_comm_group_leaders in mango::MPI_Partition::set_custom.");
49  MPI_Comm_size(comm_group_leaders, &N_procs_group_leaders);
50  } else {
51  // We are not allowed to query the rank from procs that are not members of comm_group_leaders.
52  rank_group_leaders = -1;
53  N_procs_group_leaders = -1;
54  }
55 
56  // Determine how many worker groups there are.
57  N_worker_groups = (proc0_worker_groups ? 1 : 0);
58  MPI_Allreduce(MPI_IN_PLACE, &N_worker_groups, 1, MPI_INT, MPI_SUM, comm_world);
59 
60  // Determine which worker group each processor is in.
61  worker_group = rank_group_leaders; // We'll say the worker group corresponds to the rank of the corresponding master proc in comm_group_leaders.
62  MPI_Bcast(&worker_group, 1, MPI_INT, 0, comm_worker_groups);
63 
64  print();
65  initialized = true;
66 }
mango::MPI_Partition::set_custom
void set_custom(MPI_Comm comm_world, MPI_Comm comm_group_leaders, MPI_Comm comm_worker_groups)
Use a user-supplied partitioning of the MPI processes into worker groups.
Definition: mpi_partition_set_custom.cpp:24
mango.hpp