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

sst/elements/portals4_sm/trig_cpu/barrier_action.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 COMPONENTS_TRIG_CPU_BARRIER_ACTION_H
00014 #define COMPONENTS_TRIG_CPU_BARRIER_ACTION_H
00015 
00016 #include <vector>
00017 #include <cstdlib>
00018 
00019 #include <sst/core/action.h>
00020 #include <sst/core/link.h>
00021 #include <sst/core/simulation.h>
00022 #include <sst/core/timeLord.h>
00023 
00024 class barrier_action : public Action {
00025 public:
00026 
00027     barrier_action() {
00028         setPriority(75);
00029         
00030         min = 0xffffffff;
00031         max = 0;
00032         total_time = 0;
00033         
00034         overall_min = 0xffffffff;
00035         overall_max = 0;
00036         overall_total_time = 0;
00037         overall_total_num = 0;
00038         
00039         rand_init = false;
00040         max_init_rank = -1;
00041 
00042         job_size = Simulation::getSimulation()->getNumRanks();
00043 
00044 //      if ( job_size > 1 ) {
00045             Simulation::getSimulation()->insertActivity(Simulation::getSimulation()->getTimeLord()->getTimeConverter("1us")->getFactor(),this);
00046 //      }
00047 
00048     }
00049 
00050     void execute() {
00051         // Check to see if everybody has entered the barrier
00052         Simulation *sim = Simulation::getSimulation();
00053 
00054 //      printf("Current time: %lu\n", sim->getTimeLord()->getNano()->convertFromCoreTime(sim->getCurrentSimCycle()));
00055         
00056         boost::mpi::communicator world;
00057 
00058         // Figure out how many still need to report
00059         int value = wake_up.size() - num_reporting;
00060         int out;
00061         
00062         all_reduce( world, &value, 1, &out, std::plus<int>() );  
00063         
00064         if ( 0 == out ) {
00065             // Barrier is done, exchange data
00066             SimTime_t total_num = wake_up.size();
00067             SimTime_t total_num_a;
00068             SimTime_t min_a;
00069             SimTime_t max_a;
00070             SimTime_t total_time_a;
00071             all_reduce( world, &total_num , 1, &total_num_a, std::plus<SimTime_t>() );
00072             all_reduce( world, &min, 1, &min_a, boost::mpi::minimum<SimTime_t>() );
00073             all_reduce( world, &max, 1, &max_a, boost::mpi::maximum<SimTime_t>() );
00074             all_reduce( world, &total_time, 1, &total_time_a, std::plus<SimTime_t>() );
00075 
00076             if ( world.rank() == 0 ) {
00077                 printf("Max time: %lu ns\n", (unsigned long) max_a);
00078                 printf("Min time: %lu ns\n", (unsigned long) min_a);
00079                 printf("Avg time: %lu ns\n", (unsigned long) (total_time_a/total_num_a));
00080                 printf("Total num: %d\n", total_num_a);
00081                 fflush(NULL);
00082             }
00083             resetBarrier();
00084             addTimeToOverallStats(max_a);
00085             resetStats();
00086             for ( int i = 0; i < wake_up.size(); i++ ) {
00087                 wake_up[i]->Send(10,NULL);
00088             }
00089             
00090         }
00091         SimTime_t next = sim->getCurrentSimCycle() + 
00092             sim->getTimeLord()->getTimeConverter("1us")->getFactor();
00093         sim->insertActivity( next, this );
00094         
00095     }
00096     
00097     void
00098     barrier()
00099     {
00100         num_reporting++;
00101 //      if ( job_size > 1 ) return;
00102 //         if ( num_reporting == wake_up.size() ) {
00103 //             // Everyone has entered barrier, wake everyone up to start
00104 //             // over
00105 //             for ( int i = 0; i < wake_up.size(); i++ ) {
00106 //                 wake_up[i]->Send(10,NULL);
00107 //             }
00108 //             resetBarrier();
00109 //             printStats();
00110 //             addTimeToOverallStats(max);
00111 //             resetStats();
00112 //         }
00113     }
00114 
00115     void
00116     addTimeToStats(SimTime_t time)
00117     {
00118         if ( time < min ) min = time;
00119         if ( time > max ) max = time;
00120         total_time += time;
00121     }
00122 
00123     void
00124     addTimeToOverallStats(SimTime_t time)
00125     {
00126         if ( time < overall_min ) overall_min = time;
00127         if ( time > overall_max ) overall_max = time;
00128         overall_total_time += time;
00129         overall_total_num++;
00130     }
00131 
00132     void
00133     resetStats()
00134     {
00135         min = 0xffffffff;
00136         max = 0;
00137         total_time = 0;
00138     }
00139 
00140     void
00141     printStats()
00142     {
00143         printf("Max time: %lu ns\n", (unsigned long) max);
00144         printf("Min time: %lu ns\n", (unsigned long) min);
00145         printf("Avg time: %lu ns\n", (unsigned long) (total_time/wake_up.size()));
00146         printf("Total num: %d\n", wake_up.size());
00147         fflush(NULL);
00148     }
00149 
00150     void
00151     printOverallStats()
00152     {
00153         printf("Overall Max time: %lu ns\n", (unsigned long) overall_max);
00154         printf("Overall Min time: %lu ns\n", (unsigned long) overall_min);
00155         printf("Overall Avg time: %lu ns\n", (unsigned long) (overall_total_time/overall_total_num));
00156         printf("Overall Total num: %d\n", overall_total_num);
00157         fflush(NULL);
00158     }
00159 
00160     int
00161     getRand(int rank, int max)
00162     {
00163         if (!rand_init) {
00164             srand(1);
00165             rand_init = true;
00166         }
00167         if ( max == 0 ) return 0;
00168         if ( max_init_rank < rank ) {
00169             for ( int i = max_init_rank + 1; i <= rank; i++ ) {
00170                 rand_nums.push_back(rand());
00171             }
00172             
00173         }
00174         
00175         return rand_nums[rank] % max;
00176     }
00177 
00178     void
00179     addWakeUp(Link* link)
00180     {
00181         wake_up.push_back(link);
00182     }
00183 
00184 /*     void */
00185 /*     setTotalNodes(int total) */
00186 /*     { */
00187 /*         if ( wake_up == NULL ) wake_up = new Link*[total]; */
00188 /*         total_nodes = total; */
00189 /*     } */
00190 
00191     void
00192     resetBarrier()
00193     {
00194         num_reporting = 0;
00195     }
00196 
00197 
00198 private:
00199     SimTime_t min;
00200     SimTime_t max;
00201     SimTime_t total_time;
00202     int num_reporting;
00203 
00204     SimTime_t overall_min;
00205     SimTime_t overall_max;
00206     SimTime_t overall_total_time;
00207     int overall_total_num;
00208 
00209     bool rand_init;
00210     int max_init_rank;
00211     std::vector<int> rand_nums; 
00212     
00213     std::vector<Link*> wake_up;
00214 
00215     int job_size;
00216 
00217     
00218 };
00219 
00220 #endif // COMPONENTS_TRIG_CPU_BARRIER_ACTION_H

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