00001
00002
00003
00004 #include <cstdio>
00005
00006 #include "CoinTime.hpp"
00007
00008 #include "BCP_math.hpp"
00009
00010 #include "BCP_USER.hpp"
00011
00012 #include "BCP_error.hpp"
00013 #include "BCP_buffer.hpp"
00014 #include "BCP_vector.hpp"
00015 #include "BCP_message_single.hpp"
00016
00017 #include "BCP_problem_core.hpp"
00018 #include "BCP_node_change.hpp"
00019
00020 #include "BCP_tm_functions.hpp"
00021 #include "BCP_tm_user.hpp"
00022 #include "BCP_lp_functions.hpp"
00023 #include "BCP_lp_user.hpp"
00024 #include "BCP_lp.hpp"
00025
00026 #include "BCP_cg_user.hpp"
00027 #include "BCP_cg.hpp"
00028
00029 #include "BCP_vg_user.hpp"
00030 #include "BCP_vg.hpp"
00031
00032 #include "BCP_tm.hpp"
00033
00034 std::map<int, BCP_process*> BCP_single_environment::processes;
00035
00036
00037
00038 void
00039 BCP_single_environment::set_arguments(const int argnum,
00040 const char* const * args)
00041 {
00042 int i;
00043 for (i = _argnum - 1; i >= 0; --i) {
00044 free(_arglist[i]);
00045 }
00046 _argnum = argnum;
00047 _arglist = new char*[argnum];
00048 for (i = _argnum - 1; i >= 0; --i) {
00049 _arglist[i] = strdup(args[i]);
00050 }
00051 }
00052
00053
00054
00055 BCP_single_environment::~BCP_single_environment()
00056 {
00057 for (int i = _argnum - 1; i >= 0; --i) {
00058 free(_arglist[i]);
00059 }
00060 delete[] _arglist;
00061 }
00062
00063
00064
00065 int
00066 BCP_single_environment::register_process(USER_initialize* user_init)
00067 {
00068
00069
00070
00071
00072 int _tm_id(0);
00073 int _lp_id(1);
00074 #if ! defined(BCP_ONLY_LP_PROCESS_HANDLING_WORKS)
00075 int _cg_id(2);
00076 int _vg_id(3);
00077 #endif
00078
00079
00080 BCP_tm_prob* _tm_prob = new BCP_tm_prob();
00081 processes[0] = _tm_prob;
00082
00083 _tm_prob->par.set_entry(BCP_tm_par::MessagePassingIsSerial,true);
00084 _tm_prob->slave_pars.lp.set_entry(BCP_lp_par::MessagePassingIsSerial,true);
00085 _tm_prob->slave_pars.cg.set_entry(BCP_cg_par::MessagePassingIsSerial,true);
00086 _tm_prob->slave_pars.vg.set_entry(BCP_vg_par::MessagePassingIsSerial,true);
00087
00088
00089
00090
00091 BCP_tm_parse_command_line(*_tm_prob, _argnum, _arglist);
00092
00093 _tm_prob->msg_env = this;
00094 _tm_prob->start_time = CoinWallclockTime();
00095 _my_id = _tm_id;
00096
00097
00098
00099
00100
00101
00102
00103 _tm_prob->user = user_init->tm_init(*_tm_prob, _argnum, _arglist);
00104 _tm_prob->user->setTmProblemPointer(_tm_prob);
00105 _tm_prob->packer = user_init->packer_init(_tm_prob->user);
00106 _tm_prob->packer->user_class = _tm_prob->user;
00107
00108
00109 #if ! defined(BCP_ONLY_LP_PROCESS_HANDLING_WORKS)
00110 if (_tm_prob->param(BCP_tm_par::CpProcessNum) > 0) {
00111 _tm_prob->leaves_per_cp.reserve(_tm_prob->slaves.cp->procs().size());
00112 for (int i = _tm_prob->slaves.cp->procs().size() - 1; i >= 0; --i)
00113 _tm_prob->leaves_per_cp.unchecked_push_back
00114 (std::make_pair(_tm_prob->slaves.cp->procs()[i], 0));
00115 }
00116 if (_tm_prob->param(BCP_tm_par::VpProcessNum) > 0) {
00117 _tm_prob->leaves_per_vp.reserve(_tm_prob->slaves.vp->procs().size());
00118 for (int i = _tm_prob->slaves.vp->procs().size() - 1; i >= 0; --i)
00119 _tm_prob->leaves_per_vp.unchecked_push_back
00120 (std::make_pair(_tm_prob->slaves.vp->procs()[i], 0));
00121 }
00122 #endif
00123
00124
00125 _tm_prob->core = BCP_tm_create_core(*_tm_prob);
00126 _tm_prob->core_as_change = new BCP_problem_core_change;
00127 *_tm_prob->core_as_change = *_tm_prob->core;
00128
00129
00130
00131
00132
00133 BCP_tm_node* root = BCP_tm_create_root(*_tm_prob);
00134
00135 _tm_prob->next_phase_nodes.push_back(root);
00136 _tm_prob->search_tree.insert(root);
00137
00138 BCP_sanity_checks(*_tm_prob);
00139
00140
00141
00142
00143
00144
00145
00146 BCP_lp_prob* _lp_prob = new BCP_lp_prob(_lp_id, _tm_id);
00147 processes[_lp_id] = _lp_prob;
00148 _lp_prob->msg_env = new BCP_single_environment(_lp_id);
00149 _tm_prob->lp_procs.push_back(_lp_id);
00150 _tm_prob->lp_scheduler.add_free_ids(_tm_prob->lp_procs.size(),
00151 &_tm_prob->lp_procs[0]);
00152 _tm_prob->lp_scheduler.
00153 setParams(_tm_prob->param(BCP_tm_par::LPscheduler_OverEstimationStatic),
00154 _tm_prob->param(BCP_tm_par::LPscheduler_SwitchToRateThreshold),
00155 10.0,
00156 _tm_prob->param(BCP_tm_par::LPscheduler_FactorTimeHorizon),
00157 _tm_prob->param(BCP_tm_par::LPscheduler_OverEstimationRate),
00158 _tm_prob->param(BCP_tm_par::LPscheduler_MaxNodeIdRatio),
00159 _tm_prob->param(BCP_tm_par::LPscheduler_MaxNodeIdNum),
00160 _tm_prob->param(BCP_tm_par::LPscheduler_MaxSbIdNum),
00161 _tm_prob->param(BCP_tm_par::LPscheduler_MinSbIdNum));
00162
00163
00164 BCP_cg_prob* _cg_prob = 0;
00165 BCP_vg_prob* _vg_prob = 0;
00166
00167
00168
00169
00170 #if ! defined(BCP_ONLY_LP_PROCESS_HANDLING_WORKS)
00171 if (_tm_prob->param(BCP_tm_par::CgProcessNum) > 0) {
00172 _cg_prob = new BCP_cg_prob(_cg_id, _tm_id);
00173 processes[_cg_id] = _cg_prob;
00174 _cg_prob->msg_env = new BCP_single_environment(_cg_id);
00175 _tm_prob->slaves.cg = new BCP_proc_array;
00176 _tm_prob->slaves.cg->add_proc(_cg_id);
00177 _tm_prob->slaves.all->add_proc(_cg_id);
00178 }
00179
00180
00181 if (_tm_prob->param(BCP_tm_par::VgProcessNum) > 0) {
00182 _vg_prob = new BCP_vg_prob(_vg_id, _tm_id);
00183 processes[_vg_id] = _vg_prob;
00184 _vg_prob->msg_env = new BCP_single_environment(_vg_id);
00185 _tm_prob->slaves.vg = new BCP_proc_array;
00186 _tm_prob->slaves.vg->add_proc(_vg_id);
00187 _tm_prob->slaves.all->add_proc(_vg_id);
00188 }
00189
00190
00191 if (_tm_prob->param(BCP_tm_par::CpProcessNum) > 0) {
00192 _cp_prob = new BCP_cp_prob(_cp_id, _tm_id);
00193 processes[_cp_id] = _cp_prob;
00194 _cp_prob->msg_env = new BCP_single_environment(_cp_id);
00195 _tm_prob->slaves.cp = new BCP_proc_array;
00196 _tm_prob->slaves.cp->add_proc(_cp_id);
00197 _tm_prob->slaves.all->add_proc(_cp_id);
00198 }
00199
00200
00201 if (_tm_prob->param(BCP_tm_par::VpProcessNum) > 0) {
00202 _vp_prob = new BCP_vp_prob(_vp_id, _tm_id);
00203 processes[_vp_id] = _vp_prob;
00204 _vp_prob->msg_env = new BCP_single_environment(_vp_id);
00205 _tm_prob->slaves.vp = new BCP_proc_array;
00206 _tm_prob->slaves.vp->add_proc(_vp_id);
00207 _tm_prob->slaves.all->add_proc(_vp_id);
00208 }
00209 #endif
00210
00211
00212
00213
00214 _tm_prob->msg_buf.clear();
00215 _tm_prob->core->pack(_tm_prob->msg_buf);
00216 BCP_lp_process_core(*_lp_prob, _tm_prob->msg_buf);
00217
00218
00219 if (_cg_prob) {
00220 _tm_prob->msg_buf.clear();
00221 _tm_prob->core->pack(_tm_prob->msg_buf);
00222 _cg_prob->core->unpack(_tm_prob->msg_buf);
00223 }
00224
00225 if (_vg_prob) {
00226 _tm_prob->msg_buf.clear();
00227 _tm_prob->core->pack(_tm_prob->msg_buf);
00228 _vg_prob->core->unpack(_tm_prob->msg_buf);
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238 _lp_prob->par = _tm_prob->slave_pars.lp;
00239
00240 _lp_prob->user = user_init->lp_init(*_lp_prob);
00241 _lp_prob->user->setLpProblemPointer(_lp_prob);
00242 _lp_prob->packer = user_init->packer_init(_lp_prob->user);
00243 _lp_prob->packer->user_class = _lp_prob->user;
00244
00245
00246 _tm_prob->msg_buf.clear();
00247 _tm_prob->user->pack_module_data(_tm_prob->msg_buf, BCP_ProcessType_LP);
00248 _lp_prob->user->unpack_module_data(_tm_prob->msg_buf);
00249 _lp_prob->master_lp = _lp_prob->user->initialize_solver_interface();
00250
00251 _lp_prob->upper_bound = std::min<double>(_tm_prob->ub(), BCP_DBL_MAX);
00252
00253 if (_cg_prob) {
00254
00255
00256 _cg_prob->par = _tm_prob->slave_pars.cg;
00257
00258 _cg_prob->user = user_init->cg_init(*_cg_prob);
00259 _cg_prob->user->setCgProblemPointer(_cg_prob);
00260 _cg_prob->packer = user_init->packer_init(_cg_prob->user);
00261 _cg_prob->packer->user_class = _cg_prob->user;
00262
00263 _tm_prob->msg_buf.clear();
00264 _tm_prob->user->pack_module_data(_tm_prob->msg_buf,
00265 BCP_ProcessType_CG);
00266 if (_cg_prob->user)
00267 _cg_prob->user->unpack_module_data(_tm_prob->msg_buf);
00268 }
00269
00270
00271 if (_vg_prob) {
00272
00273
00274 _vg_prob->par = _tm_prob->slave_pars.vg;
00275
00276 _vg_prob->user = user_init->vg_init(*_vg_prob);
00277 _vg_prob->user->setVgProblemPointer(_vg_prob);
00278 _vg_prob->packer = user_init->packer_init(_vg_prob->user);
00279 _vg_prob->packer->user_class = _vg_prob->user;
00280
00281 _tm_prob->msg_buf.clear();
00282 _tm_prob->user->pack_module_data(_tm_prob->msg_buf,
00283 BCP_ProcessType_VG);
00284 if (_vg_prob->user)
00285 _vg_prob->user->unpack_module_data(_tm_prob->msg_buf);
00286 }
00287
00288
00289
00290
00291
00292
00293 bool something_died = false;
00294 try {
00295 for ( _tm_prob->phase = 0; true ; ++_tm_prob->phase) {
00296
00297
00298
00299 BCP_tm_tasks_before_new_phase(*_tm_prob);
00300
00301
00302
00303 something_died = false;
00304 while (! _tm_prob->candidate_list.empty() ||
00305 _tm_prob->lp_scheduler.numNodeIds() > 0){
00306
00307 if (BCP_tm_start_new_nodes(*_tm_prob) == BCP_NodeStart_Error) {
00308
00309 something_died = true;
00310 break;
00311 }
00312
00313
00314 }
00315
00316
00317 if (_tm_prob->next_phase_nodes.size() == 0 || something_died)
00318 break;
00319 }
00320 }
00321 catch (BCP_fatal_error& err) {
00322
00323 }
00324
00325
00326 BCP_tm_wrapup(_tm_prob, _lp_prob, _cg_prob, _vg_prob, true);
00327
00328
00329 delete _lp_prob;
00330
00331 if (_cg_prob) {
00332 delete _cg_prob;
00333 }
00334 if (_vg_prob) {
00335 delete _vg_prob;
00336 }
00337
00338
00339
00340
00341
00342
00343 delete _tm_prob;
00344
00345 return 0;
00346 }
00347
00348
00349
00350 int
00351 BCP_single_environment::parent_process() {
00352 throw BCP_fatal_error("\
00353 BCP_single_environment::parent_process() invoked.\n");
00354 return 0;
00355 }
00356
00357 bool
00358 BCP_single_environment::alive(const int pid)
00359 {
00360 return true;
00361 }
00362
00363 const int*
00364 BCP_single_environment::alive(int num, const int* pids)
00365 {
00366 return NULL;
00367 }
00368
00369
00370
00371 void
00372 BCP_single_environment::send(const int target,
00373 const BCP_message_tag tag)
00374 {
00375 BCP_process* target_process = processes[target];
00376 BCP_buffer& target_buf = target_process->get_message_buffer();
00377 target_buf.clear();
00378 target_buf._sender = _my_id;
00379 target_buf._msgtag = tag;
00380 target_process->process_message();
00381 }
00382
00383 void
00384 BCP_single_environment::send(const int target,
00385 const BCP_message_tag tag,
00386 const BCP_buffer& buf)
00387 {
00388 BCP_process* target_process = processes[target];
00389 BCP_buffer& target_buf = target_process->get_message_buffer();
00390 target_buf = buf;
00391 target_buf._sender = _my_id;
00392 target_buf._msgtag = tag;
00393 target_process->process_message();
00394 }
00395
00396
00397
00398 void
00399 BCP_single_environment::multicast(int num, const int* targets,
00400 const BCP_message_tag tag)
00401 {
00402 for (int i = 0; i < num; ++i) {
00403 send(targets[i], tag);
00404 }
00405 }
00406
00407 void
00408 BCP_single_environment::multicast(int num, const int* targets,
00409 const BCP_message_tag tag,
00410 const BCP_buffer& buf)
00411 {
00412 for (int i = 0; i < num; ++i) {
00413 send(targets[i], tag, buf);
00414 }
00415 }
00416
00417
00418
00419 void
00420 BCP_single_environment::receive(const int source,
00421 const BCP_message_tag tag,
00422 BCP_buffer& buf, const double timeout)
00423 {
00424
00425
00426
00427 if (tag != BCP_Msg_UpperBound &&
00428 tag != BCP_Msg_DivingInfo)
00429 printf("BCP_single_environment::receive() is called with %i as tag.\n",
00430 tag);
00431 }
00432
00433
00434
00435 bool
00436 BCP_single_environment::probe(const int source,
00437 const BCP_message_tag tag)
00438 {
00439
00440 return false;
00441 }
00442
00443
00444
00445
00446 int
00447 BCP_single_environment::start_process(const BCP_string& exe,
00448 const bool debug)
00449 {
00450 throw BCP_fatal_error("start_process() called!\n");
00451 return 0;
00452 }
00453
00454 int
00455 BCP_single_environment::start_process(const BCP_string& exe,
00456 const BCP_string& machine,
00457 const bool debug)
00458 {
00459 throw BCP_fatal_error("start_process() called!\n");
00460 return 0;
00461 }
00462
00463 bool
00464 BCP_single_environment::start_processes(const BCP_string& exe,
00465 const int proc_num,
00466 const bool debug,
00467 int* ids)
00468 {
00469 throw BCP_fatal_error("start_processes() called!\n");
00470 return false;
00471 }
00472
00473 bool
00474 BCP_single_environment::start_processes(const BCP_string& exe,
00475 const int proc_num,
00476 const BCP_vec<BCP_string>& machines,
00477 const bool debug,
00478 int* ids)
00479 {
00480 throw BCP_fatal_error("start_processes() called!\n");
00481 return false;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499