00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _GHOST_PATTERN_H
00014 #define _GHOST_PATTERN_H
00015
00016 #include <sst/core/event.h>
00017 #include <sst/core/component.h>
00018 #include <sst/core/link.h>
00019 #include "pattern_common.h"
00020
00021 using namespace SST;
00022
00023 #define DBG_GHOST_PATTERN 1
00024 #if DBG_GHOST_PATTERN
00025 #define _GHOST_PATTERN_DBG(lvl, fmt, args...)\
00026 if (ghost_pattern_debug >= lvl) { \
00027 printf("%d:Ghost_pattern::%s():%4d: " fmt, _debug_rank, __FUNCTION__, __LINE__, ## args); \
00028 }
00029 #else
00030 #define _GHOST_PATTERN_DBG(lvl, fmt, args...)
00031 #endif
00032
00033 typedef enum {INIT,
00034 COMPUTE,
00035 WAIT,
00036 DONE,
00037 CHCKPT,
00038 SAVE_ENVELOPE,
00039 LOG_MSG1,
00040 LOG_MSG2,
00041 LOG_MSG3,
00042 LOG_MSG4
00043 } state_t;
00044
00045
00046
00047 class Ghost_pattern : public Component {
00048 public:
00049 Ghost_pattern(ComponentId_t id, Params_t& params) :
00050 Component(id),
00051 params(params)
00052 {
00053
00054 Params_t::iterator it= params.begin();
00055
00056
00057 ghost_pattern_debug= 0;
00058 my_rank= -1;
00059 net_latency= 0;
00060 net_bandwidth= 0;
00061 node_latency= 0;
00062 node_bandwidth= 0;
00063 compute_time= 0;
00064 application_end_time= 0;
00065 exchange_msg_len= 128;
00066 cores= -1;
00067 chckpt_method= CHCKPT_NONE;
00068 chckpt_interval= 0;
00069 envelope_size= 0;
00070 chckpt_size= 0;
00071 msg_write_time= 0;
00072
00073
00074 execution_time= 0;
00075 msg_wait_time= 0;
00076 chckpt_time= 0;
00077 timestep_cnt= 0;
00078 state= INIT;
00079 rcv_cnt= 0;
00080 save_ENVELOPE_cnt= 0;
00081 application_time_so_far= 0;
00082 chckpt_steps= 1;
00083 application_done= FALSE;
00084 num_chckpts= 0;
00085 total_rcvs= 0;
00086
00087
00088
00089 registerExit();
00090
00091 while (it != params.end()) {
00092 _GHOST_PATTERN_DBG(2, "[%3d] key \"%s\", value \"%s\"\n", my_rank,
00093 it->first.c_str(), it->second.c_str());
00094
00095 if (!it->first.compare("debug")) {
00096 sscanf(it->second.c_str(), "%d", &ghost_pattern_debug);
00097 }
00098
00099 if (!it->first.compare("rank")) {
00100 sscanf(it->second.c_str(), "%d", &my_rank);
00101 }
00102
00103 if (!it->first.compare("x_dim")) {
00104 sscanf(it->second.c_str(), "%d", &x_dim);
00105 }
00106
00107 if (!it->first.compare("y_dim")) {
00108 sscanf(it->second.c_str(), "%d", &y_dim);
00109 }
00110
00111 if (!it->first.compare("NoC_x_dim")) {
00112 sscanf(it->second.c_str(), "%d", &NoC_x_dim);
00113 }
00114
00115 if (!it->first.compare("NoC_y_dim")) {
00116 sscanf(it->second.c_str(), "%d", &NoC_y_dim);
00117 }
00118
00119 if (!it->first.compare("cores")) {
00120 sscanf(it->second.c_str(), "%d", &cores);
00121 }
00122
00123 if (!it->first.compare("net_latency")) {
00124 sscanf(it->second.c_str(), "%lu", &net_latency);
00125 }
00126
00127 if (!it->first.compare("net_bandwidth")) {
00128 sscanf(it->second.c_str(), "%lu", &net_bandwidth);
00129 }
00130
00131 if (!it->first.compare("node_latency")) {
00132 sscanf(it->second.c_str(), "%lu", &node_latency);
00133 }
00134
00135 if (!it->first.compare("node_bandwidth")) {
00136 sscanf(it->second.c_str(), "%lu", &node_bandwidth);
00137 }
00138
00139 if (!it->first.compare("compute_time")) {
00140 sscanf(it->second.c_str(), "%lu", &compute_time);
00141 }
00142
00143 if (!it->first.compare("application_end_time")) {
00144 sscanf(it->second.c_str(), "%lu", &application_end_time);
00145 }
00146
00147 if (!it->first.compare("exchange_msg_len")) {
00148 sscanf(it->second.c_str(), "%d", &exchange_msg_len);
00149 }
00150
00151 if (!it->first.compare("chckpt_method")) {
00152 if (!it->second.compare("none")) {
00153 chckpt_method= CHCKPT_NONE;
00154 } else if (!it->second.compare("coordinated")) {
00155 chckpt_method= CHCKPT_COORD;
00156 } else if (!it->second.compare("uncoordinated")) {
00157 chckpt_method= CHCKPT_UNCOORD;
00158 } else if (!it->second.compare("distributed")) {
00159 chckpt_method= CHCKPT_RAID;
00160 }
00161 }
00162
00163 if (!it->first.compare("chckpt_interval")) {
00164 sscanf(it->second.c_str(), "%lu", &chckpt_interval);
00165 }
00166
00167 if (!it->first.compare("envelope_size")) {
00168 sscanf(it->second.c_str(), "%d", &envelope_size);
00169 }
00170
00171 if (!it->first.compare("msg_write_time")) {
00172 sscanf(it->second.c_str(), "%lu", &msg_write_time);
00173 }
00174
00175 if (!it->first.compare("chckpt_size")) {
00176 sscanf(it->second.c_str(), "%d", &chckpt_size);
00177 }
00178
00179 ++it;
00180 }
00181
00182
00183
00184 tc= registerTimeBase("1ns", true);
00185
00186
00187 net= configureLink("NETWORK", new Event::Handler<Ghost_pattern>
00188 (this, &Ghost_pattern::handle_net_events));
00189 if (net == NULL) {
00190 _GHOST_PATTERN_DBG(1, "There is no network...\n");
00191 } else {
00192 net->setDefaultTimeBase(tc);
00193 _GHOST_PATTERN_DBG(2, "[%3d] Added a link and a handler for the Network\n", my_rank);
00194 }
00195
00196
00197 NoC= configureLink("NoC", new Event::Handler<Ghost_pattern>
00198 (this, &Ghost_pattern::handle_NoC_events));
00199 if (NoC == NULL) {
00200 _GHOST_PATTERN_DBG(1, "There is no NoC...\n");
00201 } else {
00202 NoC->setDefaultTimeBase(tc);
00203 _GHOST_PATTERN_DBG(2, "[%3d] Added a link and a handler for the NoC\n", my_rank);
00204 }
00205
00206
00207 self_link= configureSelfLink("Me", new Event::Handler<Ghost_pattern>
00208 (this, &Ghost_pattern::handle_self_events));
00209 if (self_link == NULL) {
00210 _ABORT(Ghost_pattern, "That was no good!\n");
00211 } else {
00212 _GHOST_PATTERN_DBG(2, "[%3d] Added a self link and a handler\n", my_rank);
00213 }
00214
00215
00216 nvram= configureLink("NVRAM", new Event::Handler<Ghost_pattern>
00217 (this, &Ghost_pattern::handle_nvram_events));
00218 if (nvram == NULL) {
00219 _GHOST_PATTERN_DBG(0, "The ghost pattern generator expects a link named \"NVRAM\"\n");
00220 _ABORT(Ghost_pattern, "Check the input XML file!\n");
00221 } else {
00222 _GHOST_PATTERN_DBG(2, "[%3d] Added a link and a handler for the NVRAM\n", my_rank);
00223 }
00224
00225
00226 storage= configureLink("STORAGE", new Event::Handler<Ghost_pattern>
00227 (this, &Ghost_pattern::handle_storage_events));
00228 if (storage == NULL) {
00229 _GHOST_PATTERN_DBG(0, "The ghost pattern generator expects a link named \"STORAGE\"\n");
00230 _ABORT(Ghost_pattern, "Check the input XML file!\n");
00231 } else {
00232 _GHOST_PATTERN_DBG(2, "[%3d] Added a link and a handler for the storage\n", my_rank);
00233 }
00234
00235 self_link->setDefaultTimeBase(tc);
00236 nvram->setDefaultTimeBase(tc);
00237 storage->setDefaultTimeBase(tc);
00238
00239
00240
00241 common= new Patterns();
00242 if (!common->init(x_dim, y_dim, NoC_x_dim, NoC_y_dim, my_rank, cores, net, self_link,
00243 NoC, nvram, storage,
00244 net_latency, net_bandwidth, node_latency, node_bandwidth,
00245 chckpt_method, chckpt_size, chckpt_interval, envelope_size)) {
00246 _ABORT(Ghost_pattern, "Patterns->init() failed!\n");
00247 }
00248
00249
00250
00251
00252
00253 int logical_width= x_dim * NoC_x_dim * cores;
00254 int logical_height= y_dim * NoC_y_dim;
00255 int myX= my_rank % logical_width;
00256 int myY= my_rank / logical_width;
00257 if (my_rank == 0) {
00258 printf("||| Arranging ranks as a %d * %d logical mesh\n",
00259 logical_width, logical_height);
00260 }
00261
00262 right= ((myX + 1) % (logical_width)) + (myY * (logical_width));
00263 left= ((myX - 1 + (logical_width)) % (logical_width)) + (myY * (logical_width));
00264 down= myX + ((myY + 1) % logical_height) * (logical_width);
00265 up= myX + ((myY - 1 + logical_height) % logical_height) * (logical_width);
00266
00267
00268
00269
00270
00271
00272
00273
00274 switch (chckpt_method) {
00275 case CHCKPT_NONE:
00276 break;
00277 case CHCKPT_COORD:
00278 if (chckpt_interval >= compute_time) {
00279 chckpt_steps= chckpt_interval / compute_time;
00280 if (my_rank == 0) {
00281 printf("||| Will checkpoint every %d timesteps = %.9f s, %d bytes\n",
00282 chckpt_steps,
00283 (double)chckpt_steps * (double)compute_time / 1000000000.0,
00284 chckpt_size);
00285 }
00286 } else {
00287 _ABORT(Ghost_pattern, "Can't handle checkpoint interval %lu < timestep %lu\n",
00288 chckpt_interval, compute_time);
00289 }
00290 break;
00291
00292 case CHCKPT_UNCOORD:
00293 if (my_rank == 0) {
00294 printf("||| Don't know yet what'll have to set for uncoordinated...\n");
00295 }
00296 break;
00297
00298 case CHCKPT_RAID:
00299 _ABORT(Ghost_pattern, "Can't handle checkpoint methods other than coord and none\n");
00300 break;
00301 }
00302
00303
00304 if (my_rank == 0) {
00305 printf("||| Each timestep will take %.9f s\n", (double)compute_time / 1000000000.0);
00306 printf("||| Total application time is %.9f s = %.0f timesteps\n",
00307 (double)application_end_time / 1000000000.0,
00308 ceil((double)application_end_time / (double)compute_time));
00309 printf("||| Ghost cell exchange message size is %d bytes\n", exchange_msg_len);
00310 }
00311
00312
00313 common->event_send(my_rank, START);
00314
00315 }
00316
00317 private:
00318
00319 Ghost_pattern(const Ghost_pattern &c);
00320 void handle_events(CPUNicEvent *e);
00321 void handle_net_events(Event *sst_event);
00322 void handle_NoC_events(Event *sst_event);
00323 void handle_self_events(Event *sst_event);
00324 void handle_nvram_events(Event *sst_event);
00325 void handle_storage_events(Event *sst_event);
00326 Patterns *common;
00327
00328
00329 int my_rank;
00330 int cores;
00331 int x_dim;
00332 int y_dim;
00333 int NoC_x_dim;
00334 int NoC_y_dim;
00335 SimTime_t net_latency;
00336 SimTime_t net_bandwidth;
00337 SimTime_t node_latency;
00338 SimTime_t node_bandwidth;
00339 SimTime_t compute_time;
00340 SimTime_t application_end_time;
00341 int exchange_msg_len;
00342 int ghost_pattern_debug;
00343 chckpt_t chckpt_method;
00344 SimTime_t chckpt_interval;
00345 int chckpt_size;
00346 int envelope_size;
00347 SimTime_t msg_write_time;
00348
00349
00350 int left, right, up, down;
00351 int chckpt_steps;
00352
00353
00354 state_t state;
00355 int rcv_cnt;
00356 int save_ENVELOPE_cnt;
00357 bool application_done;
00358 int timestep_cnt;
00359 int timestep_needed;
00360 bool done_waiting;
00361
00362
00363 int num_chckpts;
00364 int total_rcvs;
00365
00366
00367 SimTime_t compute_segment_start;
00368 SimTime_t msg_wait_time_start;
00369 SimTime_t chckpt_segment_start;
00370
00371 SimTime_t execution_time;
00372 SimTime_t application_time_so_far;
00373 SimTime_t msg_wait_time;
00374 SimTime_t chckpt_time;
00375
00376
00377 Params_t params;
00378 Link *net;
00379 Link *self_link;
00380 Link *NoC;
00381 Link *nvram;
00382 Link *storage;
00383 TimeConverter *tc;
00384
00385
00386 void state_INIT(pattern_event_t event);
00387 void state_COMPUTE(pattern_event_t event);
00388 void state_WAIT(pattern_event_t event);
00389 void state_DONE(pattern_event_t event);
00390 void state_CHCKPT(pattern_event_t event);
00391 void state_SAVE_ENVELOPE(pattern_event_t event);
00392 void state_LOG_MSG1(pattern_event_t event);
00393 void state_LOG_MSG2(pattern_event_t event);
00394 void state_LOG_MSG3(pattern_event_t event);
00395 void state_LOG_MSG4(pattern_event_t event);
00396
00397 void transition_to_COMPUTE(void);
00398 void transition_to_CHCKPT(void);
00399 void count_receives(void);
00400
00401
00402 friend class boost::serialization::access;
00403 template<class Archive>
00404 void serialize(Archive & ar, const unsigned int version )
00405 {
00406 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Component);
00407 ar & BOOST_SERIALIZATION_NVP(params);
00408 ar & BOOST_SERIALIZATION_NVP(my_rank);
00409 ar & BOOST_SERIALIZATION_NVP(cores);
00410 ar & BOOST_SERIALIZATION_NVP(x_dim);
00411 ar & BOOST_SERIALIZATION_NVP(y_dim);
00412 ar & BOOST_SERIALIZATION_NVP(NoC_x_dim);
00413 ar & BOOST_SERIALIZATION_NVP(NoC_y_dim);
00414 ar & BOOST_SERIALIZATION_NVP(net_latency);
00415 ar & BOOST_SERIALIZATION_NVP(net_bandwidth);
00416 ar & BOOST_SERIALIZATION_NVP(node_latency);
00417 ar & BOOST_SERIALIZATION_NVP(node_bandwidth);
00418 ar & BOOST_SERIALIZATION_NVP(compute_time);
00419 ar & BOOST_SERIALIZATION_NVP(done_waiting);
00420 ar & BOOST_SERIALIZATION_NVP(compute_segment_start);
00421 ar & BOOST_SERIALIZATION_NVP(application_end_time);
00422 ar & BOOST_SERIALIZATION_NVP(exchange_msg_len);
00423 ar & BOOST_SERIALIZATION_NVP(state);
00424 ar & BOOST_SERIALIZATION_NVP(left);
00425 ar & BOOST_SERIALIZATION_NVP(right);
00426 ar & BOOST_SERIALIZATION_NVP(up);
00427 ar & BOOST_SERIALIZATION_NVP(down);
00428 ar & BOOST_SERIALIZATION_NVP(rcv_cnt);
00429 ar & BOOST_SERIALIZATION_NVP(ghost_pattern_debug);
00430 ar & BOOST_SERIALIZATION_NVP(application_done);
00431 ar & BOOST_SERIALIZATION_NVP(timestep_cnt);
00432 ar & BOOST_SERIALIZATION_NVP(timestep_needed);
00433 ar & BOOST_SERIALIZATION_NVP(chckpt_method);
00434 ar & BOOST_SERIALIZATION_NVP(chckpt_steps);
00435 ar & BOOST_SERIALIZATION_NVP(chckpt_interval);
00436 ar & BOOST_SERIALIZATION_NVP(chckpt_size);
00437 ar & BOOST_SERIALIZATION_NVP(envelope_size);
00438 ar & BOOST_SERIALIZATION_NVP(msg_wait_time_start);
00439 ar & BOOST_SERIALIZATION_NVP(num_chckpts);
00440 ar & BOOST_SERIALIZATION_NVP(total_rcvs);
00441 ar & BOOST_SERIALIZATION_NVP(compute_segment_start);
00442 ar & BOOST_SERIALIZATION_NVP(msg_wait_time_start);
00443 ar & BOOST_SERIALIZATION_NVP(chckpt_segment_start);
00444 ar & BOOST_SERIALIZATION_NVP(execution_time);
00445 ar & BOOST_SERIALIZATION_NVP(application_time_so_far);
00446 ar & BOOST_SERIALIZATION_NVP(msg_wait_time);
00447 ar & BOOST_SERIALIZATION_NVP(chckpt_time);
00448 ar & BOOST_SERIALIZATION_NVP(net);
00449 ar & BOOST_SERIALIZATION_NVP(self_link);
00450 ar & BOOST_SERIALIZATION_NVP(tc);
00451 }
00452
00453 template<class Archive>
00454 friend void save_construct_data(Archive & ar,
00455 const Ghost_pattern * t,
00456 const unsigned int file_version)
00457 {
00458 _AR_DBG(Ghost_pattern,"\n");
00459 ComponentId_t id = t->getId();
00460 Params_t params = t->params;
00461 ar << BOOST_SERIALIZATION_NVP(id);
00462 ar << BOOST_SERIALIZATION_NVP(params);
00463 }
00464
00465 template<class Archive>
00466 friend void load_construct_data(Archive & ar,
00467 Ghost_pattern * t,
00468 const unsigned int file_version)
00469 {
00470 _AR_DBG(Ghost_pattern,"\n");
00471 ComponentId_t id;
00472 Params_t params;
00473 ar >> BOOST_SERIALIZATION_NVP(id);
00474 ar >> BOOST_SERIALIZATION_NVP(params);
00475 ::new(t)Ghost_pattern(id, params);
00476 }
00477 };
00478
00479 #endif // _GHOST_PATTERN_H