Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

BCP_vg_main.cpp

00001 // Copyright (C) 2000, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
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    // wait for the message with the parameters and unpack it
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    // Let us be nice
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); // make it line buffered
00057       delete[] logname;
00058    } else {
00059       setvbuf(stdout, NULL, _IOLBF, 0); // make it line buffered
00060    }
00061 
00062    // now create the user universe
00063    p.user = user_init->vg_init(p);
00064    p.user->setVgProblemPointer(&p);
00065 
00066    // wait for the core description and process it
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    // wait for the user info
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    // ok, we're all geared up to generate vars
00077    // wait for messages and process them...
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          // test if the TM is still alive
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             // BCP_Msg_FinishedBCP arrived
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          // a bogus message
00137          printf("Unknown message type arrived to VG: %i\n", msg_buf.msgtag());
00138       }
00139       msg_buf.clear();
00140 
00141       if (probe_messages()) {
00142          // if there's something interesting in the queue that overrides
00143          // the pervious message then just continue to get the next message
00144          continue;
00145       }
00146       // if there's nothing interesting then msgtag has the message tag of
00147       // the last unpacked message. We got to do something only if the
00148       // message is an lp solution, everything else has already been taken
00149       // care of. 
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          // upon return send a no more vars message
00155          double timing = 0.0; // *FIXME*
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 }

Generated on Wed Dec 3 14:32:35 2003 for BCP by doxygen 1.3.5