/home/coin/SVN-release/OS-2.0.1/Bcp/src/CG/BCP_cg_main.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
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    // wait for the message with the parameters and unpack it
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    // Let us be nice
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); // make it line buffered
00058       delete[] logname;
00059    } else {
00060       setvbuf(stdout, NULL, _IOLBF, 0); // make it line buffered
00061    }
00062 
00063    // now create the user universe
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    // wait for the core description and process it
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    // wait for the user info
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    // ok, we're all geared up to generate cuts
00080    // wait for messages and process them...
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          // test if the TM is still alive
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             // BCP_Msg_FinishedBCP arrived
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          // a bogus message
00147          printf("Unknown message type arrived to CG: %i\n", msg_buf.msgtag());
00148       }
00149       msg_buf.clear();
00150 
00151       if (probe_messages()) {
00152          // if there's something interesting in the queue that overrides
00153          // the pervious message then just continue to get the next message
00154          continue;
00155       }
00156       // if there's nothing interesting then msgtag has the message tag of
00157       // the last unpacked message. We got to do something only if the
00158       // message is an lp solution, everything else has already been taken
00159       // care of. 
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          // upon return send a no more cuts message
00166          double timing = 0.0; // *FIXME*
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 }

Generated on Thu Oct 8 03:02:51 2009 by  doxygen 1.4.7