HavoqGT
environment.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, Lawrence Livermore National Security, LLC.
3  * Produced at the Lawrence Livermore National Laboratory.
4  * Written by Roger Pearce <rpearce@llnl.gov>.
5  * LLNL-CODE-644630.
6  * All rights reserved.
7  *
8  * This file is part of HavoqGT, Version 0.1.
9  * For details, see https://computation.llnl.gov/casc/dcca-pub/dcca/Downloads.html
10  *
11  * Please also read this link – Our Notice and GNU Lesser General Public License.
12  * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
13  *
14  * This program is free software; you can redistribute it and/or modify it under
15  * the terms of the GNU Lesser General Public License (as published by the Free
16  * Software Foundation) version 2.1 dated February 1999.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
19  * WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A
20  * PARTICULAR PURPOSE. See the terms and conditions of the GNU General Public
21  * License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License along
24  * with this program; if not, write to the Free Software Foundation, Inc.,
25  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26  *
27  * OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
28  *
29  * Our Preamble Notice
30  *
31  * A. This notice is required to be provided under our contract with the
32  * U.S. Department of Energy (DOE). This work was produced at the Lawrence
33  * Livermore National Laboratory under Contract No. DE-AC52-07NA27344 with the DOE.
34  *
35  * B. Neither the United States Government nor Lawrence Livermore National
36  * Security, LLC nor any of their employees, makes any warranty, express or
37  * implied, or assumes any liability or responsibility for the accuracy,
38  * completeness, or usefulness of any information, apparatus, product, or process
39  * disclosed, or represents that its use would not infringe privately-owned rights.
40  *
41  * C. Also, reference herein to any specific commercial products, process, or
42  * services by trade name, trademark, manufacturer or otherwise does not
43  * necessarily constitute or imply its endorsement, recommendation, or favoring by
44  * the United States Government or Lawrence Livermore National Security, LLC. The
45  * views and opinions of authors expressed herein do not necessarily state or
46  * reflect those of the United States Government or Lawrence Livermore National
47  * Security, LLC, and shall not be used for advertising or product endorsement
48  * purposes.
49  *
50  */
51 
52 #ifndef HAVOQGT_ENVIRONMENT_HPP_INCLUDED
53 #define HAVOQGT_ENVIRONMENT_HPP_INCLUDED
54 
55 #include <iostream>
56 #include <stdexcept>
57 #include <sstream>
58 #include <cstdlib>
59 #include <boost/lexical_cast.hpp>
60 
61 #include <havoqgt/error.hpp>
62 #include <havoqgt/mpi.hpp>
63 
64 namespace havoqgt {
70 public:
72  m_mailbox_num_irecv = get_env_var<uint32_t>("HAVOQGT_MAILBOX_NUM_IRECV", 8);
73  m_mailbox_num_isend = get_env_var<uint32_t>("HAVOQGT_MAILBOX_NUM_ISEND", 8);
74  m_mailbox_aggregation = get_env_var<uint32_t>("HAVOQGT_MAILBOX_AGGREGATION", 1024);
75  m_mailbox_tree_aggregation = get_env_var<uint32_t>("HAVOQGT_MAILBOX_TREE_AGGREGATION", 64);
76  m_mailbox_print_stats = get_env_var<bool> ("HAVOQGT_MAILBOX_PRINT_STATS", false);
77  }
78 
79  uint32_t mailbox_num_irecv() const { return m_mailbox_num_irecv; }
80  uint32_t mailbox_num_isend() const { return m_mailbox_num_isend; }
81  uint32_t mailbox_aggregation() const { return m_mailbox_aggregation; }
83  bool mailbox_print_stats() const { return m_mailbox_print_stats; }
84 
85  template <typename T>
86  inline T get_env_var(const char* key, T default_val) const;
87 
88  void print() const;
89 
90 private:
96 };
97 
98 inline void
100  std::cout << "HAVOQGT_MAILBOX_NUM_IRECV "<< " = " << m_mailbox_num_irecv << std::endl;
101  std::cout << "HAVOQGT_MAILBOX_NUM_ISEND "<< " = " << m_mailbox_num_isend << std::endl;
102  std::cout << "HAVOQGT_MAILBOX_AGGREGATION "<< " = " << m_mailbox_aggregation << std::endl;
103  std::cout << "HAVOQGT_MAILBOX_TREE_AGGREGATION "<< " = " << m_mailbox_tree_aggregation << std::endl;
104  std::cout << "HAVOQGT_MAILBOX_PRINT_STATS "<< " = " << m_mailbox_print_stats << std::endl;
105 }
106 
107 template <typename T>
108 inline
109 T
110 old_environment::get_env_var(const char* key, T default_val) const {
111  char* val = std::getenv( key );
112  if(val != NULL) {
113  try {
114  default_val = boost::lexical_cast<T>(val);
115  } catch (...) {
116  std::stringstream err;
117  err << "havoqgt::environment -- Unable to parse environment variable: "
118  << key << "=" << val << std::endl;
119  throw std::runtime_error(err.str());
120  }
121  }
122 
123  return default_val;
124 }
125 
126 inline
129  static old_environment env;
130  return env;
131 }
132 
133 
135 
136 class environment {
137 public:
138  environment(int *argc, char*** argv) {
139  // Init MPI
140  MPI_Init(argc, argv);
141 
142  // Create communicators
143  m_world_comm = communicator(MPI_COMM_WORLD);
144  MPI_Comm tmp_node_local_comm = split_node_local_comm(MPI_COMM_WORLD);
145  m_node_local_comm = communicator(tmp_node_local_comm);
146  MPI_Comm tmp_node_offset_comm = split_node_offset_comm(MPI_COMM_WORLD, tmp_node_local_comm);
147  m_node_offset_comm = communicator(tmp_node_offset_comm);
148  }
149 
152  MPI_Finalize();
153  }
154 
155  const communicator& world_comm() const { return m_world_comm; }
156  const communicator& node_local_comm() const { return m_node_local_comm; }
158 
159 private:
160 
162  {
163  MPI_Comm to_return;
164  int rank;
165  MPI_Comm_rank(world_comm, &rank);
166 
167  int color = 0;
168  char* cnodeid = NULL;//getenv("SLURM_NODEID");
169  char chostname[256];
170  gethostname(chostname, 256);
171  if(cnodeid) {
172  color = boost::lexical_cast<int>(cnodeid);
173  } else if(chostname) {
174  std::string shostname(chostname);
175  std::hash<std::string> hasher;
176  color = hasher(shostname);
177  if(color < 0) color *= -1;
178  }
179 
180  int key = rank;
181  int ret = MPI_Comm_split(world_comm, color, key, &to_return);
182 
183  int node_local_rank, node_local_size;
184  MPI_Comm_rank(to_return, &node_local_rank);
185  MPI_Comm_size(to_return, &node_local_size);
186 
187  if(rank < node_local_size)
188  {
189  if(rank != node_local_rank) {
190  std::cerr << "ERROR: Only blocked task mapping is supported" << std::endl; exit(-1);
191  }
192  }
193 
194 
195 
196  return to_return;
197  }
198 
199  MPI_Comm split_node_offset_comm(MPI_Comm world_comm, MPI_Comm node_local_comm)
200  {
201  MPI_Comm to_return;
202  int world_rank, node_local_rank;
203  MPI_Comm_rank(world_comm, &world_rank);
204  MPI_Comm_rank(node_local_comm, &node_local_rank);
205 
206  int color = node_local_rank;
207  int key = world_rank;
208 
209  int ret = MPI_Comm_split(world_comm, color, key, &to_return);
210 
211  return to_return;
212  }
213 
215  {
216 
217  }
218 
220  {
221  int world_rank, world_size, node_local_rank, node_local_size;
222  MPI_Comm_rank(world_comm, &world_rank);
223  MPI_Comm_size(world_comm, &world_size);
224  MPI_Comm_rank(node_local_comm, &node_local_rank);
225  MPI_Comm_size(node_local_comm, &node_local_size);
226 
227  }
228 
232 };
233 
234 
235 namespace detail {
237  static environment* penv;
238  return penv;
239  }
240 }
241 
243  return detail::priv_havoqgt_env();
244 }
245 
246 
247 inline void havoqgt_init( int *argc, char ***argv ) {
248  detail::priv_havoqgt_env() = new environment(argc, argv);
249 }
250 
251 inline void havoqgt_finalize() {
252  delete detail::priv_havoqgt_env();
253 }
254 
255 
256 
257 
258 
259 } //namespace havoqgt
260 
261 #endif
void barrier() const
Definition: mpi.hpp:621
bool is_node_mapping_round_robin(MPI_Comm world_comm, MPI_Comm node_local_comm)
communicator m_node_offset_comm
MPI_Comm split_node_offset_comm(MPI_Comm world_comm, MPI_Comm node_local_comm)
bool is_node_mapping_block(MPI_Comm world_comm, MPI_Comm node_local_comm)
Start 'new' environmet here.
void havoqgt_finalize()
uint32_t mailbox_num_irecv() const
Definition: environment.hpp:79
communicator m_node_local_comm
const communicator & world_comm() const
uint32_t mailbox_aggregation() const
Definition: environment.hpp:81
MPI_Comm split_node_local_comm(MPI_Comm world_comm)
environment(int *argc, char ***argv)
bool mailbox_print_stats() const
Definition: environment.hpp:83
environment * havoqgt_env()
communicator m_world_comm
uint32_t m_mailbox_tree_aggregation
Definition: environment.hpp:94
uint32_t mailbox_num_isend() const
Definition: environment.hpp:80
old_environment & get_environment()
const communicator & node_local_comm() const
const communicator & node_offset_comm() const
environment *& priv_havoqgt_env()
T get_env_var(const char *key, T default_val) const
void havoqgt_init(int *argc, char ***argv)
uint32_t mailbox_tree_aggregation() const
Definition: environment.hpp:82