aboutsummaryrefslogtreecommitdiff
path: root/src/Inputs.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Inputs.cc')
-rw-r--r--src/Inputs.cc166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/Inputs.cc b/src/Inputs.cc
new file mode 100644
index 0000000..de81aec
--- /dev/null
+++ b/src/Inputs.cc
@@ -0,0 +1,166 @@
+#include "Inputs.hpp"
+
+#include <algorithm>
+#include <iostream>
+#include <fstream>
+
+Inputs::Inputs(std::string node_name){
+ // Here we doing all the boring stuff
+ FILE* input_file = fopen(INPUTS_FILE, "rb");
+ char input_file_buffer[JSON_BUFFER_SIZE];
+ rapidjson::FileReadStream is(input_file, input_file_buffer, sizeof(input_file_buffer));
+ d.ParseStream(is);
+ fclose(input_file);
+
+ // Init all variables
+ is_sender=d["nodes"][node_name.c_str()]["is_sender"].GetBool();
+ use_hint=d["nodes"][node_name.c_str()]["use_hint"].GetBool();
+ data_size=d["nodes"][node_name.c_str()]["data_size"].GetInt();
+ extended=d["extended"].GetBool();
+
+ // Instantiate wake_ts
+ for(auto& v:d["nodes"][node_name.c_str()]["wake_ts"].GetArray()){
+ wake_ts.push_back(v.GetDouble());
+ }
+
+ // Instantiate wake_duration
+ for(auto& v:d["nodes"][node_name.c_str()]["wake_duration"].GetArray()){
+ wake_duration.push_back(v.GetDouble());
+ }
+
+ // Identity check
+ if(wake_ts.size()!=wake_duration.size()){
+ std::cerr << "Invalid node configuration: wake_ts.size() != wake_duration.size()" <<std::endl;
+ exit(1);
+ }
+ if(!std::is_sorted(wake_ts.begin(),wake_ts.end())){
+ std::cerr << "Invalid node configuration: wake_ts is not sorted" <<std::endl;
+ exit(1);
+ }
+
+ // Ensure events are merged
+ MergeEvents();
+}
+
+void Inputs::MergeEvents(){
+ for(int i=0;i<(wake_ts.size()-1);i++){
+ double cur_ts=wake_ts[i];
+ double next_ts=wake_ts[i+1];
+ double cur_duration=wake_duration[i];
+ double next_duration=wake_duration[i+1];
+ // If we should merge then
+ if((cur_ts+cur_duration)>=next_ts){
+ // Create variable for convenience
+ double start=cur_ts;
+ double end=std::max(cur_ts+cur_duration,next_ts+next_duration);
+ wake_duration[i]=end-start;
+ // Now remove next event
+ wake_ts.erase(wake_ts.begin() + i + 1);
+ wake_duration.erase(wake_duration.begin() + i +1);
+ // This is not optimal. Yet it is simple :D
+ MergeEvents();
+ }
+ }
+}
+
+double Inputs::GetNextTS(){
+ // Ensure the caller is smart
+ if(wake_duration.size()<2){
+ std::cerr << "You are trying to access to the next timestamp but it does not exists" <<std::endl;
+ exit(1);
+ }
+ return wake_ts[1];
+}
+
+double Inputs::GetNextDuration(){
+ // Ensure the caller is smart
+ if(wake_duration.size()<2){
+ std::cerr << "You are trying to access to the next duration but it does not exists" <<std::endl;
+ exit(1);
+ }
+ return wake_duration[1];
+}
+
+void Inputs::GotoNextEvent(){
+ wake_ts.erase(wake_ts.begin());
+ wake_duration.erase(wake_duration.begin());
+}
+
+void Inputs::DumpEvents(){
+ std::cout << "Timestamps: ";
+ for(auto a:wake_ts){
+ std::cout << std::setw(5) << a << " ";
+ }
+ std::cout << std::endl;
+ std::cout << "Wake Durations: ";
+ for(auto a:wake_duration){
+ std::cout << std::setw(5) << a << " ";
+ }
+ std::cout << std::endl;
+}
+
+void Inputs::AddEvent(double ts, double duration){
+ // First handle timestamp
+ int pos=0;
+ for(auto it = std::begin(wake_ts); it != std::end(wake_ts); ++it) {
+ if(*it>=ts){
+ wake_ts.insert(it,ts);
+ break;
+ }
+ pos++;
+ }
+
+ // Ensure that ts and duration should not go to the end
+ if(pos==wake_ts.size()){
+ wake_ts.push_back(ts);
+ wake_duration.push_back(duration);
+ }
+ else {
+ // Handle durations here
+ int pos2=0;
+ for(auto it = std::begin(wake_duration); it != std::end(wake_duration); ++it) {
+ if(pos==pos2){
+ wake_duration.insert(it,duration);
+ break;
+ }
+ else if (it+1==std::end(wake_duration)) {
+ wake_duration.push_back(duration);
+ }
+ pos2++;
+ }
+ }
+ // Don't forget
+ MergeEvents();
+}
+
+void Inputs::GeneratePlatform(std::string p){
+
+ // The boring stuff
+ FILE* input_file = fopen(INPUTS_FILE, "rb");
+ char input_file_buffer[JSON_BUFFER_SIZE];
+ rapidjson::FileReadStream is(input_file, input_file_buffer, sizeof(input_file_buffer));
+ rapidjson::Document d;
+ d.ParseStream(is);
+ fclose(input_file);
+
+ // Write platform file
+ std::ofstream pf;
+ pf.open (p);
+ pf << "<?xml version='1.0'?>\n";
+ pf << "<!DOCTYPE platform SYSTEM \"http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd\">\n";
+ pf << "<platform version=\"4.1\">\n <AS id=\"AS0\" routing=\"Cluster\">\n";
+ pf << " <link id=\"link\" bandwidth=\"1Mbps\" latency=\"0ms\" sharing_policy=\"SHARED\"></link>\n";
+ for (Value::ConstMemberIterator itr = d["nodes"].MemberBegin(); itr != d["nodes"].MemberEnd(); ++itr)
+ {
+ std::string name=itr->name.GetString();
+ double power_on=d["nodes"][itr->name.GetString()]["power_on"].GetDouble();
+ double power_off=d["nodes"][itr->name.GetString()]["power_off"].GetDouble();
+ // Create node
+ pf << " <host id=\""<<name<<"\" speed=\"100.0f,100.0f\" pstate=\"0\">\n";
+ pf << " <prop id=\"wattage_per_state\" value=\""<< power_off<<":"<<power_off<<", "<< power_on<<":"<<power_on<<"\" />\n";
+ pf << " <prop id=\"wattage_off\" value=\"0\" />\n </host>\n";
+ pf << " <host_link id=\""<<name<<"\" up=\"link\" down=\"link\"/>\n";
+ }
+ pf << " </AS>\n</platform>\n";
+ pf.close();
+} \ No newline at end of file