• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/routermodel/routermodel.h

00001 // Copyright 2009-2010 Sandia Corporation. Under the terms
00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
00003 // Government retains certain rights in this software.
00004 //
00005 // Copyright (c) 2009-2010, Sandia Corporation
00006 // All rights reserved.
00007 //
00008 // This file is part of the SST software package. For license
00009 // information, see the LICENSE file in the top level directory of the
00010 // distribution.
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             // Defaults
00048             router_model_debug= 0;
00049             num_ports= -1;
00050             hop_delay= 20;
00051             router_bw= 1200000000; // Bytes per second
00052             congestion_out_cnt= 0;
00053             congestion_out= 0;
00054             congestion_in_cnt= 0;
00055             congestion_in= 0;
00056 
00057             // Power modeling
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                 // Power modeling paramters
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             // Create a time converter for the NIC simulator.
00124             // TimeConverter *tc= registerTimeBase("1ns", true);
00125             // FIXME: I'm not sure this is the right way to do it. The router assumes that
00126             // the time base is 1ns....
00127 
00128             // for power
00129             TimeConverter *tc= registerTimeBase(frequency, true);
00130 
00131             // for power introspection
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                 //for introspection
00143                 registerMonitorInt("router_delay");
00144                 registerMonitorInt("local_message");
00145             }
00146 
00147 
00148             /* Attach the handler to each port */
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                     /* Push a dummy port, so port numbering and order in list match */
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             // Create a channel for "out of band" events sent to ourselves
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                 //set up floorplan and thermal tiles
00209                 power->setChip(params);
00210 
00211                 //set up architecture parameters
00212                 power->setTech(getId(), params, ROUTER, powerModel);
00213 
00214                 //reset all counts to zero
00215                 power->resetCounts(&mycounts);
00216             }
00217             return 0;
00218         }
00219 
00220 
00221         int
00222         Finish()
00223         {
00224             //power->printFloorplanAreaInfo();
00225             //std::cout << "area return from McPAT = " << power->estimateAreaMcPAT() << " mm^2" << std::endl;
00226             //power->printFloorplanPowerInfo();
00227             //power->printFloorplanThermalInfo();
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         // For power & introspection
00296         std::string frequency;
00297         std::string pushIntrospector;
00298         Pdissipation_t pdata, pstats;
00299         Power *power;
00300         // Over-specified struct that holds usage counts of its sub-components
00301         usagecounts_t mycounts;
00302 
00303         // totaldelay = congestion delay + generic router delay
00304         SimTime_t router_totaldelay;
00305 
00306         //number of intra-core messages
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             // FIXME: Do we need this? ar & BOOST_SERIALIZATION_NVP(tc);
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

Generated on Fri Oct 22 2010 11:02:28 for SST by  doxygen 1.7.1