Avoid using directly surf_action->set_bound to modify action's bound.
Actual bound is defined by CPU model, for cas01 is the min of:
- user's bound
- requested_core*speed*scale.
Explicitly deny the use of user_bound_ for ptask and cpuTI. We need
proper tests to verify their behavior.
state_ = State::RUNNING;
if (not MC_is_active() && not MC_record_replay_is_active()) {
if (hosts_.size() == 1) {
- surf_action_ = hosts_.front()->get_cpu()->execution_start(flops_amounts_.front());
+ surf_action_ = hosts_.front()->get_cpu()->execution_start(flops_amounts_.front(), bound_);
surf_action_->set_sharing_penalty(sharing_penalty_);
surf_action_->set_category(get_tracing_category());
-
- if (bound_ > 0) {
- surf_action_->set_bound(bound_);
- surf_action_->set_user_bound(bound_);
- }
} else {
// get the model from first host since we have only 1 by now
auto host_model = hosts_.front()->get_netpoint()->get_englobing_zone()->get_host_model();
{
if (not MC_is_active() && not MC_record_replay_is_active()) {
resource::Action* old_action = this->surf_action_;
- resource::Action* new_action = to->get_cpu()->execution_start(old_action->get_cost());
+ resource::Action* new_action = to->get_cpu()->execution_start(old_action->get_cost(), old_action->get_user_bound());
new_action->set_remains(old_action->get_remains());
new_action->set_activity(this);
new_action->set_sharing_penalty(old_action->get_sharing_penalty());
get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(),
get_core_count() * speed_.scale * speed_.peak);
+
while (const auto* var = get_constraint()->get_variable(&elem)) {
const auto* action = static_cast<CpuCas01Action*>(var->get_id());
+ double bound = action->requested_core() * speed_.scale * speed_.peak;
+ if (action->get_user_bound() > 0) {
+ bound = std::min(bound, action->get_user_bound());
+ }
- get_model()->get_maxmin_system()->update_variable_bound(action->get_variable(),
- action->requested_core() * speed_.scale * speed_.peak);
+ get_model()->get_maxmin_system()->update_variable_bound(action->get_variable(), bound);
}
CpuImpl::on_speed_change();
}
/** @brief Start a new execution on this CPU lasting @param size flops and using one core */
-CpuAction* CpuCas01::execution_start(double size)
+CpuAction* CpuCas01::execution_start(double size, double user_bound)
{
- return new CpuCas01Action(get_model(), size, not is_on(), speed_.scale * speed_.peak, get_constraint());
+ return execution_start(size, 1, user_bound);
}
-CpuAction* CpuCas01::execution_start(double size, int requested_cores)
+CpuAction* CpuCas01::execution_start(double size, int requested_cores, double user_bound)
{
- return new CpuCas01Action(get_model(), size, not is_on(), speed_.scale * speed_.peak, get_constraint(),
- requested_cores);
+ auto* action =
+ new CpuCas01Action(get_model(), size, not is_on(), speed_.scale * speed_.peak, get_constraint(), requested_cores);
+ action->set_user_bound(user_bound);
+ if (user_bound > 0 && user_bound < action->get_bound()) {
+ get_model()->get_maxmin_system()->update_variable_bound(action->get_variable(), user_bound);
+ }
+
+ return action;
}
CpuAction* CpuCas01::sleep(double duration)
duration = std::max(duration, sg_surf_precision);
XBT_IN("(%s,%g)", get_cname(), duration);
- auto* action = new CpuCas01Action(get_model(), 1.0, not is_on(), speed_.scale * speed_.peak, get_constraint());
+ auto* action = new CpuCas01Action(get_model(), 1.0, not is_on(), speed_.scale * speed_.peak, get_constraint(), 1);
// FIXME: sleep variables should not consume 1.0 in System::expand()
action->set_max_duration(duration);
CpuCas01(const CpuCas01&) = delete;
CpuCas01& operator=(const CpuCas01&) = delete;
void apply_event(profile::Event* event, double value) override;
- CpuAction* execution_start(double size) override;
- CpuAction* execution_start(double size, int requested_cores) override;
+ CpuAction* execution_start(double size, double user_bound) override;
+ CpuAction* execution_start(double size, int requested_cores, double user_bound) override;
CpuAction* sleep(double duration) override;
bool is_used() const override;
* Action *
**********/
class CpuCas01Action : public CpuAction {
- friend CpuAction* CpuCas01::execution_start(double size);
- friend CpuAction* CpuCas01::sleep(double duration);
-
public:
- CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm::Constraint* constraint,
- int requested_core = 1);
+ CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm::Constraint* constraint, int requested_core);
CpuCas01Action(const CpuCas01Action&) = delete;
CpuCas01Action& operator=(const CpuCas01Action&) = delete;
int requested_core() const;
* @brief Execute some quantity of computation
*
* @param size The value of the processing amount (in flop) needed to process
+ * @param user_bound User's bound for execution speed
* @return The CpuAction corresponding to the processing
*/
- virtual CpuAction* execution_start(double size) = 0;
+ virtual CpuAction* execution_start(double size, double user_bound) = 0;
/**
* @brief Execute some quantity of computation on more than one core
*
* @param size The value of the processing amount (in flop) needed to process
* @param requested_cores The desired amount of cores. Must be >= 1
+ * @param user_bound User's bound for execution speed
* @return The CpuAction corresponding to the processing
*/
- virtual CpuAction* execution_start(double size, int requested_cores) = 0;
+ virtual CpuAction* execution_start(double size, int requested_cores, double user_bound) = 0;
/**
* @brief Make a process sleep for duration (in seconds)
last_update_ = now;
}
-CpuAction* CpuTi::execution_start(double size)
+CpuAction* CpuTi::execution_start(double size, double user_bound)
{
XBT_IN("(%s,%g)", get_cname(), size);
+ xbt_assert(user_bound <= 0, "Invalid user bound (%lf) in CPU TI model", user_bound);
auto* action = new CpuTiAction(this, size);
action_set_.push_back(*action); // Actually start the action
void update_remaining_amount(double now);
bool is_used() const override;
- CpuAction* execution_start(double size) override;
- CpuAction* execution_start(double, int) override
+ CpuAction* execution_start(double size, double user_bound) override;
+ CpuAction* execution_start(double, int, double) override
{
THROW_UNIMPLEMENTED;
return nullptr;
kernel::resource::Action* action = nullptr;
auto net_model = host_list[0]->get_netpoint()->get_englobing_zone()->get_network_model();
if ((host_list.size() == 1) && (has_cost(bytes_amount, 0) <= 0) && (has_cost(flops_amount, 0) > 0)) {
- action = host_list[0]->get_cpu()->execution_start(flops_amount[0]);
+ action = host_list[0]->get_cpu()->execution_start(flops_amount[0], rate);
} else if ((host_list.size() == 1) && (has_cost(flops_amount, 0) <= 0)) {
action = net_model->communicate(host_list[0], host_list[0], bytes_amount[0], rate);
} else if ((host_list.size() == 2) && (has_cost(flops_amount, 0) <= 0) && (has_cost(flops_amount, 1) <= 0)) {
* Resource *
************/
-kernel::resource::CpuAction* CpuL07::execution_start(double size)
+kernel::resource::CpuAction* CpuL07::execution_start(double size, double user_bound)
{
std::vector<s4u::Host*> host_list = {get_iface()};
+ xbt_assert(user_bound <= 0, "User bound not supported by ptask model");
auto* flops_amount = new double[host_list.size()]();
flops_amount[0] = size;
kernel::resource::CpuAction* CpuL07::sleep(double duration)
{
- auto* action = static_cast<L07Action*>(execution_start(1.0));
+ auto* action = static_cast<L07Action*>(execution_start(1.0, -1));
action->set_max_duration(duration);
action->set_suspend_state(kernel::resource::Action::SuspendStates::SLEEPING);
get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), 0.0);
bool is_used() const override;
void apply_event(kernel::profile::Event* event, double value) override;
- kernel::resource::CpuAction* execution_start(double size) override;
- kernel::resource::CpuAction* execution_start(double, int) override
+ kernel::resource::CpuAction* execution_start(double size, double user_bound) override;
+ kernel::resource::CpuAction* execution_start(double, int, double) override
{
THROW_UNIMPLEMENTED;
return nullptr;
double latency_;
double rate_;
- friend CpuAction* CpuL07::execution_start(double size);
+ friend CpuAction* CpuL07::execution_start(double size, double user_bound);
friend CpuAction* CpuL07::sleep(double duration);
friend CpuAction* HostL07Model::execute_parallel(const std::vector<s4u::Host*>& host_list, const double* flops_amount,
const double* bytes_amount, double rate);
simgrid::s4u::Host* hostB = sg_host_by_name("Cpu B");
/* Let's do something on it */
- const simgrid::kernel::resource::Action* actionA = hostA->get_cpu()->execution_start(1000.0);
- const simgrid::kernel::resource::Action* actionB = hostB->get_cpu()->execution_start(1000.0);
+ const simgrid::kernel::resource::Action* actionA = hostA->get_cpu()->execution_start(1000.0, -1);
+ const simgrid::kernel::resource::Action* actionB = hostB->get_cpu()->execution_start(1000.0, -1);
const simgrid::kernel::resource::Action* actionC = hostB->get_cpu()->sleep(7.32);
simgrid::kernel::resource::Action::State stateActionA = actionA->get_state();
simgrid::s4u::Host* hostB = sg_host_by_name("Cpu B");
/* Let's do something on it */
- hostA->get_cpu()->execution_start(1000.0);
- hostB->get_cpu()->execution_start(1000.0);
+ hostA->get_cpu()->execution_start(1000.0, -1);
+ hostB->get_cpu()->execution_start(1000.0, -1);
hostB->get_cpu()->sleep(7.32);
const_sg_netzone_t as_zone = sg_zone_get_by_name("AS0");