/home/coin/SVN-release/OS-2.1.0/Bcp/src/VG/BCP_vg_main.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
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    // wait for the message with the parameters and unpack it
00033    p.msg_buf.clear();
00034    msg_env->receive(parent /*tree_manager*/,
00035                     BCP_Msg_ProcessParameters, p.msg_buf, -1);
00036    p.par.unpack(p.msg_buf);
00037 
00038    // Let us be nice
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); // make it line buffered
00060       delete[] logname;
00061    } else {
00062       setvbuf(stdout, NULL, _IOLBF, 0); // make it line buffered
00063    }
00064 
00065    // now create the user universe
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    // wait for the core description and process it
00072    p.msg_buf.clear();
00073    p.msg_env->receive(parent /*tree_manager*/,
00074                       BCP_Msg_CoreDescription, p.msg_buf, -1);
00075    p.core->unpack(p.msg_buf);
00076 
00077    // wait for the user info
00078    p.msg_buf.clear();
00079    msg_env->receive(parent /*tree_manager*/,
00080                     BCP_Msg_InitialUserInfo, p.msg_buf, -1);
00081    p.user->unpack_module_data(p.msg_buf);
00082 
00083    // ok, we're all geared up to generate vars
00084    // wait for messages and process them...
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          // test if the TM is still alive
00093          if (! p.msg_env->alive(parent /*tree_manager*/))
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             // BCP_Msg_FinishedBCP arrived
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          // a bogus message
00150          printf("Unknown message type arrived to VG: %i\n", msg_buf.msgtag());
00151       }
00152       msg_buf.clear();
00153 
00154       if (probe_messages()) {
00155          // if there's something interesting in the queue that overrides
00156          // the pervious message then just continue to get the next message
00157          continue;
00158       }
00159       // if there's nothing interesting then msgtag has the message tag of
00160       // the last unpacked message. We got to do something only if the
00161       // message is an lp solution, everything else has already been taken
00162       // care of. 
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          // upon return send a no more vars message
00168          double timing = 0.0; // *FIXME*
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 }

Generated on Tue Mar 30 03:04:33 2010 by  doxygen 1.4.7