BCP_vg_main.cpp
Go to the documentation of this file.
1 // Copyright (C) 2000, International Business Machines
2 // Corporation and others. All Rights Reserved.
3 
4 #include <cstdio>
5 #include <cerrno>
6 #ifdef _MSC_VER
7 #include <process.h>
8 #endif
9 
10 #include "BcpConfig.h"
11 #include "BCP_os.hpp"
12 
13 #include "BCP_USER.hpp"
14 #include "BCP_error.hpp"
15 #include "BCP_buffer.hpp"
16 #include "BCP_message.hpp"
17 #include "BCP_problem_core.hpp"
18 #include "BCP_main_fun.hpp"
19 #include "BCP_vg_user.hpp"
20 #include "BCP_vg.hpp"
21 
22 //#############################################################################
23 
25  USER_initialize* user_init,
26  int my_id, int parent, double ub)
27 {
28  BCP_vg_prob p(my_id, parent);
29  p.upper_bound = ub;
30  p.msg_env = msg_env;
31 
32  // wait for the message with the parameters and unpack it
33  p.msg_buf.clear();
34  msg_env->receive(parent /*tree_manager*/,
36  p.par.unpack(p.msg_buf);
37 
38  // Let us be nice
39  setpriority(PRIO_PROCESS, 0, p.par.entry(BCP_vg_par::NiceLevel));
40 
41  FILE* logfile = 0;
42 
44  if (! (p.par.entry(BCP_vg_par::LogFileName) == "")) {
45  int len = log.length();
46  char *logname = new char[len + 300];
47  memcpy(logname, log.c_str(), len);
48  memcpy(logname + len, "-vg-", 4);
49  len += 4;
50  gethostname(logname + len, 255);
51  len = strlen(logname);
52  logname[len++] = '-';
53  sprintf(logname + len, "%i", static_cast<int>(GETPID));
54  logfile = freopen(logname, "a", stdout);
55  if (logfile == 0) {
56  fprintf(stderr, "Error while redirecting stdout: %i\n", errno);
57  abort();
58  }
59  setvbuf(logfile, NULL, _IOLBF, 0); // make it line buffered
60  delete[] logname;
61  } else {
62  setvbuf(stdout, NULL, _IOLBF, 0); // make it line buffered
63  }
64 
65  // now create the user universe
66  p.user = user_init->vg_init(p);
68  p.packer = user_init->packer_init(p.user);
69  p.packer->user_class = p.user;
70 
71  // wait for the core description and process it
72  p.msg_buf.clear();
73  p.msg_env->receive(parent /*tree_manager*/,
75  p.core->unpack(p.msg_buf);
76 
77  // wait for the user info
78  p.msg_buf.clear();
79  msg_env->receive(parent /*tree_manager*/,
82 
83  // ok, we're all geared up to generate vars
84  // wait for messages and process them...
85  BCP_message_tag msgtag;
87  while (true) {
88  p.msg_buf.clear();
90  msgtag = p.msg_buf.msgtag();
91  if (msgtag == BCP_Msg_NoMessage) {
92  // test if the TM is still alive
93  if (! p.msg_env->alive(parent /*tree_manager*/))
94  throw BCP_fatal_error("VG: The TM has died -- VG exiting\n");
95  } if (msgtag == BCP_Msg_ProcessType) {
96  p.msg_buf.unpack(ptype);
97  break;
98  } else {
99  if (BCP_vg_process_message(p, p.msg_buf)) {
100  // BCP_Msg_FinishedBCP arrived
101  break;
102  }
103  }
104  }
105  if (logfile)
106  fclose(logfile);
107 
108  return ptype;
109 }
110 
111 //#############################################################################
112 
113 bool
115 {
116  p.process_message();
117  return (p.msg_buf.msgtag() == BCP_Msg_FinishedBCP);
118 }
119 
120 void
122 {
123  while (true) {
124  const BCP_message_tag msgtag = msg_buf.msgtag();
125  switch (msgtag) {
128  case BCP_Msg_ForVG_User:
130  sender = msg_buf.sender();
132  break;
133 
134  case BCP_Msg_UpperBound:
135  double new_ub;
136  msg_buf.unpack(new_ub);
137  if (new_ub < upper_bound)
138  upper_bound = new_ub;
139  break;
140 
142  phase++;
143  break;
144 
145  case BCP_Msg_FinishedBCP:
146  return;
147 
148  default:
149  // a bogus message
150  printf("Unknown message type arrived to VG: %i\n", msg_buf.msgtag());
151  }
152  msg_buf.clear();
153 
154  if (probe_messages()) {
155  // if there's something interesting in the queue that overrides
156  // the pervious message then just continue to get the next message
157  continue;
158  }
159  // if there's nothing interesting then msgtag has the message tag of
160  // the last unpacked message. We got to do something only if the
161  // message is an lp solution, everything else has already been taken
162  // care of.
163  if (msgtag == BCP_Msg_ForVG_DualNonzeros ||
164  msgtag == BCP_Msg_ForVG_DualFull ||
165  msgtag == BCP_Msg_ForVG_User) {
167  // upon return send a no more vars message
168  double timing = 0.0; // *FIXME*
169  msg_buf.clear();
172  }
173  break;
174  }
175 }
BCP_message_tag
This enumerative constant describes the message tags different processes of BCP understand.
virtual void send(const int target, const BCP_message_tag tag)=0
Send an empty message (message tag only) to the process given by the frist argument.
BCP_vg_user * user
The user object holding the user&#39;s data.
Definition: BCP_vg.hpp:49
BCP_buffer & pack(const T &value)
Pack a single object of type T.
Definition: BCP_buffer.hpp:177
BCP has finished.
Used when receiving, message with any message tag will be received.
Used to indicate that there is no message in the buffer of a process.
BCP_buffer & unpack(T &value)
Unpack a single object of type T.
Definition: BCP_buffer.hpp:186
The &quot;nice&quot; level the process should run at.
virtual void receive(const int source, const BCP_message_tag tag, BCP_buffer &buf, const double timeout)=0
Blocking receive with timeout.
BCP_process_t BCP_vg_main(BCP_message_environment *msg_env, USER_initialize *user_init, int my_id, int parent, double ub)
Definition: BCP_vg_main.cpp:24
virtual void unpack_dual_solution(BCP_buffer &buf)
Unpack the LP solution arriving from the LP process.
Definition: BCP_vg_user.cpp:82
const int BCP_AnyProcess
Definition: BCP_message.hpp:21
This is an abstract base class that describes the message passing environment.
Definition: BCP_message.hpp:30
BCP_process_t
This enumerative constant describes the various process types.
BCP_message_environment * msg_env
The message passing environment.
Definition: BCP_vg.hpp:57
char entry(const chr_params key) const
Pack all dual variables.
const char * c_str() const
Definition: BCP_string.hpp:19
virtual BCP_user_pack * packer_init(BCP_user_class *p)
Definition: BCP_USER.hpp:225
The TM sends the description of the core formulation to the slave process.
int sender() const
Return a const pointer to the process id of the sender of the message in the buffer.
Definition: BCP_buffer.hpp:93
The TM sends the process type to the process (LP, Cut Generator, etc.)
int phase
The phase the algorithm is in.
Definition: BCP_vg.hpp:89
BCP_buffer msg_buf
The message buffer of the Variable Generator process.
Definition: BCP_vg.hpp:60
void unpack(BCP_buffer &buf)
Unpack the contents of the core description from the buffer.
Pack only dual variables currently at nonzero level.
#define setpriority(x, y, z)
Definition: BCP_os.hpp:13
This class is a very simple impelementation of a constant length string.
Definition: BCP_string.hpp:13
void setVgProblemPointer(BCP_vg_prob *ptr)
Set the pointer.
Definition: BCP_vg_user.hpp:62
int sender
The process id of the LP process that sent the solution.
Definition: BCP_vg.hpp:86
The user packed everything.
bool BCP_vg_process_message(BCP_vg_prob &p, BCP_buffer &buf)
This class is an abstract base class for the initializer class the user has to provide.
Definition: BCP_USER.hpp:160
#define GETPID
Definition: BCP_os.hpp:31
int length() const
Definition: BCP_string.hpp:16
int node_index
The index of search tree node where the solution was generated.
Definition: BCP_vg.hpp:93
BCP_user_class * user_class
A pointer ot the usr class of the process from which the methods of this class are invoked from...
Definition: BCP_USER.hpp:55
#define gethostname(x, y)
Definition: BCP_os.hpp:25
The TM sends the appropriate parameters to the slave process.
fint timing
Definition: readASLfg.cpp:18
The TM sends the initial user packed information to the slave process.
TM warns an LP process that the second phase will start.
void clear()
Completely clear the buffer.
Definition: BCP_buffer.hpp:168
virtual BCP_vg_user * vg_init(BCP_vg_prob &p)
Definition: BCP_USER.hpp:205
BCP_parameter_set< BCP_vg_par > par
The parameters controlling the Variable Generator process.
Definition: BCP_vg.hpp:63
virtual void generate_vars(BCP_vec< BCP_cut * > &cuts, BCP_vec< double > &pi)
Perform the actual variable generation.
BCP_message_tag msgtag() const
Return the message tag of the message in the buffer.
Definition: BCP_buffer.hpp:90
BCP_problem_core * core
The description of the core of the problem.
Definition: BCP_vg.hpp:66
Currently there isn&#39;t any error handling in BCP.
Definition: BCP_error.hpp:20
bool probe_messages()
Test if there is a message in the message queue waiting to be processed.
Definition: BCP_vg.cpp:27
int node_level
The level of search tree node where the solution was generated.
Definition: BCP_vg.hpp:91
This class describes the message buffer used for all processes of BCP.
Definition: BCP_buffer.hpp:39
No more (improving) variables could be found.
int node_iteration
The iteration within the search tree node where the solution was generated.
Definition: BCP_vg.hpp:96
void unpack(BCP_buffer &buf)
Unpack the parameter set from the buffer.
BCP_user_pack * packer
A class that holds the methods about how to pack things.
Definition: BCP_vg.hpp:52
BCP_vec< BCP_cut * > cuts
Variables are to be generated for the LP solution given by these cuts and their values (next member)...
Definition: BCP_vg.hpp:82
Any process to TM or TM to any process: a new upper bound found.
virtual bool alive(const int pid)=0
Test if the process given by the argument is alive or not.
This class is the central class of the Variable Generator process.
Definition: BCP_vg.hpp:32
double upper_bound
The proc id of the Tree Manager.
Definition: BCP_vg.hpp:72
BCP_vec< double > pi
The dual values corresponding to the cuts above.
Definition: BCP_vg.hpp:84
virtual void unpack_module_data(BCP_buffer &buf)
Unpack the initial information sent to the Variable Generator process by the Tree Manager...
Definition: BCP_vg_user.cpp:72
virtual void process_message()
CouExpr & log(CouExpr &e)