Commit f54a11a1 authored by Millian Poquet's avatar Millian Poquet

Pstate changes can now be done on machine ranges

parent 864ce776
......@@ -131,12 +131,12 @@ IPMessage::~IPMessage()
} break;
case IPMessageType::SWITCHED_ON:
{
PStateModificationMessage * msg = (PStateModificationMessage *) data;
SwitchONMessage * msg = (SwitchONMessage *) data;
delete msg;
} break;
case IPMessageType::SWITCHED_OFF:
{
PStateModificationMessage * msg = (PStateModificationMessage *) data;
SwitchOFFMessage * msg = (SwitchOFFMessage *) data;
delete msg;
} break;
case IPMessageType::WAITING_DONE:
......
......@@ -60,8 +60,8 @@ struct SchedulingAllocationMessage
struct PStateModificationMessage
{
int machine;
int new_pstate;
MachineRange machine_ids; //! The IDs of the machines on which the pstate should be changed
int new_pstate; //! The pstate the machines should be put into
};
struct NOPMeLaterMessage
......@@ -69,6 +69,18 @@ struct NOPMeLaterMessage
double target_time;
};
struct SwitchONMessage
{
int machine_id;
int new_pstate;
};
struct SwitchOFFMessage
{
int machine_id;
int new_pstate;
};
struct IPMessage
{
~IPMessage();
......@@ -102,7 +114,8 @@ struct KillerProcessArguments
struct SwitchPStateProcessArguments
{
BatsimContext * context;
PStateModificationMessage * message;
int machine_id;
int new_pstate;
};
struct JobSubmitterProcessArguments
......
......@@ -2,7 +2,7 @@
#include <vector>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string.hpp>
#include <simgrid/msg.h>
......@@ -112,3 +112,42 @@ string MachineRange::to_string_elements(const string &sep)
return boost::algorithm::join(machine_id_strings, sep);
}
MachineRange MachineRange::from_string_hyphen(const string &str, const string &sep, const string &joiner, const string & error_prefix)
{
MachineRange res;
// Let us do a split by sep to get all the parts
vector<string> parts;
boost::split(parts, str, boost::is_any_of(sep), boost::token_compress_on);
for (const string & part : parts)
{
// Since each machineIDk can either be a single machine or a closed interval, let's try to split on joiner
vector<string> interval_parts;
boost::split(interval_parts, part, boost::is_any_of(joiner), boost::token_compress_on);
xbt_assert(interval_parts.size() >= 1 && interval_parts.size() <= 2,
"%s: the MIDk '%s' should either be a single machine ID"
" (syntax: MID to represent the machine ID MID) or a closed interval (syntax: MIDa-MIDb to represent"
" the machine interval [MIDA,MIDb])", error_prefix.c_str(), part.c_str());
if (interval_parts.size() == 1)
{
int machine_id = std::stoi(interval_parts[0]);
res.insert(machine_id);
}
else
{
int machineIDa = std::stoi(interval_parts[0]);
int machineIDb = std::stoi(interval_parts[1]);
xbt_assert(machineIDa <= machineIDb, "%s: the MIDk '%s' is composed of two"
" parts (1:%d and 2:%d) but the first value must be lesser than or equal to the second one",
error_prefix.c_str(), part.c_str(), machineIDa, machineIDb);
res.insert(MachineRange::Interval::closed(machineIDa, machineIDb));
}
}
return res;
}
......@@ -38,4 +38,7 @@ public:
std::string to_string_brackets(const std::string & union_str = "∪", const std::string & opening_bracket = "[", const std::string & closing_bracket = "]", const std::string & sep = ",");
std::string to_string_hyphen(const std::string & sep = ",", const std::string & joiner = "-");
std::string to_string_elements(const std::string & sep = ",");
public:
static MachineRange from_string_hyphen(const std::string & str, const std::string & sep = ",", const std::string & joiner = "-", const std::string & error_prefix = "Invalid machine range string");
};
......@@ -359,38 +359,44 @@ int request_reply_scheduler_process(int argc, char *argv[])
vector<string> parts3;
boost::split(parts3, parts2[2], boost::is_any_of("="), boost::token_compress_on);
xbt_assert(parts3.size() == 2, "Invalid event received ('%s'): invalid pstate modification message content ('%s'): it must be"
" of type M=P where M is a machine number and P a pstate number of machine M", event_string.c_str(), parts2[2].c_str());
" formated like M=P where M is a machine range (1,2,3,6,7 or 1-3,6-7 for example) and P a pstate number of machines M",
event_string.c_str(), parts2[2].c_str());
int machineID = std::stoi(parts3[0]);
int pstate = std::stoi(parts3[1]);
xbt_assert(context->machines.exists(machineID), "Invalid event received ('%s'): machine %d does not exist", event_string.c_str(), machineID);
Machine * machine = context->machines[machineID];
xbt_assert(machine->state == MachineState::IDLE || machine->state == MachineState::SLEEPING,
"Invalid event received ('%s'): machine %d's pstate can only be changed while the"
" machine is idle or sleeping, which is not the case now.", event_string.c_str(), machineID);
xbt_assert(context->machines[machineID]->has_pstate(pstate), "Invalid event received ('%s'): machine %d has no pstate %d", event_string.c_str(), machineID, pstate);
string error_prefix = "Invalid pstate modification message content ('" + event_string + "')";
message->machine_ids = MachineRange::from_string_hyphen(parts3[0], ",", "-", error_prefix);
int current_pstate = MSG_host_get_pstate(machine->host);
xbt_assert(machine->has_pstate(current_pstate));
if (machine->pstates[current_pstate] == PStateType::COMPUTATION_PSTATE)
{
xbt_assert(machine->pstates[pstate] == PStateType::COMPUTATION_PSTATE ||
machine->pstates[pstate] == PStateType::SLEEP_PSTATE, "Invalid event received ('%s'): asked to switch machine %d ('%s') from"
" pstate %d (a computation one) to pstate %d (not a computation pstate nor a sleep pstate), which is forbidden",
event_string.c_str(), machineID, machine->name.c_str(), current_pstate, pstate);
}
else if (machine->pstates[current_pstate] == PStateType::SLEEP_PSTATE)
for (auto machine_it = message->machine_ids.elements_begin(); machine_it != message->machine_ids.elements_end(); ++machine_it)
{
xbt_assert(machine->pstates[pstate] == PStateType::COMPUTATION_PSTATE, "Invalid event received ('%s'): asked to switch machine %d ('%s') from"
" pstate %d (a sleep pstate) to pstate %d (not a computation pstate), which is forbidden",
event_string.c_str(), machineID, machine->name.c_str(), current_pstate, pstate);
int machine_id = *machine_it;
xbt_assert(context->machines.exists(machine_id), "%s: the machine %d does not exist", error_prefix.c_str(), machine_id);
Machine * machine = context->machines[machine_id];
xbt_assert(machine->state == MachineState::IDLE || machine->state == MachineState::SLEEPING,
"%s: machine %d's pstate can only be changed while the"
" machine is idle or sleeping, which is not the case now", error_prefix.c_str(), machine_id);
xbt_assert(machine->has_pstate(pstate), "%s: machine %d has no pstate %d", error_prefix.c_str(), machine_id, pstate);
int current_pstate = MSG_host_get_pstate(machine->host);
xbt_assert(machine->has_pstate(current_pstate));
if (machine->pstates[current_pstate] == PStateType::COMPUTATION_PSTATE)
{
xbt_assert(machine->pstates[pstate] == PStateType::COMPUTATION_PSTATE ||
machine->pstates[pstate] == PStateType::SLEEP_PSTATE, "%s: asked to switch machine %d ('%s') from"
" pstate %d (a computation one) to pstate %d (not a computation pstate nor a sleep pstate), which is forbidden",
error_prefix.c_str(), machine_id, machine->name.c_str(), current_pstate, pstate);
}
else if (machine->pstates[current_pstate] == PStateType::SLEEP_PSTATE)
{
xbt_assert(machine->pstates[pstate] == PStateType::COMPUTATION_PSTATE, "%s: asked to switch machine %d ('%s') from"
" pstate %d (a sleep pstate) to pstate %d (not a computation pstate), which is forbidden",
error_prefix.c_str(), machine_id, machine->name.c_str(), current_pstate, pstate);
}
}
message->machine = machineID;
message->new_pstate = pstate;
send_message("server", IPMessageType::PSTATE_MODIFICATION, (void*) message);
} break; // End of case received_stamp == PSTATE_SET
......
......@@ -14,8 +14,8 @@ int switch_on_machine_process(int argc, char *argv[])
SwitchPStateProcessArguments * args = (SwitchPStateProcessArguments *) MSG_process_get_data(MSG_process_self());
int machineID = args->message->machine;
int pstate = args->message->new_pstate;
int machineID = args->machine_id;
int pstate = args->new_pstate;
xbt_assert(args->context->machines.exists(machineID));
Machine * machine = args->context->machines[machineID];
......@@ -54,7 +54,11 @@ int switch_on_machine_process(int argc, char *argv[])
machine->state = MachineState::IDLE;
send_message("server", IPMessageType::SWITCHED_ON, (void *) args->message);
SwitchONMessage * msg = new SwitchONMessage;
msg->machine_id = args->machine_id;
msg->new_pstate = args->new_pstate;
send_message("server", IPMessageType::SWITCHED_ON, (void *) msg);
delete args;
return 0;
}
......@@ -66,8 +70,8 @@ int switch_off_machine_process(int argc, char *argv[])
SwitchPStateProcessArguments * args = (SwitchPStateProcessArguments *) MSG_process_get_data(MSG_process_self());
int machineID = args->message->machine;
int pstate = args->message->new_pstate;
int machineID = args->machine_id;
int pstate = args->new_pstate;
xbt_assert(args->context->machines.exists(machineID));
Machine * machine = args->context->machines[machineID];
......@@ -105,7 +109,11 @@ int switch_off_machine_process(int argc, char *argv[])
machine->state = MachineState::SLEEPING;
send_message("server", IPMessageType::SWITCHED_OFF, (void *) args->message);
SwitchOFFMessage * msg = new SwitchOFFMessage;
msg->machine_id = args->machine_id;
msg->new_pstate = args->new_pstate;
send_message("server", IPMessageType::SWITCHED_OFF, (void *) msg);
delete args;
return 0;
}
......@@ -128,61 +128,63 @@ int uds_server_process(int argc, char *argv[])
xbt_assert(task_data->data != nullptr);
PStateModificationMessage * message = (PStateModificationMessage *) task_data->data;
Machine * machine = context->machines[message->machine];
int curr_pstate = MSG_host_get_pstate(machine->host);
if (machine->pstates[curr_pstate] == PStateType::COMPUTATION_PSTATE)
for (auto machine_it = message->machine_ids.elements_begin(); machine_it != message->machine_ids.elements_end(); ++machine_it)
{
if (machine->pstates[message->new_pstate] == PStateType::COMPUTATION_PSTATE)
const int machine_id = *machine_it;
Machine * machine = context->machines[machine_id];
int curr_pstate = MSG_host_get_pstate(machine->host);
if (machine->pstates[curr_pstate] == PStateType::COMPUTATION_PSTATE)
{
XBT_INFO("Switching machine %d ('%s') pstate : %d -> %d.", machine->id,
machine->name.c_str(), curr_pstate, message->new_pstate);
MSG_host_set_pstate(machine->host, message->new_pstate);
context->pstate_tracer.add_pstate_change(MSG_get_clock(), machine->id, message->new_pstate);
xbt_assert(MSG_host_get_pstate(machine->host) == message->new_pstate);
send_buffer += "|" + std::to_string(MSG_get_clock()) + ":p:" +
std::to_string(machine->id) + "=" + std::to_string(message->new_pstate);
XBT_DEBUG( "Message to send to scheduler : '%s'", send_buffer.c_str());
if (machine->pstates[message->new_pstate] == PStateType::COMPUTATION_PSTATE)
{
XBT_INFO("Switching machine %d ('%s') pstate : %d -> %d.", machine->id,
machine->name.c_str(), curr_pstate, message->new_pstate);
MSG_host_set_pstate(machine->host, message->new_pstate);
context->pstate_tracer.add_pstate_change(MSG_get_clock(), machine->id, message->new_pstate);
xbt_assert(MSG_host_get_pstate(machine->host) == message->new_pstate);
send_buffer += "|" + std::to_string(MSG_get_clock()) + ":p:" +
std::to_string(machine->id) + "=" + std::to_string(message->new_pstate);
XBT_DEBUG("Message to send to scheduler : '%s'", send_buffer.c_str());
}
else if (machine->pstates[message->new_pstate] == PStateType::SLEEP_PSTATE)
{
machine->state = MachineState::TRANSITING_FROM_COMPUTING_TO_SLEEPING;
SwitchPStateProcessArguments * args = new SwitchPStateProcessArguments;
args->context = context;
args->machine_id = machine_id;
args->new_pstate = message->new_pstate;
string pname = "switch ON " + to_string(machine_id);
MSG_process_create(pname.c_str(), switch_off_machine_process, (void*)args, machine->host);
++nb_switching_machines;
}
else
XBT_ERROR("Switching from a communication pstate to an invalid pstate on machine %d ('%s') : %d -> %d",
machine->id, machine->name.c_str(), curr_pstate, message->new_pstate);
}
else if (machine->pstates[message->new_pstate] == PStateType::SLEEP_PSTATE)
else if (machine->pstates[curr_pstate] == PStateType::SLEEP_PSTATE)
{
machine->state = MachineState::TRANSITING_FROM_COMPUTING_TO_SLEEPING;
xbt_assert(machine->pstates[message->new_pstate] == PStateType::COMPUTATION_PSTATE,
"Switching from a sleep pstate to a non-computation pstate on machine %d ('%s') : %d -> %d, which is forbidden",
machine->id, machine->name.c_str(), curr_pstate, message->new_pstate);
machine->state = MachineState::TRANSITING_FROM_SLEEPING_TO_COMPUTING;
SwitchPStateProcessArguments * args = new SwitchPStateProcessArguments;
args->context = context;
args->message = new PStateModificationMessage;
args->message->machine = message->machine;
args->message->new_pstate = message->new_pstate;
args->machine_id = machine_id;
args->new_pstate = message->new_pstate;
string pname = "switch ON " + to_string(message->machine);
MSG_process_create(pname.c_str(), switch_off_machine_process, (void*)args, machine->host);
string pname = "switch OFF " + to_string(machine_id);
MSG_process_create(pname.c_str(), switch_on_machine_process, (void*)args, machine->host);
++nb_switching_machines;
}
else
XBT_ERROR("Switching from a communication pstate to an invalid pstate on machine %d ('%s') : %d -> %d",
machine->id, machine->name.c_str(), curr_pstate, message->new_pstate);
}
else if (machine->pstates[curr_pstate] == PStateType::SLEEP_PSTATE)
{
xbt_assert(machine->pstates[message->new_pstate] == PStateType::COMPUTATION_PSTATE,
"Switching from a sleep pstate to a non-computation pstate on machine %d ('%s') : %d -> %d, which is forbidden",
machine->id, machine->name.c_str(), curr_pstate, message->new_pstate);
machine->state = MachineState::TRANSITING_FROM_SLEEPING_TO_COMPUTING;
SwitchPStateProcessArguments * args = new SwitchPStateProcessArguments;
args->context = context;
args->message = new PStateModificationMessage;
args->message->machine = message->machine;
args->message->new_pstate = message->new_pstate;
string pname = "switch OFF " + to_string(message->machine);
MSG_process_create(pname.c_str(), switch_on_machine_process, (void*)args, machine->host);
++nb_switching_machines;
XBT_ERROR("Machine %d ('%s') has an invalid pstate : %d", machine->id, machine->name.c_str(), curr_pstate);
}
else
XBT_ERROR("Machine %d ('%s') has an invalid pstate : %d", machine->id, machine->name.c_str(), curr_pstate);
} break; // end of case PSTATE_MODIFICATION
......@@ -283,10 +285,10 @@ int uds_server_process(int argc, char *argv[])
case IPMessageType::SWITCHED_ON:
{
xbt_assert(task_data->data != nullptr);
PStateModificationMessage * message = (PStateModificationMessage *) task_data->data;
SwitchONMessage * message = (SwitchONMessage *) task_data->data;
xbt_assert(context->machines.exists(message->machine));
Machine * machine = context->machines[message->machine];
xbt_assert(context->machines.exists(message->machine_id));
Machine * machine = context->machines[message->machine_id];
xbt_assert(MSG_host_get_pstate(machine->host) == message->new_pstate);
send_buffer += "|" + std::to_string(MSG_get_clock()) + ":p:" +
......@@ -299,10 +301,10 @@ int uds_server_process(int argc, char *argv[])
case IPMessageType::SWITCHED_OFF:
{
xbt_assert(task_data->data != nullptr);
PStateModificationMessage * message = (PStateModificationMessage *) task_data->data;
SwitchOFFMessage * message = (SwitchOFFMessage *) task_data->data;
xbt_assert(context->machines.exists(message->machine));
Machine * machine = context->machines[message->machine];
xbt_assert(context->machines.exists(message->machine_id));
Machine * machine = context->machines[message->machine_id];
xbt_assert(MSG_host_get_pstate(machine->host) == message->new_pstate);
send_buffer += "|" + std::to_string(MSG_get_clock()) + ":p:" +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment