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