00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef COMPONENTS_TRIG_CPU_TRIG_CPU_H
00014 #define COMPONENTS_TRIG_CPU_TRIG_CPU_H
00015
00016 #include <string>
00017 #include <list>
00018 #include <set>
00019 #include <queue>
00020 #include <vector>
00021 #include <cstdlib>
00022 #include <stdlib.h>
00023
00024 #include <sst/core/eventFunctor.h>
00025 #include <sst/core/component.h>
00026 #include <sst/core/compEvent.h>
00027 #include <sst/core/link.h>
00028 #include <sst/core/timeConverter.h>
00029
00030 #include "sst/elements/portals4_sm/trig_nic/trig_nic_event.h"
00031 #include "portals.h"
00032
00033 using namespace SST;
00034
00035 class portals;
00036 class algorithm;
00037
00038 struct posted_recv {
00039 int handle;
00040 int src;
00041 void* buffer;
00042
00043 posted_recv(int handle, int src, void* buffer) {
00044 this->handle = handle;
00045 this->src = src;
00046 this->buffer = buffer;
00047 }
00048 };
00049
00050 struct unex_msg {
00051 uint8_t* data;
00052 int src;
00053 int length;
00054
00055 unex_msg(uint8_t* data, int src, int length) {
00056 this->data = data;
00057 this->src = src;
00058 this->length = length;
00059 }
00060 };
00061
00062 class ptl_nic_event : public CompEvent {
00063 public:
00064 ptl_nic_event(ptl_int_nic_op_t* op) : CompEvent() {
00065 operation = op;
00066 }
00067 ptl_nic_event() : CompEvent() {}
00068
00069 ptl_int_nic_op_t* operation;
00070 };
00071
00072 class trig_cpu : public Component {
00073 public:
00074 friend class portals;
00075
00076 trig_cpu(ComponentId_t id, Params_t& params);
00077 int Setup();
00078 int Finish();
00079
00080 void send(int dest, uint64_t data);
00081 bool recv(int src, uint64_t* buf, int& handle);
00082
00083 void isend(int dest, void* data, int length);
00084 bool irecv(int src, void* buf, int& handle);
00085
00086 bool process_pending_msg();
00087 bool waitall();
00088 bool waitall(int size, int* src);
00089
00090 int calcXPosition( int node );
00091 int calcYPosition( int node );
00092 int calcZPosition( int node );
00093 int calcNodeID(int x, int y, int z);
00094
00095 int getMyId(void) { return my_id; }
00096 int getNumNodes(void) { return num_nodes; }
00097
00098 void addBusyTime(const char* time)
00099 {
00100 busy += defaultTimeBase->convertFromCoreTime(registerTimeBase(time, false)->getFactor());
00101 }
00102
00103 portals* getPortalsHandle(void) { return ptl; }
00104 int getRadix(void) { return radix; }
00105 int getMessageSize(void) { return msg_size; }
00106 int getChunkSize(void) { return chunk_size; }
00107
00108 private:
00109 trig_cpu();
00110 trig_cpu(const trig_cpu& c);
00111 void operator=(trig_cpu const&);
00112
00113 void initPortals(void);
00114
00115
00116
00117 bool event_handler(Event* ev);
00118
00119
00120
00121 bool processEvent( Event* e );
00122 bool processEventPortals( Event* e );
00123
00124
00125 bool ptlNICHandler( Event* e );
00126
00127
00128
00129
00130 bool event_nic_timing(Event* e);
00131 bool event_dma_return(Event *e);
00132 bool event_pio_delay(Event* e);
00133
00134 void wakeUp();
00135
00136
00137 bool writeToNIC(trig_nic_event* ev);
00138 void returnCredits(int num);
00139 void setTimingParams(int set);
00140
00141
00142 int my_id;
00143 int num_nodes;
00144 int state;
00145 int top_state;
00146 int x_size;
00147 int y_size;
00148 int z_size;
00149 int count;
00150 int latency;
00151
00152
00153 portals* ptl;
00154 int radix;
00155 int msg_size;
00156 int chunk_size;
00157
00158
00159 uint64_t msg_rate_delay;
00160 uint64_t busy;
00161 int outstanding_msg;
00162 int recv_handle;
00163 std::list<posted_recv*> posted_recv_q;
00164 std::set<int> outstanding_recv;
00165 std::queue<trig_nic_event*> pending_msg;
00166 std::list<unex_msg*> unex_msg_q;
00167
00168 bool waiting;
00169 SimTime_t wait_start_time;
00170
00171 bool blocking;
00172 int nic_credits;
00173 trig_nic_event* blocked_event;
00174 int blocked_busy;
00175
00176 bool pio_in_progress;
00177 bool use_portals;
00178
00179 int timing_set;
00180 int delay_host_pio_write;
00181 int delay_bus_xfer;
00182 int latency_dma_mem_access;
00183 int added_pio_latency;
00184 int recv_overhead;
00185
00186
00187 SimTime_t noise_interval;
00188 SimTime_t noise_duration;
00189 SimTime_t noise_count;
00190 int noise_runs;
00191 int current_run;
00192
00193 Params_t params;
00194 Link* nic;
00195 Link* self;
00196 Link* ptl_link;
00197 Link* nic_timing_link;
00198 bool nic_timing_wakeup_scheduled;
00199 Link* dma_return_link;
00200 Link* pio_delay_link;
00201 int dma_return_count;
00202
00203 std::string frequency;
00204
00205 algorithm *coll_algo;
00206
00207
00208
00209 std::queue<trig_nic_event*> wc_buffers;
00210 int wc_buffers_max;
00211 std::queue<trig_nic_event*> dma_buffers;
00212
00213 public:
00214 static void
00215 addTimeToStats(SimTime_t time)
00216 {
00217 if ( time < min ) min = time;
00218 if ( time > max ) max = time;
00219 total_time += time;
00220 total_num++;
00221 }
00222
00223 static void
00224 addTimeToOverallStats(SimTime_t time)
00225 {
00226 if ( time < overall_min ) overall_min = time;
00227 if ( time > overall_max ) overall_max = time;
00228 overall_total_time += time;
00229 overall_total_num++;
00230 }
00231
00232 static void
00233 resetStats()
00234 {
00235 min = 1000000;
00236 max = 0;
00237 total_time = 0;
00238 total_num = 0;
00239 }
00240
00241 static void
00242 printStats()
00243 {
00244 printf("Max time: %lu ns\n", (unsigned long) max);
00245 printf("Min time: %lu ns\n", (unsigned long) min);
00246 printf("Avg time: %lu ns\n", (unsigned long) (total_time/total_num));
00247 printf("Total num: %d\n", total_num);
00248 fflush(NULL);
00249 }
00250
00251 static void
00252 printOverallStats()
00253 {
00254 printf("Overall Max time: %lu ns\n", (unsigned long) overall_max);
00255 printf("Overall Min time: %lu ns\n", (unsigned long) overall_min);
00256 printf("Overall Avg time: %lu ns\n", (unsigned long) (overall_total_time/overall_total_num));
00257 printf("Overall Total num: %d\n", overall_total_num);
00258 fflush(NULL);
00259 }
00260
00261 static int
00262 getRand(int max)
00263 {
00264 if (!rand_init) {
00265 srand(0);
00266 rand_init = true;
00267 }
00268 if ( max == 0 ) return 0;
00269 return rand() % max;
00270 }
00271
00272 static void
00273 addWakeUp(Link* link)
00274 {
00275 wake_up[current_link++] = link;
00276 }
00277
00278 static void
00279 setTotalNodes(int total)
00280 {
00281 if ( wake_up == NULL ) wake_up = new Link*[total];
00282 total_nodes = total;
00283 }
00284
00285 static void
00286 resetBarrier()
00287 {
00288 num_remaining = total_nodes;
00289 }
00290
00291 static void
00292 barrier()
00293 {
00294 num_remaining--;
00295 if ( num_remaining == 0 ) {
00296
00297
00298 for ( int i = 0; i < total_nodes; i++ ) {
00299 wake_up[i]->Send(10,NULL);
00300 }
00301 resetBarrier();
00302 printStats();
00303 addTimeToOverallStats(max);
00304 resetStats();
00305 }
00306 }
00307
00308 private:
00309 static SimTime_t min;
00310 static SimTime_t max;
00311 static SimTime_t total_time;
00312 static int total_num;
00313
00314 static SimTime_t overall_min;
00315 static SimTime_t overall_max;
00316 static SimTime_t overall_total_time;
00317 static int overall_total_num;
00318
00319 static bool rand_init;
00320
00321
00322
00323 static Link** wake_up;
00324 static int current_link;
00325 static int total_nodes;
00326 static int num_remaining;
00327 };
00328
00329 #endif // COMPONENTS_TRIG_CPU_TRIG_CPU_H