Rheolef  7.1
an efficient C++ finite element environment
environment.cc
Go to the documentation of this file.
1 // boost::mpi::environment-like interface, with thread options for scotch lib
22 
23 #include "rheolef/distributed.h"
24 #ifndef _RHEOLEF_HAVE_MPI
25 
26 namespace rheolef {
27 
28 environment::environment (int& argc, char**& argv, const environment_option_type& opt)
29  : _oldcw(0)
30 {
31 }
32 environment::~environment()
33 {
34 }
35 
36 } // namespace rheolef
37 
38 #else // _RHEOLEF_HAVE_MPI
39 
40 // support MPI-2 (with warnings, but changed to error by the compiler flags)
41 #ifdef MPI_VERSION
42 # if (MPI_VERSION >= 2)
43 # ifndef MPI_Errhandler_set
44 # define MPI_Errhandler_set MPI_Comm_set_errhandler
45 # endif
46 # ifndef MPI_Attr_get
47 # define MPI_Attr_get MPI_Comm_get_attr
48 # endif
49 # endif
50 #endif
51 
52 namespace rheolef {
53 
55  int flag;
56  MPI_Initialized(&flag);
57  return flag != 0;
58 }
60  int flag;
61  MPI_Finalized(&flag);
62  return flag != 0;
63 }
64 environment::environment (int& argc, char**& argv, const environment_option_type& opt)
65  : _rheolef_has_init(false), _oldcw(0)
66 {
67  if (!initialized()) {
68  int status = 0;
70  status = MPI_Init (&argc, &argv);
71  } else {
72  int obtained_thread_level;
73  status = MPI_Init_thread (&argc, &argv, opt.thread_level, &obtained_thread_level);
74  if (obtained_thread_level != opt.thread_level) {
75  warning_macro ("mpi_init: obtained thread level="<<obtained_thread_level <<" while asking for thread level="<<opt.thread_level);
76  }
77  }
78  check_macro (status == MPI_SUCCESS, "mpi init failed");
79  }
80  if (!_rheolef_has_init) {
81 #ifdef _RHEOLEF_HAVE_OBSOLETE_MPI_V1
82  MPI_Errhandler_set (MPI_COMM_WORLD, MPI_ERRORS_RETURN);
83 #else
84  MPI_Comm_set_errhandler (MPI_COMM_WORLD, MPI_ERRORS_RETURN);
85 #endif
86  _rheolef_has_init = true;
87  }
88 }
90 {
91  if (_rheolef_has_init && !finalized()) {
92  boost::mpi::detail::mpi_datatype_cache().clear();
93  MPI_Finalize();
94  }
95 }
96 void environment::abort(int errcode)
97 {
98  MPI_Abort(MPI_COMM_WORLD, errcode);
99 }
101 {
102  int* max_tag_value;
103  int found = 0;
104  MPI_Attr_get(MPI_COMM_WORLD, MPI_TAG_UB, &max_tag_value, &found);
105  assert_macro (found != 0, "MPI_Attr_get: error");
106  return *max_tag_value - _num_reserved_tags;
107 }
109 {
110  return max_tag() + 1;
111 }
112 boost::optional<int> environment::host_rank()
113 {
114  int* host;
115  int found = 0;
116  MPI_Attr_get(MPI_COMM_WORLD, MPI_HOST, &host, &found);
117  if (!found || *host == MPI_PROC_NULL) {
118  return boost::optional<int>();
119  } else {
120  return *host;
121  }
122 }
123 boost::optional<int> environment::io_rank()
124 {
125  int* io;
126  int found = 0;
127  MPI_Attr_get(MPI_COMM_WORLD, MPI_IO, &io, &found);
128  if (!found || *io == MPI_PROC_NULL) {
129  return boost::optional<int>();
130  } else {
131  return *io;
132  }
133 }
135 {
136  char name[MPI_MAX_PROCESSOR_NAME];
137  int len;
138  MPI_Get_processor_name(name, &len);
139  return std::string(name, len);
140 }
141 
142 } // namespace rheolef
143 #endif // _RHEOLEF_HAVE_MPI
static std::string processor_name()
Definition: environment.cc:134
static bool initialized()
Definition: environment.cc:54
static boost::optional< int > io_rank()
Definition: environment.cc:123
environment(int &argc, char **&argv, const environment_option_type &opt=environment_option_type())
Definition: environment.cc:64
static boost::optional< int > host_rank()
Definition: environment.cc:112
static void abort(int errcode)
Definition: environment.cc:96
static int max_tag()
Definition: environment.cc:100
static bool finalized()
Definition: environment.cc:59
static int collectives_tag()
Definition: environment.cc:108
#define assert_macro(ok_condition, message)
Definition: dis_macros.h:113
#define warning_macro(message)
Definition: dis_macros.h:53
check_macro(expr1.have_homogeneous_space(Xh1), "dual(expr1,expr2); expr1 should have homogeneous space. HINT: use dual(interpolate(Xh, expr1),expr2)")
This file is part of Rheolef.