public: void stop() { DCS_DEBUG_TRACE("BEGIN Stopping Application: '" << name_ << "'"); // check: pointer to simulation model is a valid pointer DCS_DEBUG_ASSERT( ptr_sim_model_ ); ptr_sim_model_->stop_application(); DCS_DEBUG_TRACE("END Stopping Application: '" << name_ << "'"); }
void start(VMForwardIterT first, VMForwardIterT last) { DCS_DEBUG_TRACE("BEGIN Starting Application: '" << name_ << "'"); // check: pointer to simulation model is a valid pointer DCS_DEBUG_ASSERT( ptr_sim_model_ ); ptr_sim_model_->tier_virtual_machines(first, last); ptr_sim_model_->start_application(); DCS_DEBUG_TRACE("END Starting Application: '" << name_ << "'"); }
/** * \brief Perform system experiment. */ public: void run() { typedef typename app_experiment_container::const_iterator app_experiment_iterator; // typedef typename monitor_container::const_iterator monitor_iterator; DCS_DEBUG_TRACE( "BEGIN Execution of System EXPERIMENT" ); app_experiment_iterator app_exp_end_it(app_exps_.end()); app_experiment_iterator app_exp_beg_it(app_exps_.begin()); (*p_sta_sig_)(*this); if (app_exp_beg_it != app_exp_end_it) { // There is some experiment to run ::boost::thread_group exp_thds; // Create threads for application experiments for (app_experiment_iterator app_exp_it = app_exp_beg_it; app_exp_it != app_exp_end_it; ++app_exp_it) { app_experiment_pointer p_app_exp(*app_exp_it); detail::runnable<app_experiment_type> exp_runner(*app_exp_it); //::boost::thread exp_thd(exp_runner); exp_thds.create_thread(exp_runner); //::boost::this_thread::sleep_for(::boost::chrono::seconds(2)); } // // Create threads for experiment monitors // system_experiment_context<traits_type> ctx(this); // monitor_iterator mon_end_it(mons_.end()); // for (monitor_iterator mon_it = mons_.begin(); // mon_it != mon_end_it; // ++mon_it) // { // monitor_pointer p_mon(*mon_it); // // detail::monitor_runnable<monitor_type> mon_runner(p_mon, ctx); // exp_thds.create_thread(mon_runner); // } running_ = true; exp_thds.join_all(); running_ = false; } (*p_sto_sig_)(*this); DCS_DEBUG_TRACE( "END Execution of System EXPERIMENT" ); }
/// Accumulate the effective amount of work done (the work will not be scaled) public: void accumulate_work2(real_type w) { // NOTE: the use of epsilon() is to take care of cancellation errors due // to floating-point subtraction. DCS_DEBUG_TRACE("(" << this << ") Accumulating work for Customer: " << ::std::setprecision(12) << get_customer() << " -> Work: " << w << " - Old Total work: " << wt_ << " - New Total work: " << (wt_+w) << " - Service Demand: " << sd_ << " - Condition: " << ::std::boolalpha << (wt_+w<=sd_) << " - Condition#2: " << ::std::boolalpha << ((wt_+w)<=sd_) << " - Condition#3: " << ::std::boolalpha << ((wt_+w)>sd_) << " - Difference: " << ((wt_+w)-sd_) << " - epsilon: " << ::std::numeric_limits<real_type>::epsilon());//XXX DCS_DEBUG_ASSERT( w >= 0 ); //DCS_DEBUG_ASSERT( wt_+w <= sd_ ); DCS_DEBUG_ASSERT( ::dcs::math::float_traits<real_type>::definitely_less_equal(wt_+w, sd_) ); wt_ += w; lwut_ = -1; // not available }
private: void do_control() { // DCS_MACRO_SUPPRESS_UNUSED_VARIABLE_WARNING( evt ); // DCS_MACRO_SUPPRESS_UNUSED_VARIABLE_WARNING( ctx ); // DCS_DEBUG_TRACE("(" << this << ") BEGIN Do Processing CONTROL (Clock: " << ctx.simulated_time() << ")");//XXX // pre: physical machine must have already been set DCS_DEBUG_ASSERT( this->machine_ptr() ); typedef typename base_type::physical_machine_type physical_machine_type; typedef typename physical_machine_type::vmm_type vmm_type; typedef typename vmm_type::virtual_machine_type vm_type; typedef typename vmm_type::virtual_machine_pointer vm_pointer; typedef typename vmm_type::virtual_machine_container vm_container; typedef typename vm_container::const_iterator vm_iterator; typedef typename vm_type::resource_share_container share_container; typedef typename share_container::const_iterator share_iterator; typedef ::std::map<physical_resource_category,real_type> share_map_container; vm_container actual_vms(this->machine().vmm().virtual_machines(powered_on_power_status)); share_map_container share_sums; short step = 1; do { // Share assignment is done in 2 steps // 1. In the first step computes the total resource fraction // requested by all VMs. The computed value both serves to check // if the total fraction overpass the maximum allowable // utilization and as a normalization constant. // 2. In the second step assign resource shares. // Specifically, if the total amount of requested resource // capacity is greater than the one assignable then vm_iterator vm_end_it(actual_vms.end()); for (vm_iterator vm_it = actual_vms.begin(); vm_it != vm_end_it; ++vm_it) { vm_pointer ptr_vm(*vm_it); share_container vm_wanted_shares(ptr_vm->wanted_resource_shares()); share_iterator share_end_it(vm_wanted_shares.end()); for (share_iterator share_it = vm_wanted_shares.begin(); share_it != share_end_it; ++share_it) { physical_resource_category category(share_it->first); real_type share(share_it->second); if (step == 1) { // Compute share sum for this resource category if (share_sums.count(category) > 0) { share_sums[category] += share; } else { share_sums[category] = share; } } else { // Assign share for this resource category real_type share_sum(share_sums.at(category)); real_type threshold(this->machine().resource(category)->utilization_threshold()); #ifdef DCS_DES_CLOUD_EXP_PROPORTIONAL_MACH_CONTROLLER_WORK_CONSERVATIVE // Assign share proportionally share *= threshold/share_sum; // The operation below may appear useless. However it is needed to compensate spurious decimal digit derived from the above product. share = ::std::min(share, threshold); #else // DCS_DES_CLOUD_EXP_PROPORTIONAL_MACH_CONTROLLER_WORK_CONSERVATIVE if (share_sum > threshold) { // Assign share proportionally share *= threshold/share_sum; // The operation below may appear useless. However it is needed to compensate spurious decimal digit derived from the above product. share = ::std::min(share, threshold); } // ... else Assign share as it is originally requested. #endif // DCS_DES_CLOUD_EXP_PROPORTIONAL_MACH_CONTROLLER_WORK_CONSERVATIVE // check: make sure resource share is bounded in [0,1] // and respects the utilization threshold. DCS_DEBUG_ASSERT( share >= real_type(0) && share <= threshold && share <= real_type(1) ); //::std::cerr << "APP: " << ptr_vm->guest_system().application().id() << ", MACH: " << this->machine().id() << ", VM: " << ptr_vm->id() << ", WantedShare: " << share_it->second << ", GotShare: " << share << ::std::endl;//XXX ptr_vm->resource_share(category, share); DCS_DEBUG_TRACE("APP: " << ptr_vm->guest_system().application().id() << ", MACH: " << this->machine().id() << " - Assigned new share: VM: " << ptr_vm->name() << " (" << ptr_vm->id() << ") - Category: " << category << " - Threshold: " << threshold << " - Share Sum: " << share_sum << " ==> Wanted: " << share_it->second << " - Got: " << share);//XXX ::std::cerr << "[proportional_machine_controller] APP: " << ptr_vm->guest_system().application().id() << ", MACH: " << this->machine().id() << " - Assigned new share: VM: " << ptr_vm->name() << " (" << ptr_vm->id() << ") - Category: " << category << " - Threshold: " << threshold << " - Share Sum: " << share_sum << " ==> Wanted: " << share_it->second << " - Got: " << share << ::std::endl;//XXX #ifdef DCS_DES_CLOUD_EXP_OUTPUT_VM_SHARES detail::dump_vm_share<traits_type>(ptr_vm->id(), ptr_vm->guest_system().application().id(), ptr_vm->guest_system().id(), this->machine().id(), category, share_it->second, share); #endif // DCS_DES_CLOUD_EXP_OUTPUT_VM_SHARES } } } ++step; } while (step <= 2); // // DCS_DEBUG_TRACE("(" << this << ") END Do Processing CONTROL (Clock: " << ctx.simulated_time() << ")");//XXX }
bool run_matlab_command(::std::string const& cmd, ArgsT const& args, ConsumerT& consumer) { int pipefd[2]; // Create a pipe to let to communicate with MATLAB. // Specifically, we want to read the output from MATLAB. // So, the parent process read from the pipe, while the child process // write on it. if (::pipe(pipefd) == -1) { char const* err_str = ::strerror(errno); ::std::ostringstream oss; oss << "[dcs::des::cloud::detail::matlab::run_matlab_command] pipe(2) failed: " << ::std::string(err_str); throw ::std::runtime_error(oss.str()); } // // Install signal handlers // struct ::sigaction sig_act; // struct ::sigaction old_sigterm_act; // struct ::sigaction old_sigint_act; // //::memset(&sig_act, 0, sizeof(sig_act)); // ::sigemptyset(&sig_act.sa_mask); // sig_act.sa_flags = 0; // sig_act.sa_handler = self_type::process_signals; // ::sigaction(SIGTERM, &sig_act, &old_sigterm_act); // ::sigaction(SIGINT, &sig_act, &old_sigint_act); // Spawn a new process // Between fork() and execve() only async-signal-safe functions // must be called if multithreaded applications should be supported. // That's why the following code is executed before fork() is called. ::pid_t pid = ::fork(); // check: pid == -1 --> error if (pid == -1) { char const* err_str = ::strerror(errno); ::std::ostringstream oss; oss << "[dcs::des::cloud::detail::matlab::run_matlab_command] fork(2) failed: " << ::std::string(err_str); throw ::std::runtime_error(oss.str()); } if (pid == 0) { // The child // // Cancel signal handler set for parent // sig_act.sa_handler = SIG_DFL; // ::sigaction(SIGTERM, &sig_act, 0); // ::sigaction(SIGINT, &sig_act, 0); // Get the maximum number of files this process is allowed to open #if defined(F_MAXFD) int maxdescs = ::fcntl(-1, F_MAXFD, 0); if (maxdescs == -1) { #if defined(_SC_OPEN_MAX) maxdescs = ::sysconf(_SC_OPEN_MAX); #else ::rlimit limit; if (::getrlimit(RLIMIT_NOFILE, &limit) < 0) { char const* err_str = ::strerror(errno); ::std::ostringstream oss; oss << "[dcs::des::cloud::detail::matlab::run_matlab_command] getrlimit(2) failed: " << ::std::string(err_str); throw ::std::runtime_error(oss.str()); } maxdescs = limit.rlim_cur; #endif // _SC_OPEN_MAX } #else // F_MAXFD #if defined(_SC_OPEN_MAX) int maxdescs = ::sysconf(_SC_OPEN_MAX); #else // _SC_OPEN_MAX ::rlimit limit; if (::getrlimit(RLIMIT_NOFILE, &limit) < 0) { char const* err_str = ::strerror(errno); ::std::ostringstream oss; oss << "[dcs::des::cloud::detail::matlab::run_matlab_command] getrlimit(2) failed: " << ::std::string(err_str); throw ::std::runtime_error(oss.str()); } maxdescs = limit.rlim_cur; #endif // _SC_OPEN_MAX #endif // F_MAXFD if (maxdescs == -1) { maxdescs = 1024; } ::std::vector<bool> close_fd(maxdescs, true); // Associate the child's stdout to the pipe write fd. close_fd[STDOUT_FILENO] = false; if (pipefd[1] != STDOUT_FILENO) { if (::dup2(pipefd[1], STDOUT_FILENO) != STDOUT_FILENO) { char const* err_str = ::strerror(errno); ::std::ostringstream oss; oss << "[dcs::des::cloud::detail::matlab::run_matlab_command] dup2(2) failed: " << ::std::string(err_str); throw ::std::runtime_error(oss.str()); } } else { close_fd[pipefd[1]] = false; } // ::close(STDOUT_FILENO); // ::dup(pipefd[1]); // Check if the command already has path information ::std::string cmd_path; ::std::string cmd_name; typename ::std::string::size_type pos; pos = cmd.find_last_of('/'); if (pos != ::std::string::npos) { cmd_path = cmd.substr(0, pos); cmd_name = cmd.substr(pos+1); } //FIXME: use scoped_ptr in place of "new" ::std::size_t nargs = args.size()+1; char** argv = new char*[nargs + 2]; argv[0] = new char[cmd_name.size()+1]; ::std::strncpy(argv[0], cmd_name.c_str(), cmd_name.size()+1); // by convention, the first argument is always the command name typename ArgsT::size_type i(1); typename ArgsT::const_iterator end_it(args.end()); for (typename ArgsT::const_iterator it = args.begin(); it != end_it; ++it) { argv[i] = new char[it->size()+1]; ::std::strncpy(argv[i], it->c_str(), it->size()+1); ++i; } argv[nargs] = 0; //char** envp(0); // Close unused file descriptors #ifdef DCS_DEBUG // Keep standard error open for debug close_fd[STDERR_FILENO] = false; #endif // DCS_DEBUG for (int fd = 0; fd < maxdescs; ++fd) { if (close_fd[fd]) { ::close(fd); } } //[XXX] #ifdef DCS_DEBUG ::std::cerr << "Executing MATLAB: " << cmd;//XXX for (::std::size_t i=0; i < args.size(); ++i)//XXX {//XXX ::std::cerr << " " << args[i] << ::std::flush;//XXX }//XXX ::std::cerr << ::std::endl;//XXX #endif // DCS_DEBUG //[/XXX] //DCS_DEBUG_TRACE("Executing: " << cmd << " " << args[0] << " " << args[1] << " " << args[2] << " - " << args[3]); //::execve(cmd.c_str(), argv, envp); ::execvp(cmd.c_str(), argv); // Actually we should delete argv and envp data. As we must not // call any non-async-signal-safe functions though we simply exit. ::write(STDERR_FILENO, "execvp() failed\n", 17); //_exit(EXIT_FAILURE); _exit(127); } // The parent // // Associate the parent's stdin to the pipe read fd. ::close(pipefd[1]); // ::close(STDIN_FILENO); // ::dup(pipefd[0]); if (pipefd[0] != STDIN_FILENO) { if (::dup2(pipefd[0], STDIN_FILENO) != STDIN_FILENO) { char const* err_str = ::strerror(errno); ::std::ostringstream oss; oss << "[dcs::des::cloud::detail::matlab::run_matlab_command] dup2(2) failed: " << ::std::string(err_str); throw ::std::runtime_error(oss.str()); } ::close(pipefd[0]); } typedef ::boost::iostreams::file_descriptor_source fd_device_type; typedef ::boost::iostreams::stream_buffer<fd_device_type> fd_streambuf_type; //fd_device_type fd_src(pipefd[0], ::boost::iostreams::close_handle); fd_device_type fd_src(STDIN_FILENO, ::boost::iostreams::close_handle); fd_streambuf_type fd_buf(fd_src); ::std::istream is(&fd_buf); consumer(is); DCS_DEBUG_TRACE("END parsing MATLAB output");//XXX DCS_DEBUG_TRACE("IS state: " << is.good() << " - " << is.eof() << " - " << is.fail() << " - " << is.bad());//XXX // Wait the child termination (in order to prevent zombies) int status; // ::pid_t wait_pid; // wait_pid = ::wait(&status); // if (wait_pid != pid) // { // throw ::std::runtime_error("[dcs::des::cloud::detail::rls_miso_matlab_app_proxy::run_matlab] Unexpected child process."); // } if (::waitpid(pid, &status, 0) == -1) { char const* err_str = ::strerror(errno); ::std::ostringstream oss; oss << "[dcs::des::cloud::detail::matlab::run_matlab_command] waitpid(2) failed: " << ::std::string(err_str); throw ::std::runtime_error(oss.str()); } DCS_DEBUG_TRACE("MATLAB exited");//XXX bool ok(true); if (WIFEXITED(status)) { DCS_DEBUG_TRACE("MATLAB exited with a call to 'exit(" << WEXITSTATUS(status) << ")'");//XXX if (WEXITSTATUS(status)) { // status != 0 --> error in the execution ::std::clog << "[Warning] MATLAB command exited with status " << WEXITSTATUS(status) << ::std::endl; ok = false; } } else if (WIFSIGNALED(status)) { DCS_DEBUG_TRACE("MATLAB exited with a call to 'kill(" << WTERMSIG(status) << ")'");//XXX ::std::clog << "[Warning] MATLAB command received signal " << WTERMSIG(status) << ::std::endl; ok = false; } else { DCS_DEBUG_TRACE("MATLAB exited with an unexpected way");//XXX ok = false; } // // Restore signal handler // ::sigaction(SIGTERM, &old_sigterm_act, 0); // ::sigaction(SIGINT, &old_sigint_act, 0); return ok; }
private: void do_control() { typedef typename base_type::target_value_map::const_iterator target_iterator; typedef typename app_type::vm_pointer vm_pointer; DCS_DEBUG_TRACE("(" << this << ") BEGIN Do CONTROL - Count: " << ctl_count_ << "/" << ctl_skip_count_ << "/" << ctl_fail_count_); ++ctl_count_; bool skip_ctl = false; ::std::map<virtual_machine_performance_category,::std::vector<real_type> > cress; ::std::map<application_performance_category,real_type> rgains; ::std::vector<vm_pointer> vms = this->app().vms(); const ::std::size_t nvms = vms.size(); for (::std::size_t i = 0; i < nvms; ++i) { const virtual_machine_performance_category cat = cpu_util_virtual_machine_performance; const vm_pointer p_vm = vms[i]; // if (this->data_estimator(cat, vms[i]->id()).count() > 0) // { // //const real_type uh = this->data_estimator(cat, p_vm->id()).estimate(); // const real_type uh = this->data_smoother(cat, p_vm->id()).forecast(0); // const real_type c = p_vm->cpu_share(); // // cress[cat].push_back(c-uh); // } // else // { // // No observation collected during the last control interval // DCS_DEBUG_TRACE("No input observation collected during the last control interval -> Skip control"); // skip_ctl = true; // break; // } const real_type uh = this->data_smoother(cat, p_vm->id()).forecast(0); const real_type c = p_vm->cpu_share(); const real_type cres = c-uh; cress[cat].push_back(cres); DCS_DEBUG_TRACE("VM " << p_vm->id() << " - Performance Category: " << cat << " - Uhat(k): " << uh << " - C(k): " << c << " -> Cres(k+1): " << cres << " (Relative Cres(k+1): " << cres/c << ")");//XXX } if (!skip_ctl) { const target_iterator tgt_end_it = this->target_values().end(); for (target_iterator tgt_it = this->target_values().begin(); tgt_it != tgt_end_it; ++tgt_it) { const application_performance_category cat(tgt_it->first); // Compute a summary statistics of collected observation if (this->data_estimator(cat).count() > 0) { const real_type yh = this->data_estimator(cat).estimate(); const real_type yr = this->target_value(cat); switch (cat) { case response_time_application_performance: rgains[cat] = (yr-yh)/yr; break; case throughput_application_performance: rgains[cat] = (yh-yr)/yr; break; } DCS_DEBUG_TRACE("APP Performance Category: " << cat << " - Yhat(k): " << yh << " - R: " << yr << " -> Rgain(k+1): " << rgains.at(cat));//XXX } else { // No observation collected during the last control interval DCS_DEBUG_TRACE("No output observation collected during the last control interval -> Skip control"); skip_ctl = true; break; } #ifdef DCSXX_TESTBED_EXP_APP_MGR_RESET_ESTIMATION_EVERY_INTERVAL this->data_estimator(cat).reset(); #endif // DCSXX_TESTBED_EXP_APP_MGR_RESET_ESTIMATION_EVERY_INTERVAL } } if (!skip_ctl) { //FIXME: actually we only handle SISO systems DCS_ASSERT(cress.size() == 1 && rgains.size() == 1, DCS_EXCEPTION_THROW(::std::runtime_error, "Only SISO system are currently managed")); // Perform fuzzy control bool ok = false; ::std::vector<real_type> deltacs(nvms); try { for (::std::size_t i = 0; i < nvms; ++i) { vm_pointer p_vm = vms[i]; const real_type cres = cress.begin()->second.at(i); const real_type rgain = rgains.begin()->second; p_fuzzy_eng_->setInputValue(cres_fuzzy_var_name, cres/p_vm->cpu_share()); p_fuzzy_eng_->setInputValue(rgain_fuzzy_var_name, rgain); p_fuzzy_eng_->process(); const real_type deltac = p_fuzzy_eng_->getOutputValue(deltac_fuzzy_var_name); deltacs[i] = deltac; DCS_DEBUG_TRACE("VM " << vms[i]->id() << " -> DeltaC(k+1): " << deltacs.at(i));//XXX } ok = true; } catch (fl::Exception const& fe) { DCS_DEBUG_TRACE( "Caught exception: " << fe.what() ); ::std::ostringstream oss; oss << "Unable to compute optimal control: " << fe.what(); ::dcs::log_warn(DCS_LOGGING_AT, oss.str()); } catch (::std::exception const& e) { DCS_DEBUG_TRACE( "Caught exception: " << e.what() ); ::std::ostringstream oss; oss << "Unable to compute optimal control: " << e.what(); ::dcs::log_warn(DCS_LOGGING_AT, oss.str()); } // Apply fuzzy control results if (ok) { for (::std::size_t i = 0; i < nvms; ++i) { vm_pointer p_vm = vms[i]; const real_type old_share = p_vm->cpu_share(); const real_type new_share = ::std::max(::std::min(old_share+deltacs[i], 1.0), 0.0); DCS_DEBUG_TRACE("VM '" << p_vm->id() << "' - old-share: " << old_share << " - new-share: " << new_share); if (::std::isfinite(new_share) && !::dcs::math::float_traits<real_type>::essentially_equal(old_share, new_share)) { p_vm->cpu_share(new_share); DCS_DEBUG_TRACE("VM " << vms[i]->id() << " -> C(k+1): " << new_share);//XXX } } DCS_DEBUG_TRACE("Optimal control applied");//XXX } else { ++ctl_fail_count_; ::std::ostringstream oss; oss << "Control not applied: failed to solve the control problem"; ::dcs::log_warn(DCS_LOGGING_AT, oss.str()); } } else { ++ctl_skip_count_; } // Export to file if (p_dat_ofs_) { *p_dat_ofs_ << ::std::time(0) << ","; for (::std::size_t i = 0; i < nvms; ++i) { const vm_pointer p_vm = vms[i]; // check: p_vm != null DCS_DEBUG_ASSERT( p_vm ); if (i != 0) { *p_dat_ofs_ << ","; } *p_dat_ofs_ << p_vm->cpu_cap() << "," << p_vm->cpu_share(); } *p_dat_ofs_ << ","; const target_iterator tgt_end_it = this->target_values().end(); for (target_iterator tgt_it = this->target_values().begin(); tgt_it != tgt_end_it; ++tgt_it) { const application_performance_category cat = tgt_it->first; if (tgt_it != this->target_values().begin()) { *p_dat_ofs_ << ","; } const real_type yh = this->data_estimator(cat).estimate(); const real_type yr = tgt_it->second; const real_type yn = yh/yr; *p_dat_ofs_ << yh << "," << yn << "," << yr; } *p_dat_ofs_ << "," << ctl_count_ << "," << ctl_skip_count_ << "," << ctl_fail_count_; *p_dat_ofs_ << ::std::endl; } DCS_DEBUG_TRACE("(" << this << ") END Do CONTROL - Count: " << ctl_count_ << "/" << ctl_skip_count_ << "/" << ctl_fail_count_); }
private: void do_sample() { typedef typename in_sensor_map::const_iterator in_sensor_iterator; typedef typename out_sensor_map::const_iterator out_sensor_iterator; typedef ::std::vector<typename sensor_type::observation_type> obs_container; typedef typename obs_container::const_iterator obs_iterator; DCS_DEBUG_TRACE("(" << this << ") BEGIN Do SAMPLE - Count: " << ctl_count_ << "/" << ctl_skip_count_ << "/" << ctl_fail_count_); // Collect input values const in_sensor_iterator in_sens_end_it = in_sensors_.end(); for (in_sensor_iterator in_sens_it = in_sensors_.begin(); in_sens_it != in_sens_end_it; ++in_sens_it) { const virtual_machine_performance_category cat = in_sens_it->first; //const ::std::size_t n = in_sens_it->second.size(); //for (::std::size_t i = 0; i < n; ++i) //{ // sensor_pointer p_sens = in_sens_it->second.at(i); const typename in_sensor_map::mapped_type::const_iterator vm_end_it = in_sens_it->second.end(); for (typename in_sensor_map::mapped_type::const_iterator vm_it = in_sens_it->second.begin(); vm_it != vm_end_it; ++vm_it) { const vm_identifier_type vm_id = vm_it->first; sensor_pointer p_sens = vm_it->second; // check: p_sens != null DCS_DEBUG_ASSERT( p_sens ); p_sens->sense(); if (p_sens->has_observations()) { const obs_container obs = p_sens->observations(); const obs_iterator end_it = obs.end(); for (obs_iterator it = obs.begin(); it != end_it; ++it) { //this->data_estimator(cat, vm_id).collect(it->value()); this->data_smoother(cat, vm_id).smooth(it->value()); } } } } // Collect output values const out_sensor_iterator out_sens_end_it = out_sensors_.end(); for (out_sensor_iterator out_sens_it = out_sensors_.begin(); out_sens_it != out_sens_end_it; ++out_sens_it) { const application_performance_category cat = out_sens_it->first; sensor_pointer p_sens = out_sens_it->second; // check: p_sens != null DCS_DEBUG_ASSERT( p_sens ); p_sens->sense(); if (p_sens->has_observations()) { const obs_container obs = p_sens->observations(); const obs_iterator end_it = obs.end(); for (obs_iterator it = obs.begin(); it != end_it; ++it) { this->data_estimator(cat).collect(it->value()); } } } DCS_DEBUG_TRACE("(" << this << ") END Do SAMPLE - Count: " << ctl_count_ << "/" << ctl_skip_count_ << "/" << ctl_fail_count_); }
virtual_machines_placement<traits_type> do_placement(data_center_type const& dc) { DCS_DEBUG_TRACE("BEGIN Initial Placement");//XXX ::std::cerr << "[optimal_initial_placement] BEGIN Initial Placement" << ::std::endl;//XXX typedef typename traits_type::physical_machine_identifier_type physical_machine_identifier_type; typedef typename traits_type::virtual_machine_identifier_type virtual_machine_identifier_type; typedef ::std::map<virtual_machine_identifier_type,real_type> virtual_machine_utilization_map; typedef typename optimal_solver_type::physical_virtual_machine_map physical_virtual_machine_map; typedef typename physical_virtual_machine_map::const_iterator physical_virtual_machine_iterator; typedef typename optimal_solver_type::resource_share_container resource_share_container; typedef typename data_center_type::physical_machine_type physical_machine_type; typedef typename data_center_type::physical_machine_pointer physical_machine_pointer; typedef typename data_center_type::virtual_machine_type virtual_machine_type; typedef typename data_center_type::virtual_machine_pointer virtual_machine_pointer; typedef typename data_center_type::application_type application_type; typedef typename application_type::reference_physical_resource_type ref_resource_type; typedef typename application_type::reference_physical_resource_container ref_resource_container; typedef typename ref_resource_container::const_iterator ref_resource_iterator; virtual_machine_utilization_map vm_util_map; // Retrieve application performance info { typedef ::std::vector<virtual_machine_pointer> virtual_machine_container; typedef typename virtual_machine_container::const_iterator virtual_machine_iterator; virtual_machine_container vms(dc.active_virtual_machines()); virtual_machine_iterator vm_end_it(vms.end()); for (virtual_machine_iterator vm_it = vms.begin(); vm_it != vm_end_it; ++vm_it) { virtual_machine_pointer ptr_vm(*vm_it); // paranoid-check: null DCS_DEBUG_ASSERT( ptr_vm ); ref_resource_container rress(ptr_vm->guest_system().application().reference_resources()); ref_resource_iterator rress_end_it(rress.end()); for (ref_resource_iterator rress_it = rress.begin(); rress_it != rress_end_it; ++rress_it) { ref_resource_type res(*rress_it); //TODO: CPU resource category not yet handle in app simulation model and optimization problem DCS_ASSERT( res.category() == cpu_resource_category, DCS_EXCEPTION_THROW( ::std::runtime_error, "Resource categories other than CPU are not yet implemented." ) ); vm_util_map[ptr_vm->id()] = ptr_vm->guest_system().application().performance_model().tier_measure( ptr_vm->guest_system().id(), ::dcs::des::cloud::utilization_performance_measure ); ::std::cerr << "[optimal_initial_placement] VM: " << *ptr_vm << " - U: " << vm_util_map.at(ptr_vm->id()) << ::std::endl;//XXX } } } // Solve the optimization problem //optimal_solver_type solver; ptr_solver_->solve(dc, wp_, ws_, this->reference_share_penalty(), vm_util_map); // Check solution and act accordingly //FIXME: handle ref_penalty if (!ptr_solver_->result().solved()) { throw ::std::runtime_error("[dcs::des::cloud::optimal_initial_placement_strategy] Unable to solve optimal problem."); } virtual_machines_placement<traits_type> deployment; physical_virtual_machine_map pm_vm_map(ptr_solver_->result().placement()); //[XXX] ::std::cerr << "CHECK SOLVER INITIAL PLACEMENT" << ::std::endl;//XXX for (typename physical_virtual_machine_map::const_iterator it = ptr_solver_->result().placement().begin(); it != ptr_solver_->result().placement().end(); ++it)//XXX { //XXX ::std::cerr << "VM ID: " << (it->first.second) << " placed on PM ID: " << (it->first.first) << " with SHARE: " << ((it->second)[0].second) << ::std::endl;//XXX }//XXX //[/XXX] physical_virtual_machine_iterator pm_vm_end_it(pm_vm_map.end()); for (physical_virtual_machine_iterator pm_vm_it = pm_vm_map.begin(); pm_vm_it != pm_vm_end_it; ++pm_vm_it) { physical_machine_pointer ptr_pm(dc.physical_machine_ptr(pm_vm_it->first.first)); virtual_machine_pointer ptr_vm(dc.virtual_machine_ptr(pm_vm_it->first.second)); resource_share_container shares(pm_vm_it->second); //::std::cerr << "Going to migrate VM (" << pm_vm_it->first.second << "): " << *ptr_vm << " into PM (" << pm_vm_it->first.first << "): " << *ptr_pm << ::std::endl; //XXX deployment.place(*ptr_vm, *ptr_pm, shares.begin(), shares.end()); DCS_DEBUG_TRACE("Placed: VM(" << ptr_vm->id() << ") -> PM(" << ptr_pm->id() << ")");//XXX } ::std::cerr << "[optimal_initial_placement] END Initial Placement" << ::std::endl;//XXX DCS_DEBUG_TRACE("END Initial Placement ==> " << deployment);///XXX return deployment; }
::std::vector< partition_info<RealT> > operator()(::gtpack::cooperative_game<RealT> const& game, ::std::map< gtpack::cid_type, coalition_info<RealT> > const& visited_coalitions) { namespace alg = ::dcs::algorithm; // Generate all partitions and select the ones that are Pareto optimal ::std::vector< partition_info<RealT> > best_partitions; const ::std::vector<gtpack::player_type> players(game.players()); const ::std::size_t np(players.size()); alg::lexicographic_partition partition(np); ::std::vector<RealT> best_payoffs(np, ::std::numeric_limits<RealT>::quiet_NaN()); while (partition.has_next()) { typedef typename alg::partition_traits<bsid_type>::subset_container subset_container; typedef typename alg::partition_traits<bsid_type>::subset_const_iterator subset_iterator; subset_container subs; // Each subset is a collection of coalitions subs = alg::next_partition(players.begin(), players.end(), partition); DCS_DEBUG_TRACE("--- PARTITION: " << partition);//XXX partition_info<RealT> candidate_partition; subset_iterator sub_end_it(subs.end()); for (subset_iterator sub_it = subs.begin(); sub_it != sub_end_it; ++sub_it) { const gtpack::cid_type cid = gtpack::players_coalition<RealT>::make_id(sub_it->begin(), sub_it->end()); if (visited_coalitions.count(cid) == 0) { continue; } DCS_DEBUG_TRACE("--- COALITION: " << game.coalition(cid) << " (CID=" << cid << ")");//XXX candidate_partition.coalitions.insert(cid); ::std::vector<gtpack::player_type> coal_players(sub_it->begin(), sub_it->end()); for (::std::size_t p = 0; p < coal_players.size(); ++p) { const gtpack::player_type pid = coal_players[p]; if (visited_coalitions.at(cid).payoffs.count(pid) > 0) { candidate_partition.payoffs[pid] = visited_coalitions.at(cid).payoffs.at(pid); } else { candidate_partition.payoffs[pid] = ::std::numeric_limits<RealT>::quiet_NaN(); } } } // Check Pareto optimality bool pareto_optimal(true); // For all players $p$ for (std::size_t p = 0; p < np && pareto_optimal; ++p) { const gtpack::player_type pid(players[p]); if (::std::isnan(best_payoffs[p]) || candidate_partition.payoffs.at(pid) > best_payoffs[p]) { best_payoffs[p] = candidate_partition.payoffs.at(pid); } else { pareto_optimal = false; } } if (pareto_optimal) { best_partitions.push_back(candidate_partition); } } return best_partitions; }