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