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