00001
00002
00003
00004 #include <cstdio>
00005 #include <cerrno>
00006 #ifdef _MSC_VER
00007 #include <process.h>
00008 #endif
00009
00010 #include "BcpConfig.h"
00011 #include "BCP_os.hpp"
00012
00013 #include "BCP_USER.hpp"
00014 #include "BCP_error.hpp"
00015 #include "BCP_buffer.hpp"
00016 #include "BCP_message.hpp"
00017 #include "BCP_problem_core.hpp"
00018 #include "BCP_main_fun.hpp"
00019 #include "BCP_vg_user.hpp"
00020 #include "BCP_vg.hpp"
00021
00022
00023
00024 BCP_process_t BCP_vg_main(BCP_message_environment* msg_env,
00025 USER_initialize* user_init,
00026 int my_id, int parent, double ub)
00027 {
00028 BCP_vg_prob p(my_id, parent);
00029 p.upper_bound = ub;
00030 p.msg_env = msg_env;
00031
00032
00033 p.msg_buf.clear();
00034 msg_env->receive(parent ,
00035 BCP_Msg_ProcessParameters, p.msg_buf, -1);
00036 p.par.unpack(p.msg_buf);
00037
00038
00039 setpriority(PRIO_PROCESS, 0, p.par.entry(BCP_vg_par::NiceLevel));
00040
00041 FILE* logfile = 0;
00042
00043 const BCP_string& log = p.par.entry(BCP_vg_par::LogFileName);
00044 if (! (p.par.entry(BCP_vg_par::LogFileName) == "")) {
00045 int len = log.length();
00046 char *logname = new char[len + 300];
00047 memcpy(logname, log.c_str(), len);
00048 memcpy(logname + len, "-vg-", 4);
00049 len += 4;
00050 gethostname(logname + len, 255);
00051 len = strlen(logname);
00052 logname[len++] = '-';
00053 sprintf(logname + len, "%i", static_cast<int>(GETPID));
00054 logfile = freopen(logname, "a", stdout);
00055 if (logfile == 0) {
00056 fprintf(stderr, "Error while redirecting stdout: %i\n", errno);
00057 abort();
00058 }
00059 setvbuf(logfile, NULL, _IOLBF, 0);
00060 delete[] logname;
00061 } else {
00062 setvbuf(stdout, NULL, _IOLBF, 0);
00063 }
00064
00065
00066 p.user = user_init->vg_init(p);
00067 p.user->setVgProblemPointer(&p);
00068 p.packer = user_init->packer_init(p.user);
00069 p.packer->user_class = p.user;
00070
00071
00072 p.msg_buf.clear();
00073 p.msg_env->receive(parent ,
00074 BCP_Msg_CoreDescription, p.msg_buf, -1);
00075 p.core->unpack(p.msg_buf);
00076
00077
00078 p.msg_buf.clear();
00079 msg_env->receive(parent ,
00080 BCP_Msg_InitialUserInfo, p.msg_buf, -1);
00081 p.user->unpack_module_data(p.msg_buf);
00082
00083
00084
00085 BCP_message_tag msgtag;
00086 BCP_process_t ptype = BCP_ProcessType_EndProcess;
00087 while (true) {
00088 p.msg_buf.clear();
00089 msg_env->receive(BCP_AnyProcess, BCP_Msg_AnyMessage, p.msg_buf, 15);
00090 msgtag = p.msg_buf.msgtag();
00091 if (msgtag == BCP_Msg_NoMessage) {
00092
00093 if (! p.msg_env->alive(parent ))
00094 throw BCP_fatal_error("VG: The TM has died -- VG exiting\n");
00095 } if (msgtag == BCP_Msg_ProcessType) {
00096 p.msg_buf.unpack(ptype);
00097 break;
00098 } else {
00099 if (BCP_vg_process_message(p, p.msg_buf)) {
00100
00101 break;
00102 }
00103 }
00104 }
00105 if (logfile)
00106 fclose(logfile);
00107
00108 return ptype;
00109 }
00110
00111
00112
00113 bool
00114 BCP_vg_process_message(BCP_vg_prob& p, BCP_buffer& buf)
00115 {
00116 p.process_message();
00117 return (p.msg_buf.msgtag() == BCP_Msg_FinishedBCP);
00118 }
00119
00120 void
00121 BCP_vg_prob::process_message()
00122 {
00123 while (true) {
00124 const BCP_message_tag msgtag = msg_buf.msgtag();
00125 switch (msgtag) {
00126 case BCP_Msg_ForVG_DualNonzeros:
00127 case BCP_Msg_ForVG_DualFull:
00128 case BCP_Msg_ForVG_User:
00129 msg_buf.unpack(node_level).unpack(node_index).unpack(node_iteration);
00130 sender = msg_buf.sender();
00131 user->unpack_dual_solution(msg_buf);
00132 break;
00133
00134 case BCP_Msg_UpperBound:
00135 double new_ub;
00136 msg_buf.unpack(new_ub);
00137 if (new_ub < upper_bound)
00138 upper_bound = new_ub;
00139 break;
00140
00141 case BCP_Msg_NextPhaseStarts:
00142 phase++;
00143 break;
00144
00145 case BCP_Msg_FinishedBCP:
00146 return;
00147
00148 default:
00149
00150 printf("Unknown message type arrived to VG: %i\n", msg_buf.msgtag());
00151 }
00152 msg_buf.clear();
00153
00154 if (probe_messages()) {
00155
00156
00157 continue;
00158 }
00159
00160
00161
00162
00163 if (msgtag == BCP_Msg_ForVG_DualNonzeros ||
00164 msgtag == BCP_Msg_ForVG_DualFull ||
00165 msgtag == BCP_Msg_ForVG_User) {
00166 user->generate_vars(cuts, pi);
00167
00168 double timing = 0.0;
00169 msg_buf.clear();
00170 msg_buf.pack(node_index).pack(node_iteration).pack(timing);
00171 msg_env->send(sender, BCP_Msg_NoMoreVars, msg_buf);
00172 }
00173 break;
00174 }
00175 }