00001 #ifndef _NICMODEL_H
00002 #define _NICMODEL_H
00003
00004 #include <sst/core/eventFunctor.h>
00005 #include <sst/core/component.h>
00006 #include <sst/core/link.h>
00007 #include "netsim_model.h"
00008 #include "routing.h"
00009 #include "user_includes/netsim/netsim_internal.h"
00010
00011
00012 using namespace SST;
00013
00014 #define DBG_NIC_MODEL 1
00015 #if DBG_NIC_MODEL
00016 #define _NIC_MODEL_DBG(lvl, fmt, args...)\
00017 if (get_nic_model_debug() >= lvl) { \
00018 printf("%d:Nicmodel::%s():%d: " fmt, _debug_rank, __FUNCTION__, __LINE__, ## args); \
00019 }
00020 #else
00021 #define _NIC_MODEL_DBG(lvl, fmt, args...)
00022 #endif
00023
00024
00025 class Nicmodel : public Component {
00026 public:
00027 Nicmodel(ComponentId_t id, Params_t& params) :
00028 Component(id),
00029 params(params)
00030 {
00031 _NIC_MODEL_DBG(1, "NIC model component %lu is on rank %d\n", id, _debug_rank);
00032
00033
00034 Params_t::iterator it= params.begin();
00035
00036
00037 nic_model_debug= 0;
00038 my_rank= -1;
00039 my_router= -1;
00040 num_NICs= -1;
00041 num_routers= -1;
00042 num_ports= -1;
00043 num_links= -1;
00044 rcv_router_delays= 0.0;
00045 rcv_msgs= 0;;
00046 rcv_total_hops= 0;;
00047
00048 while (it != params.end()) {
00049 if (!it->first.compare("debug")) {
00050 sscanf(it->second.c_str(), "%d", &nic_model_debug);
00051 }
00052 if (!it->first.compare("rank")) {
00053 sscanf(it->second.c_str(), "%d", &my_rank);
00054 }
00055 if (!it->first.compare("num_NICs")) {
00056 sscanf(it->second.c_str(), "%d", &num_NICs);
00057 }
00058 if (!it->first.compare("num_routers")) {
00059 sscanf(it->second.c_str(), "%d", &num_routers);
00060 }
00061 if (!it->first.compare("num_ports")) {
00062 sscanf(it->second.c_str(), "%d", &num_ports);
00063 }
00064 if (!it->first.compare("num_links")) {
00065 sscanf(it->second.c_str(), "%d", &num_links);
00066 }
00067
00068 ++it;
00069 }
00070
00071 _NIC_MODEL_DBG(1, "My rank is %d/%d\n", my_rank, num_NICs);
00072 if ((my_rank < 0) || (my_rank >= num_NICs) || (num_NICs < 1)) {
00073 _ABORT(Nicmodel, "Check the input XML file! You need to specify an unique rank "
00074 "for each CPU and a total number of ranks.\n");
00075 }
00076
00077 _NIC_MODEL_DBG(1, "num_routers %d, num_ports %d, num_links %d\n",
00078 num_routers, num_ports, num_links);
00079 if ((num_routers < 1) || (num_ports < 1) || (num_links < 1)) {
00080 _ABORT(Nicmodel, "Check the input XML file! You need to specify num_routers, "
00081 "num_port, and num_links in the nic_params section!\n");
00082 }
00083
00084
00085
00086
00087 vrinfo= init_routing(num_routers, num_NICs);
00088 for (int rank= 0; rank < num_NICs; rank++) {
00089
00090 sprintf(search_str, "NIC%drouter", rank);
00091 it= params.begin();
00092 while (it != params.end()) {
00093 if (!it->first.compare(search_str)) {
00094 sscanf(it->second.c_str(), "%d", &num_item);
00095 NIC_table_insert_router(rank, num_item, vrinfo);
00096 if (rank == my_rank) {
00097
00098 my_router= num_item;
00099 _NIC_MODEL_DBG(1, "NIC with rank %d is attached to router %d\n",
00100 my_rank, my_router);
00101 }
00102 break;
00103 }
00104 it++;
00105 }
00106
00107
00108 sprintf(search_str, "NIC%dport", rank);
00109 it= params.begin();
00110 while (it != params.end()) {
00111 if (!it->first.compare(search_str)) {
00112 sscanf(it->second.c_str(), "%d", &num_item);
00113 if (num_item >= num_ports) {
00114 _ABORT(Nicmodel, "Port number %d for NIC %d, larger than num_ports %d\n",
00115 num_item, rank, num_ports);
00116 }
00117 NIC_table_insert_port(rank, num_item, vrinfo);
00118 break;
00119 }
00120 it++;
00121 }
00122 }
00123
00124 if (check_NIC_table(vrinfo)) {
00125 _ABORT(Nicmodel, "Each of the %d NICs must list its rank and the router and "
00126 "port it is attached to in the common <nic_params> section!\n", num_NICs);
00127 }
00128
00129
00130
00131
00132 for (int link= 0; link < num_links; link++) {
00133 int left_router, left_port;
00134 int right_router, right_port;
00135
00136
00137 sprintf(search_str, "Link%dLeftRouter", link);
00138 it= params.begin();
00139 while (it != params.end()) {
00140 if (!it->first.compare(search_str)) {
00141 sscanf(it->second.c_str(), "%d", &left_router);
00142 break;
00143 }
00144 it++;
00145 }
00146
00147
00148 sprintf(search_str, "Link%dLeftPort", link);
00149 it= params.begin();
00150 while (it != params.end()) {
00151 if (!it->first.compare(search_str)) {
00152 sscanf(it->second.c_str(), "%d", &left_port);
00153 break;
00154 }
00155 it++;
00156 }
00157
00158
00159 sprintf(search_str, "Link%dRightRouter", link);
00160 it= params.begin();
00161 while (it != params.end()) {
00162 if (!it->first.compare(search_str)) {
00163 sscanf(it->second.c_str(), "%d", &right_router);
00164 break;
00165 }
00166 it++;
00167 }
00168
00169
00170 sprintf(search_str, "Link%dRightPort", link);
00171 it= params.begin();
00172 while (it != params.end()) {
00173 if (!it->first.compare(search_str)) {
00174 sscanf(it->second.c_str(), "%d", &right_port);
00175 break;
00176 }
00177 it++;
00178 }
00179
00180 Adj_Matrix_insert(link, left_router, left_port, right_router, right_port, vrinfo);
00181
00182 }
00183
00184 if (my_rank == 0 && nic_model_debug > 1) {
00185 Adj_Matrix_print(vrinfo);
00186 }
00187
00188
00189
00190
00191
00192 cpuHandler= new EventHandler<Nicmodel, bool, Event *>
00193 (this, &Nicmodel::handle_cpu_events);
00194
00195 cpu= LinkAdd("CPU", cpuHandler);
00196 if (cpu == NULL) {
00197 _NIC_MODEL_DBG(0, "The NIC model expects links to the CPU and the network "
00198 "named \"CPU\" and \"NETWORK\". CPU is missing!\n");
00199 _ABORT(Nicmodel, "Check the input XML file!\n");
00200 } else {
00201 _NIC_MODEL_DBG(1, "Added a link and a handler for the cpu\n");
00202 }
00203
00204
00205 netHandler= new EventHandler<Nicmodel, bool, Event *>
00206 (this, &Nicmodel::handle_nic_events);
00207
00208 net= LinkAdd("NETWORK", netHandler);
00209 if (net == NULL) {
00210 _NIC_MODEL_DBG(0, "The NIC model expects links to the CPU and the network "
00211 "named \"CPU\" and \"NETWORK\". NETWORK is missing!\n");
00212 _ABORT(Nicmodel, "Check the input XML file!\n");
00213 } else {
00214 _NIC_MODEL_DBG(1, "Added a link and a handler for the network\n");
00215 }
00216
00217
00218 tc= registerTimeBase("1ns", true);
00219
00220
00221
00222 uQ= new UnexpectedQ();
00223 uQ->completion_link(cpu);
00224
00225
00226 pQ= new PostedQ();
00227 pQ->completion_link(cpu);
00228
00229
00230
00231
00232 gen_routes(my_rank, my_router, nic_model_debug, vrinfo);
00233 }
00234
00235 ~Nicmodel() {
00236 delete pQ;
00237 delete uQ;
00238 }
00239
00240 int
00241 get_my_rank(void)
00242 {
00243 return my_rank;
00244 }
00245
00246 int
00247 get_num_NICs(void)
00248 {
00249 return num_NICs;
00250 }
00251
00252 int
00253 get_nic_model_debug(void)
00254 {
00255 return nic_model_debug;
00256 }
00257
00258
00259 private:
00260
00261 Nicmodel(const Nicmodel &c);
00262 bool handle_nic_events(Event *);
00263 bool handle_cpu_events(Event *);
00264 void hton_params(netsim_params_t *params);
00265 void insert_graph_link(const char *from, const char *to);
00266
00267 EventHandler_t *cpuHandler;
00268 EventHandler_t *netHandler;
00269
00270 Params_t params;
00271 Link *cpu;
00272 Link *net;
00273 int my_rank;
00274 int my_router;
00275 int num_NICs;
00276 int num_routers;
00277 int num_ports;
00278 int num_links;
00279 int num_item;
00280 char search_str[64];
00281 int nic_model_debug;
00282 PostedQ *pQ;
00283 UnexpectedQ *uQ;
00284 double rcv_router_delays;
00285 long long rcv_msgs;
00286 long long rcv_total_hops;
00287 void *vrinfo;
00288
00289 TimeConverter *tc;
00290
00291 friend class boost::serialization::access;
00292 template<class Archive>
00293 void serialize(Archive & ar, const unsigned int version )
00294 {
00295 boost::serialization::base_object<Component>(*this);
00296 ar & BOOST_SERIALIZATION_NVP(cpuHandler);
00297 ar & BOOST_SERIALIZATION_NVP(netHandler);
00298 ar & BOOST_SERIALIZATION_NVP(cpu);
00299 ar & BOOST_SERIALIZATION_NVP(net);
00300 ar & BOOST_SERIALIZATION_NVP(my_rank);
00301 ar & BOOST_SERIALIZATION_NVP(my_router);
00302 ar & BOOST_SERIALIZATION_NVP(num_NICs);
00303 ar & BOOST_SERIALIZATION_NVP(num_routers);
00304 ar & BOOST_SERIALIZATION_NVP(num_ports);
00305 ar & BOOST_SERIALIZATION_NVP(num_links);
00306 ar & BOOST_SERIALIZATION_NVP(num_item);
00307 ar & BOOST_SERIALIZATION_NVP(search_str);
00308 ar & BOOST_SERIALIZATION_NVP(nic_model_debug);
00309 ar & BOOST_SERIALIZATION_NVP(pQ);
00310 ar & BOOST_SERIALIZATION_NVP(uQ);
00311 ar & BOOST_SERIALIZATION_NVP(rcv_router_delays);
00312 ar & BOOST_SERIALIZATION_NVP(rcv_msgs);
00313 ar & BOOST_SERIALIZATION_NVP(rcv_total_hops);
00314
00315 ar & BOOST_SERIALIZATION_NVP(tc);
00316 }
00317
00318 template<class Archive>
00319 friend void save_construct_data(Archive & ar,
00320 const Nicmodel * t,
00321 const unsigned int file_version)
00322 {
00323 _AR_DBG(Nicmodel,"\n");
00324 ComponentId_t id = t->_id;
00325 Params_t params = t->params;
00326 ar << BOOST_SERIALIZATION_NVP(id);
00327 ar << BOOST_SERIALIZATION_NVP(params);
00328 }
00329
00330 template<class Archive>
00331 friend void load_construct_data(Archive & ar,
00332 Nicmodel * t,
00333 const unsigned int file_version)
00334 {
00335 _AR_DBG(Nicmodel,"\n");
00336 ComponentId_t id;
00337 Params_t params;
00338 ar >> BOOST_SERIALIZATION_NVP(id);
00339 ar >> BOOST_SERIALIZATION_NVP(params);
00340 ::new(t)Nicmodel(id, params);
00341 }
00342 };
00343
00344 #endif