QMCPACK
Communicate.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2022 QMCPACK developers.
6 //
7 // File developed by: Ken Esler, kpesler@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Anouar Benali, benali@anl.gov, Argonne National Laboratory
10 // Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
11 // Cynthia Gu, zg1@ornl.gov, Oak Ridge National Laboratory
12 // Mark Dewing, markdewing@gmail.com, University of Illinois at Urbana-Champaign
13 // Peter Doak, doakpw@ornl.gov, Oak Ridge National Laboratory
14 // Alfredo A. Correa, correaa@llnl.gov, Lawrence Livermore National Laboratory
15 //
16 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
17 //////////////////////////////////////////////////////////////////////////////////////
18 
19 
20 #include "Communicate.h"
21 #include <iostream>
22 #include <sstream>
23 #include <string>
24 #include <cstdio>
25 #include <fstream>
26 #include "config.h"
27 #include "Utilities/FairDivide.h"
28 
29 #ifdef HAVE_MPI
30 #include "mpi3/shared_communicator.hpp"
31 #endif
32 
33 
34 //Global Communicator is created without initialization
36 
37 //default constructor: ready for a serial execution
38 Communicate::Communicate() : myMPI(MPI_COMM_NULL), d_mycontext(0), d_ncontexts(1), d_groupid(0), d_ngroups(1) {}
39 
40 Communicate::~Communicate() = default;
41 
42 //exclusive: MPI or Serial
43 #ifdef HAVE_MPI
44 
45  // in_comm needs to be mutable to be duplicated
46 Communicate::Communicate(mpi3::communicator& in_comm) : d_groupid(0), d_ngroups(1), comm{in_comm.duplicate()}
47 {
48  myMPI = comm.get();
49  d_mycontext = comm.rank();
50  d_ncontexts = comm.size();
51 }
52 
53 Communicate::Communicate(mpi3::communicator&& in_comm) : d_groupid(0), d_ngroups(1), comm{std::move(in_comm)}
54 {
55  myMPI = comm.get();
56  d_mycontext = comm.rank();
57  d_ncontexts = comm.size();
58 }
59 
60 Communicate::Communicate(const Communicate& in_comm, int nparts)
61 {
62  std::vector<int> nplist(nparts + 1);
63  int p = FairDivideLow(in_comm.rank(), in_comm.size(), nparts, nplist); //group
64  // comm is mutable member
65  comm = in_comm.comm.split(p, in_comm.rank());
66  myMPI = comm.get();
67  // TODO: mpi3 needs to define comm
68  d_mycontext = comm.rank();
69  d_ncontexts = comm.size();
70  d_groupid = p;
71  d_ngroups = nparts;
72  // create a communicator among group leaders.
73 
74  nplist.pop_back();
75  mpi3::communicator leader_comm = in_comm.comm.subcomm(nplist);
76  if (isGroupLeader())
77  GroupLeaderComm = std::make_unique<Communicate>(leader_comm);
78  else
79  GroupLeaderComm.reset();
80 }
81 
82 // For unit tests until they can be changed and this will be removed.
83 void Communicate::initialize(int argc, char** argv) {}
84 
86  // comm is mutable member
87  return Communicate{comm.split_shared()};
88 }
89 
91 {
92  static bool has_finalized = false;
93 
94  if (!has_finalized)
95  {
96  has_finalized = true;
97  }
98 }
99 
100 void Communicate::cleanupMessage(void*) {}
101 
102 void Communicate::abort() const { comm.abort(1); }
103 
104 void Communicate::barrier() const { comm.barrier(); }
105 #else
106 
107 void Communicate::initialize(int argc, char** argv) {}
108 
110 
112 
113 void Communicate::abort() const { std::_Exit(EXIT_FAILURE); }
114 
115 void Communicate::barrier() const {}
116 
118 
119 Communicate::Communicate(const Communicate& in_comm, int nparts)
120  : myMPI(MPI_COMM_NULL), d_mycontext(0), d_ncontexts(1), d_groupid(0)
121 {
122  GroupLeaderComm = std::make_unique<Communicate>();
123 }
124 #endif // !HAVE_MPI
125 
126 void Communicate::barrier_and_abort(const std::string& msg) const
127 {
128  if (!rank())
129  std::cerr << "Fatal Error. Aborting at " << msg << std::endl;
132 }
virtual ~Communicate()
destructor Call proper finalization of Communication library
void initialize(int argc, char **argv)
void barrier() const
int rank() const
return the rank
Definition: Communicate.h:116
int d_mycontext
Rank.
Definition: Communicate.h:218
void cleanupMessage(void *)
mpi_comm_type myMPI
Raw communicator.
Definition: Communicate.h:214
Communicate * Controller
Global Communicator for a process.
Definition: Communicate.cpp:35
int size() const
return the number of tasks
Definition: Communicate.h:118
void FairDivideLow(int ntot, int npart, IV &adist)
partition ntot elements among npart
Definition: FairDivide.h:114
Wrapping information on parallelism.
Definition: Communicate.h:68
A collection of functions for dividing fairly.
int d_ncontexts
Size.
Definition: Communicate.h:220
bool isGroupLeader()
return true if the current MPI rank is the group lead
Definition: Communicate.h:134
int d_ngroups
Total number of groups in the parent communicator.
Definition: Communicate.h:224
int d_groupid
Group ID of the current communicator in the parent communicator.
Definition: Communicate.h:222
Communicate NodeComm() const
provide a node/shared-memory communicator from current (parent) communicator
void abort() const
void finalize()
std::unique_ptr< Communicate > GroupLeaderComm
Group Leader Communicator.
Definition: Communicate.h:226
Communicate()
constructor
Definition: Communicate.cpp:38
void barrier_and_abort(const std::string &msg) const