00001 #ifndef _NICMODEL_H
00002 #define _NICMODEL_H
00003
00004 #include <sst/core/event.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;
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 cpu= configureLink("CPU", new Event::Handler<Nicmodel>(this,&Nicmodel::handle_cpu_events));
00193 if (cpu == NULL) {
00194 _NIC_MODEL_DBG(0, "The NIC model expects links to the CPU and the network "
00195 "named \"CPU\" and \"NETWORK\". CPU is missing!\n");
00196 _ABORT(Nicmodel, "Check the input XML file!\n");
00197 } else {
00198 _NIC_MODEL_DBG(1, "Added a link and a handler for the cpu\n");
00199 }
00200
00201
00202 net= configureLink("NETWORK", new Event::Handler<Nicmodel>(this,&Nicmodel::handle_nic_events));
00203 if (net == NULL) {
00204 _NIC_MODEL_DBG(0, "The NIC model expects links to the CPU and the network "
00205 "named \"CPU\" and \"NETWORK\". NETWORK is missing!\n");
00206 _ABORT(Nicmodel, "Check the input XML file!\n");
00207 } else {
00208 _NIC_MODEL_DBG(1, "Added a link and a handler for the network\n");
00209 }
00210
00211
00212 tc= registerTimeBase("1ns", true);
00213
00214
00215
00216 uQ= new UnexpectedQ();
00217 uQ->completion_link(cpu);
00218
00219
00220 pQ= new PostedQ();
00221 pQ->completion_link(cpu);
00222
00223
00224
00225
00226 gen_routes(my_rank, my_router, nic_model_debug, vrinfo);
00227 }
00228
00229 ~Nicmodel() {
00230 delete pQ;
00231 delete uQ;
00232 }
00233
00234 int
00235 get_my_rank(void)
00236 {
00237 return my_rank;
00238 }
00239
00240 int
00241 get_num_NICs(void)
00242 {
00243 return num_NICs;
00244 }
00245
00246 int
00247 get_nic_model_debug(void)
00248 {
00249 return nic_model_debug;
00250 }
00251
00252
00253 private:
00254
00255 Nicmodel(const Nicmodel &c);
00256 void handle_nic_events(Event *);
00257 void handle_cpu_events(Event *);
00258 void hton_params(netsim_params_t *params);
00259 void insert_graph_link(const char *from, const char *to);
00260
00261 Params_t params;
00262 Link *cpu;
00263 Link *net;
00264 int my_rank;
00265 int my_router;
00266 int num_NICs;
00267 int num_routers;
00268 int num_ports;
00269 int num_links;
00270 int num_item;
00271 char search_str[64];
00272 int nic_model_debug;
00273 PostedQ *pQ;
00274 UnexpectedQ *uQ;
00275 SimTime_t rcv_router_delays;
00276 long long rcv_msgs;
00277 long long rcv_total_hops;
00278 void *vrinfo;
00279
00280 TimeConverter *tc;
00281
00282 friend class boost::serialization::access;
00283 template<class Archive>
00284 void serialize(Archive & ar, const unsigned int version )
00285 {
00286 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Component);
00287 ar & BOOST_SERIALIZATION_NVP(cpu);
00288 ar & BOOST_SERIALIZATION_NVP(net);
00289 ar & BOOST_SERIALIZATION_NVP(my_rank);
00290 ar & BOOST_SERIALIZATION_NVP(my_router);
00291 ar & BOOST_SERIALIZATION_NVP(num_NICs);
00292 ar & BOOST_SERIALIZATION_NVP(num_routers);
00293 ar & BOOST_SERIALIZATION_NVP(num_ports);
00294 ar & BOOST_SERIALIZATION_NVP(num_links);
00295 ar & BOOST_SERIALIZATION_NVP(num_item);
00296 ar & BOOST_SERIALIZATION_NVP(search_str);
00297 ar & BOOST_SERIALIZATION_NVP(nic_model_debug);
00298 ar & BOOST_SERIALIZATION_NVP(pQ);
00299 ar & BOOST_SERIALIZATION_NVP(uQ);
00300 ar & BOOST_SERIALIZATION_NVP(rcv_router_delays);
00301 ar & BOOST_SERIALIZATION_NVP(rcv_msgs);
00302 ar & BOOST_SERIALIZATION_NVP(rcv_total_hops);
00303
00304 ar & BOOST_SERIALIZATION_NVP(tc);
00305 }
00306
00307 template<class Archive>
00308 friend void save_construct_data(Archive & ar,
00309 const Nicmodel * t,
00310 const unsigned int file_version)
00311 {
00312 _AR_DBG(Nicmodel,"\n");
00313 ComponentId_t id = t->getId();
00314 Params_t params = t->params;
00315 ar << BOOST_SERIALIZATION_NVP(id);
00316 ar << BOOST_SERIALIZATION_NVP(params);
00317 }
00318
00319 template<class Archive>
00320 friend void load_construct_data(Archive & ar,
00321 Nicmodel * t,
00322 const unsigned int file_version)
00323 {
00324 _AR_DBG(Nicmodel,"\n");
00325 ComponentId_t id;
00326 Params_t params;
00327 ar >> BOOST_SERIALIZATION_NVP(id);
00328 ar >> BOOST_SERIALIZATION_NVP(params);
00329 ::new(t)Nicmodel(id, params);
00330 }
00331 };
00332
00333 #endif