00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _ROUTERMODEL_H
00014 #define _ROUTERMODEL_H
00015
00016 #include <sst/core/event.h>
00017 #include <sst/core/link.h>
00018 #include <sst/core/introspectedComponent.h>
00019 #include "../power/power.h"
00020
00021
00022 using namespace SST;
00023
00024 #define DBG_ROUTER_MODEL 1
00025 #if DBG_ROUTER_MODEL
00026 #define _ROUTER_MODEL_DBG(lvl, fmt, args...)\
00027 if (router_model_debug >= lvl) { \
00028 printf("%d:Routermodel::%s():%d: " fmt, _debug_rank, __FUNCTION__, __LINE__, ## args); \
00029 }
00030 #else
00031 #define _ROUTER_MODEL_DBG(lvl, fmt, args...)
00032 #endif
00033
00034
00035
00036 #define MAX_LINK_NAME (16)
00037
00038
00039 class Routermodel : public IntrospectedComponent {
00040 public:
00041 Routermodel(ComponentId_t id, Params_t& params) :
00042 IntrospectedComponent(id),
00043 params(params),
00044 frequency("1ns")
00045 {
00046 Params_t::iterator it= params.begin();
00047
00048 router_model_debug= 0;
00049 num_ports= -1;
00050 hop_delay= 20;
00051 router_bw= 1200000000;
00052 congestion_out_cnt= 0;
00053 congestion_out= 0;
00054 congestion_in_cnt= 0;
00055 congestion_in= 0;
00056
00057
00058 router_totaldelay= 0;
00059 ifModelPower= false;
00060 num_local_message= 0;
00061
00062
00063
00064 while (it != params.end()) {
00065 _ROUTER_MODEL_DBG(1, "Router %s: key=%s value=%s\n", component_name.c_str(),
00066 it->first.c_str(), it->second.c_str());
00067
00068 if (!it->first.compare("debug")) {
00069 sscanf(it->second.c_str(), "%d", &router_model_debug);
00070 }
00071
00072 else if (!it->first.compare("hop_delay")) {
00073 sscanf(it->second.c_str(), "%lud", (uint64_t *)&hop_delay);
00074 }
00075
00076 else if (!it->first.compare("bw")) {
00077 sscanf(it->second.c_str(), "%lud", (uint64_t *)&router_bw);
00078 }
00079
00080 else if (!it->first.compare("component_name")) {
00081 component_name= it->second;
00082 _ROUTER_MODEL_DBG(1, "Component name for ID %lu is \"%s\"\n", id,
00083 component_name.c_str());
00084 }
00085
00086 else if (!it->first.compare("num_ports")) {
00087 sscanf(it->second.c_str(), "%d", &num_ports);
00088 }
00089
00090
00091 else if (!it->first.compare("frequency")) {
00092 frequency= it->second;
00093 }
00094
00095 else if (!it->first.compare("push_introspector")) {
00096 pushIntrospector= it->second;
00097 }
00098
00099 else if (!it->first.compare("router_power_model")) {
00100 if (!it->second.compare("McPAT")) {
00101 powerModel= McPAT;
00102 ifModelPower= true;
00103 _ROUTER_MODEL_DBG(1, "%s: Power modeling enabled, using McPAT\n",
00104 component_name.c_str());
00105 } else if (!it->second.compare("ORION")) {
00106 powerModel= ORION;
00107 ifModelPower= true;
00108 _ROUTER_MODEL_DBG(1, "%s: Power modeling enabled, using ORION\n",
00109 component_name.c_str());
00110 } else {
00111 _abort(Routermodel, "Unknown power model!\n");
00112 }
00113 }
00114
00115 ++it;
00116 }
00117
00118
00119 if (num_ports < 1) {
00120 _abort(Routermodel, "Need to define the num_ports parameter!\n");
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 TimeConverter *tc= registerTimeBase(frequency, true);
00130
00131
00132 if (ifModelPower) {
00133 registerClock(frequency, new Clock::Handler<Routermodel>
00134 (this, &Routermodel::pushData));
00135
00136 registerMonitorDouble("current_power");
00137 registerMonitorDouble("leakage_power");
00138 registerMonitorDouble("runtime_power");
00139 registerMonitorDouble("total_power");
00140 registerMonitorDouble("peak_power");
00141
00142
00143 registerMonitorInt("router_delay");
00144 registerMonitorInt("local_message");
00145 }
00146
00147
00148
00149 for (int i= 0; i < num_ports; i++) {
00150 port_t new_port;
00151 char link_name[MAX_LINK_NAME];
00152
00153 sprintf(link_name, "Link%dname", i);
00154 it= params.begin();
00155 while (it != params.end()) {
00156 if (!it->first.compare(link_name)) {
00157 break;
00158 }
00159 it++;
00160 }
00161
00162 if (it != params.end()) {
00163 strcpy(link_name, it->second.c_str());
00164 new_port.link= configureLink(link_name, new Event::Handler<Routermodel,int>
00165 (this, &Routermodel::handle_port_events, i));
00166 new_port.link->setDefaultTimeBase(tc);
00167 _ROUTER_MODEL_DBG(2, "Added handler for port %d, link \"%s\", on router %s\n",
00168 i, link_name, component_name.c_str());
00169 } else {
00170
00171 strcpy(link_name, "Unused_port");
00172 new_port.link= NULL;
00173 _ROUTER_MODEL_DBG(2, "Recorded unused port %d, link \"%s\", on router %s\n",
00174 i, link_name, component_name.c_str());
00175 }
00176
00177 new_port.cnt_in= 0;
00178 new_port.cnt_out= 0;
00179 new_port.next_out= 0;
00180 new_port.next_in= 0;
00181 port.push_back(new_port);
00182 }
00183
00184 _ROUTER_MODEL_DBG(1, "Router model component \"%s\" is on rank %d\n",
00185 component_name.c_str(), _debug_rank);
00186
00187
00188 self_link= configureSelfLink("Me", new Event::Handler<Routermodel>
00189 (this, &Routermodel::handle_self_events));
00190 if (self_link == NULL) {
00191 _ABORT(Ghost_pattern, "That was no good!\n");
00192 } else {
00193 _ROUTER_MODEL_DBG(2, "Added a self link and a handler on router %s\n",
00194 component_name.c_str());
00195 }
00196
00197 self_link->setDefaultTimeBase(tc);
00198
00199 }
00200
00201
00202 int
00203 Setup()
00204 {
00205 if (ifModelPower) {
00206 power = new Power(getId());
00207
00208
00209 power->setChip(params);
00210
00211
00212 power->setTech(getId(), params, ROUTER, powerModel);
00213
00214
00215 power->resetCounts(&mycounts);
00216 }
00217 return 0;
00218 }
00219
00220
00221 int
00222 Finish()
00223 {
00224
00225
00226
00227
00228 return 0;
00229 }
00230
00231
00232 uint64_t
00233 getIntData(int dataID, int index=0)
00234 {
00235 switch(dataID) {
00236 case router_delay:
00237 return ((uint64_t)router_totaldelay);
00238 break;
00239
00240 case local_message:
00241 return ( num_local_message);
00242 break;
00243
00244 default:
00245 return 0;
00246 break;
00247 }
00248 }
00249
00250
00251 double
00252 getDoubleData(int dataID, int index=0)
00253 {
00254 switch(dataID) {
00255 case current_power:
00256 return ((double)median(pdata.currentPower));
00257 break;
00258
00259 case leakage_power:
00260 return ((double)median(pdata.leakagePower));
00261 break;
00262
00263 case runtime_power:
00264 return ((double)median(pdata.runtimeDynamicPower));
00265 break;
00266
00267 case total_power:
00268 return ((double)median(pdata.totalEnergy));
00269 break;
00270
00271 case peak_power:
00272 return ((double)median(pdata.peak));
00273 break;
00274
00275 default:
00276 return 0;
00277 break;
00278 }
00279 }
00280
00281
00282
00283 private:
00284
00285 Routermodel(const Routermodel &c);
00286 void handle_port_events(Event *, int in_port);
00287 void handle_self_events(Event *);
00288 Link *initPort(int port, char *link_name);
00289
00290 Params_t params;
00291
00292 SimTime_t hop_delay;
00293 std::string component_name;
00294
00295
00296 std::string frequency;
00297 std::string pushIntrospector;
00298 Pdissipation_t pdata, pstats;
00299 Power *power;
00300
00301 usagecounts_t mycounts;
00302
00303
00304 SimTime_t router_totaldelay;
00305
00306
00307 uint64_t num_local_message;
00308
00309 pmodel powerModel;
00310 bool ifModelPower;
00311 bool pushData(Cycle_t);
00312
00313
00314 typedef struct port_t {
00315 Link *link;
00316 long long int cnt_in;
00317 long long int cnt_out;
00318 SimTime_t next_out;
00319 SimTime_t next_in;
00320 } port_t;
00321 std::vector<port_t> port;
00322
00323 Link *self_link;
00324 int num_ports;
00325 int router_model_debug;
00326 uint64_t router_bw;
00327 SimTime_t congestion_out;
00328 long long int congestion_out_cnt;
00329 SimTime_t congestion_in;
00330 long long int congestion_in_cnt;
00331
00332
00333 friend class boost::serialization::access;
00334 template<class Archive>
00335 void serialize(Archive & ar, const unsigned int version )
00336 {
00337 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Component);
00338 ar & BOOST_SERIALIZATION_NVP(params);
00339
00340 }
00341
00342 template<class Archive>
00343 friend void save_construct_data(Archive & ar,
00344 const Routermodel * t,
00345 const unsigned int file_version)
00346 {
00347 _AR_DBG(Routermodel,"\n");
00348 ComponentId_t id = t->getId();
00349 Params_t params = t->params;
00350 ar << BOOST_SERIALIZATION_NVP(id);
00351 ar << BOOST_SERIALIZATION_NVP(params);
00352 }
00353
00354 template<class Archive>
00355 friend void load_construct_data(Archive & ar,
00356 Routermodel * t,
00357 const unsigned int file_version)
00358 {
00359 _AR_DBG(Routermodel,"\n");
00360 ComponentId_t id;
00361 Params_t params;
00362 ar >> BOOST_SERIALIZATION_NVP(id);
00363 ar >> BOOST_SERIALIZATION_NVP(params);
00364 ::new(t)Routermodel(id, params);
00365 }
00366 };
00367
00368 #endif