MAiNGO
mpiUtilities.h
Go to the documentation of this file.
1 /**********************************************************************************
2  * Copyright (c) 2019 Process Systems Engineering (AVT.SVT), RWTH Aachen University
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License 2.0 which is available at
6  * http://www.eclipse.org/legal/epl-2.0.
7  *
8  * SPDX-License-Identifier: EPL-2.0
9  *
10  * @file mpiUtilities.h
11  *
12  * @brief File containing macros and utility functions for parallel MAiNGO version.
13  *
14  **********************************************************************************/
15 
16 #pragma once
17 
18 #ifdef HAVE_MAiNGO_MPI
19 #include "babNode.h"
20 #include "mpi.h"
21 
22 #define MAiNGO_IF_BAB_MANAGER if (_rank == 0) {
23 #define MAiNGO_IF_BAB_WORKER if (_rank != 0) {
24 #define MAiNGO_ELSE \
25  } \
26  else \
27  {
28 #define MAiNGO_END_IF }
29 
30 #define MAiNGO_MPI_BARRIER MPI_Barrier(MPI_COMM_WORLD);
31 #define MAiNGO_MPI_FINALIZE MPI_Finalize();
32 #else
33 #define MAiNGO_IF_BAB_MANAGER
34 #define MAiNGO_IF_BAB_WORKER
35 #define MAiNGO_ELSE
36 #define MAiNGO_END_IF
37 
38 #define MAiNGO_MPI_BARRIER
39 #define MAiNGO_MPI_FINALIZE
40 
41 #endif
42 
43 #ifdef HAVE_MAiNGO_MPI
44 
45 namespace maingo {
46 
47 
52 enum BCAST_TAG {
53  BCAST_NOTHING_PENDING = 0,
54  BCAST_EXCEPTION,
55  BCAST_EVERYTHING_FINE,
56  BCAST_TIGHTENING_INFEASIBLE,
57  BCAST_CONSTR_PROP_INFEASIBLE,
58  BCAST_INFEASIBLE,
59  BCAST_FEASIBLE,
60  BCAST_TERMINATE,
61  BCAST_FOUND_FEAS,
62  BCAST_SCALING_NEEDED
63 };
64 
69 enum COMMUNICATION_TAG {
70  TAG_EXCEPTION = 0,
71  TAG_FOUND_INCUMBENT,
72  TAG_NEW_INCUMBENT,
73  TAG_NEW_INCUMBENT_ID,
74  TAG_NODE_REQUEST,
75  TAG_NEW_NODE_NO_INCUMBENT,
76  TAG_NEW_NODE_NEW_INCUMBENT,
77  TAG_NEW_NODE_UBD,
78  TAG_SOLVED_NODE_STATUS_NORMAL,
79  TAG_SOLVED_NODE_STATUS_CONVERGED,
80  TAG_SOLVED_NODE_STATUS_INFEAS,
81  TAG_SOLVED_NODE_LBD,
82  TAG_SOLVED_NODE_SOLUTION_POINT,
83  TAG_SOLVED_NODE_STATISTICS,
84  TAG_NODE_ID,
85  TAG_NODE_PRUNING_SCORE,
86  TAG_NODE_LOWER_BOUNDS,
87  TAG_NODE_UPPER_BOUNDS,
88  TAG_NODE_HAS_INCUMBENT,
89  TAG_NODE_DEPTH,
90  TAG_WORKER_FINISHED,
91  TAG_MS_STOP_SOLVING,
92  TAG_MS_NEW_POINT,
93  TAG_MS_SOLUTION,
94  TAG_MS_FEAS,
95  TAG_MS_INFEAS,
96 };
97 
104 inline void
105 send_babnode(const babBase::BabNode &node, const int dest)
106 {
107 
108  int id = node.get_ID();
109  std::vector<double> lb = node.get_lower_bounds();
110  std::vector<double> ub = node.get_upper_bounds();
111  int hI = node.holds_incumbent() ? 1 : 0;
112  double pruningScore = node.get_pruning_score();
113  int depth = node.get_depth();
114  // Send all information
115  MPI_Ssend(&id, 1, MPI_INT, dest, TAG_NODE_ID, MPI_COMM_WORLD);
116  MPI_Ssend(&pruningScore, 1, MPI_DOUBLE, dest, TAG_NODE_PRUNING_SCORE, MPI_COMM_WORLD);
117  MPI_Ssend(lb.data(), lb.size(), MPI_DOUBLE, dest, TAG_NODE_LOWER_BOUNDS, MPI_COMM_WORLD);
118  MPI_Ssend(ub.data(), lb.size(), MPI_DOUBLE, dest, TAG_NODE_UPPER_BOUNDS, MPI_COMM_WORLD);
119  MPI_Ssend(&hI, 1, MPI_INT, dest, TAG_NODE_HAS_INCUMBENT, MPI_COMM_WORLD);
120  MPI_Ssend(&depth, 1, MPI_INT, dest, TAG_NODE_DEPTH, MPI_COMM_WORLD);
121 }
122 
130 inline void
131 recv_babnode(babBase::BabNode &node, const int source, const unsigned nvar)
132 {
133 
134  int id;
135  std::vector<double> lb(nvar, 0);
136  std::vector<double> ub(nvar, 0);
137  int hI;
138  double pruningScore;
139  int depth;
140 
141 
142  MPI_Recv(&id, 1, MPI_INT, source, TAG_NODE_ID, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
143  MPI_Recv(&pruningScore, 1, MPI_DOUBLE, source, TAG_NODE_PRUNING_SCORE, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
144  MPI_Recv(lb.data(), nvar, MPI_DOUBLE, source, TAG_NODE_LOWER_BOUNDS, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
145  MPI_Recv(ub.data(), nvar, MPI_DOUBLE, source, TAG_NODE_UPPER_BOUNDS, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
146  MPI_Recv(&hI, 1, MPI_INT, source, TAG_NODE_HAS_INCUMBENT, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
147  MPI_Recv(&depth, 1, MPI_INT, source, TAG_NODE_DEPTH, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
148 
149  node = babBase::BabNode(pruningScore, lb, ub, id, depth, hI == 1);
150 }
151 
161 inline void
162 recv_vector_double(std::vector<double> &vec, int source, int tag, MPI_Comm comm, MPI_Status *status)
163 {
164 
165  MPI_Status probeStatus;
166  int messageSize;
167 
168  MPI_Probe(source, tag, MPI_COMM_WORLD, &probeStatus);
169  MPI_Get_count(&probeStatus, MPI_DOUBLE, &messageSize);
170  vec.resize(messageSize);
171 
172  MPI_Recv(vec.data(), messageSize, MPI_DOUBLE, source, tag, comm, status);
173 }
174 
184 inline void
185 recv_vector_int(std::vector<int> &vec, int source, int tag, MPI_Comm comm, MPI_Status *status)
186 {
187 
188  MPI_Status probeStatus;
189  int messageSize;
190 
191  MPI_Probe(source, tag, MPI_COMM_WORLD, &probeStatus);
192  MPI_Get_count(&probeStatus, MPI_INT, &messageSize);
193  vec.resize(messageSize);
194 
195  MPI_Recv(vec.data(), messageSize, MPI_INT, source, tag, comm, status);
196 }
197 
205 struct WorkerNodeComparator {
213  bool operator()(const std::pair<bool, double> &a, const std::pair<bool, double> &b) const
214  {
215  if (a.first) {
216  if (b.first) {
217  return a.second < b.second;
218  }
219  else {
220  return true;
221  }
222  }
223  else {
224  return false;
225  }
226  };
227 };
228 
229 
230 } // end namespace maingo
231 
232 #endif
int get_ID() const
Function for querying the node ID.
Definition: babNode.h:100
Class representing a node in the Branch-and-Bound tree.
Definition: babNode.h:35
std::vector< double > get_lower_bounds() const
Function for querying the lower bounds on the optimization variables within this node.
Definition: babNode.h:90
int get_depth() const
Function for querying the node depth.
Definition: babNode.h:105
namespace holding all essentials of MAiNGO
Definition: aleModel.h:31
bool holds_incumbent() const
Function obtaining information whether the node holds the incumbent.
Definition: babNode.h:110
std::vector< double > get_upper_bounds() const
Function for querying the upper bounds on the optimization variables within this node.
Definition: babNode.h:95
double get_pruning_score() const
Function for querying the pruning score within this node.
Definition: babNode.h:80