00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef COMPONENTS_TRIG_CPU_BARRIER_RECDBL_TRIGGERED_H
00014 #define COMPONENTS_TRIG_CPU_BARRIER_RECDBL_TRIGGERED_H
00015
00016 #include "sst/elements/portals4_sm/trig_cpu/application.h"
00017 #include "sst/elements/portals4_sm/trig_cpu/trig_cpu.h"
00018 #include "sst/elements/portals4_sm/trig_cpu/portals.h"
00019
00020 class barrier_recdbl_triggered : public application {
00021 public:
00022 barrier_recdbl_triggered(trig_cpu *cpu) : application(cpu), init(false), algo_count(0)
00023 {
00024 int adj;
00025
00026 ptl = cpu->getPortalsHandle();
00027
00028 my_levels = -1;
00029 for (adj = 0x1; adj <= num_nodes ; adj <<= 1) { my_levels++; } adj = adj >> 1;
00030 if (adj != num_nodes) {
00031 printf("recursive_doubling requires power of 2 nodes (%d)\n",
00032 num_nodes);
00033 exit(1);
00034 }
00035
00036 my_level_ct_hs.resize(my_levels);
00037 my_level_me_hs.resize(my_levels);
00038 }
00039
00040 bool
00041 operator()(Event *ev)
00042 {
00043 ptl_md_t md;
00044 ptl_me_t me;
00045
00046 crBegin();
00047
00048 if (!init) {
00049 md.start = NULL;
00050 me.length = 0;
00051 md.eq_handle = PTL_EQ_NONE;
00052 md.ct_handle = PTL_CT_NONE;
00053 ptl->PtlMDBind(md, &my_md_h);
00054
00055 for (i = 0 ; i < my_levels ; ++i) {
00056 ptl->PtlCTAlloc(PTL_CT_OPERATION, my_level_ct_hs[i]);
00057
00058 me.start = NULL;
00059 me.length = 0;
00060 me.match_bits = i;
00061 me.ignore_bits = 0;
00062 me.ct_handle = my_level_ct_hs[i];
00063 ptl->PtlMEAppend(0, me, PTL_PRIORITY_LIST, NULL,
00064 my_level_me_hs[i]);
00065 }
00066
00067 init = true;
00068 crReturn();
00069 start_noise_section();
00070 }
00071
00072
00073 start_time = cpu->getCurrentSimTimeNano();
00074 cpu->addBusyTime("200ns");
00075 crReturn();
00076
00077 algo_count++;
00078
00079 ptl->PtlEnableCoalesce();
00080 crReturn();
00081
00082
00083 ptl->PtlPut(my_md_h, 0, 0, 0, my_id, 0, 0, 0, NULL, 0);
00084 crReturn();
00085 ptl->PtlPut(my_md_h, 0, 0, 0, my_id ^ 0x1, 0, 0, 0, NULL, 0);
00086 crReturn();
00087
00088 for (i = 1 ; i < my_levels ; ++i) {
00089 ptl->PtlTriggeredPut(my_md_h, 0, 0, 0, my_id, 0,
00090 i, 0, NULL, 0, my_level_ct_hs[i - 1], algo_count * 2);
00091 crReturn();
00092 ptl->PtlTriggeredPut(my_md_h, 0, 0, 0, my_id ^ (0x1 << i) , 0,
00093 i, 0, NULL, 0, my_level_ct_hs[i - 1], algo_count * 2);
00094 crReturn();
00095 }
00096
00097 ptl->PtlDisableCoalesce();
00098 crReturn();
00099
00100 while (!ptl->PtlCTWait(my_level_ct_hs[my_levels - 1], algo_count * 2)) {
00101 crReturn();
00102 }
00103 crReturn();
00104
00105 trig_cpu::addTimeToStats(cpu->getCurrentSimTimeNano()-start_time);
00106
00107 crFinish();
00108 return true;
00109 }
00110
00111 private:
00112 barrier_recdbl_triggered();
00113 barrier_recdbl_triggered(const application& a);
00114 void operator=(barrier_recdbl_triggered const&);
00115
00116 portals *ptl;
00117 SimTime_t start_time;
00118 int i;
00119 int my_levels;
00120 bool init;
00121
00122 std::vector<ptl_handle_ct_t> my_level_ct_hs;
00123 std::vector<ptl_handle_me_t> my_level_me_hs;
00124 ptl_handle_md_t my_md_h;
00125
00126 uint64_t algo_count;
00127 };
00128
00129 #endif // COMPONENTS_TRIG_CPU_BARRIER_RECDBL_TRIGGERED_H