diff options
Diffstat (limited to 'simulations/src/Inputs.cc')
| -rw-r--r-- | simulations/src/Inputs.cc | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/simulations/src/Inputs.cc b/simulations/src/Inputs.cc new file mode 100644 index 0000000..8c3ac9c --- /dev/null +++ b/simulations/src/Inputs.cc @@ -0,0 +1,184 @@ +#include "Inputs.hpp" + +#include <algorithm> +#include <iostream> +#include <fstream> + +Inputs::Inputs(std::string node_name){ + // Here we do 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(); + seed=d["seed"].GetInt(); + hint_size=d["hint_size"].GetInt(); + n_nodes=d["nodes"].MemberCount(); + latency=d["latency"].GetDouble(); + + // 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()<1){ + std::cerr << "Invalid node configuration: wake_ts.size() == 0" <<std::endl; + exit(1); + } + 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 that 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 that 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=\"Full\">\n"; + pf << " <link id=\"link\" bandwidth=\""<<d["bitrate"].GetString()<<"\" 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_off=d["nodes"][itr->name.GetString()]["power_off"].GetDouble(); + double power_on=d["nodes"][itr->name.GetString()]["power_on"].GetDouble(); + double power_rx=power_on+d["nodes"][itr->name.GetString()]["power_rx"].GetDouble(); + double power_tx=power_on+d["nodes"][itr->name.GetString()]["power_tx"].GetDouble(); + + // Create node + pf << " <host id=\""<<name<<"\" speed=\"100.0f,100.0f,100.0f,100.0f\" pstate=\"0\">\n"; + pf << " <prop id=\"wattage_per_state\" value=\""<< power_off<<":"<<power_off<<", "<< power_on<<":"<<power_on<<", "<<power_rx<<":"<<power_rx<<", "<<power_tx<<":"<<power_tx<<"\" />\n"; + pf << " <prop id=\"wattage_off\" value=\"0\" />\n </host>\n"; + } + for (Value::ConstMemberIterator src = d["nodes"].MemberBegin(); src != d["nodes"].MemberEnd(); ++src) + { + for (Value::ConstMemberIterator dst = d["nodes"].MemberBegin(); dst != d["nodes"].MemberEnd(); ++dst) + { + if(src->name.GetString() != dst->name.GetString()) + pf << " <route src=\""<<src->name.GetString()<<"\" dst=\""<<dst->name.GetString()<<"\" symmetrical=\"no\"><link_ctn id=\"link\"/></route>\n"; + } + } + pf << " </AS>\n</platform>\n"; + pf.close(); +}
\ No newline at end of file |
