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

sst/elements/patterns/ghost_pattern.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 _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,                     // First state in state machine
00034               COMPUTE,                  // We are currently computing
00035               WAIT,                     // Waiting for one or more messages
00036               DONE,                     // Work is all done
00037               CHCKPT,                   // Writing a checkpoint
00038               SAVE_ENVELOPE,            // Save receive msg envelope
00039               LOG_MSG1,                 // Log the first message to stable (local) storage
00040               LOG_MSG2,                 // Log the second message to stable (local) storage
00041               LOG_MSG3,                 // Log the third message to stable (local) storage
00042               LOG_MSG4                  // Log the fourth message to stable (local) storage
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             // Defaults for paramters
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             // Counters, computed values, and internal state
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             // Create a time converter
00184             tc= registerTimeBase("1ns", true);
00185 
00186             // Create a handler for events from the Network
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             // Create a handler for events from the network on chip (NoC)
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             // Create a channel for "out of band" events sent to ourselves
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             // Create a handler for events from local NVRAM
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             // Create a handler for events from the storage network
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             // Initialize the common functions we need
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             // Who are my four neighbors?
00250             // The network is x_dim * NoC_x_dim by y_dim * NoC_y_dim
00251             // The virtual network of the cores is
00252             // (x_dim * NoC_x_dim * cores) * (y_dim * NoC_y_dim)
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             //fprintf(stderr, "{%2d:%2d,%2d, node %2d} right %2d, left %2d, up %2d, down %2d\n",
00268             //my_rank, myX, myY, my_rank / (NoC_x_dim * NoC_y_dim * cores), right, left, up, down);
00269 
00270             // If we are doing coordinated checkpointing, we will do that
00271             // every time x timesteps have been computed.
00272             // This is OK as long as the checkpoint interval is larger than a time
00273             // step. In the other case we would need to quiesce, lets do that later
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             // Ghost pattern specific info
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             // Send a start event to ourselves without a delay
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         // Input paramters for simulation
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         // Precomputed values
00350         int left, right, up, down;
00351         int chckpt_steps;
00352 
00353         // Keeping track of the simulation
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         // Statistics; some of these may move to pattern_common
00363         int num_chckpts;
00364         int total_rcvs;
00365 
00366         // Keeping track of time
00367         SimTime_t compute_segment_start;        // Time when we last entered compute
00368         SimTime_t msg_wait_time_start;          // Time when we last entered wait
00369         SimTime_t chckpt_segment_start;         // Time when we last entered coord chckpt
00370 
00371         SimTime_t execution_time;               // Total time of simulation
00372         SimTime_t application_time_so_far;      // Total time in compute so far
00373         SimTime_t msg_wait_time;                // Total time in eait so far
00374         SimTime_t chckpt_time;                  // Total checkpoint time so far
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         // Some local functions we need
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

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