00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef COMPONENTS_TRIG_CPU_ALLREDUCE_RECDBL_H
00014 #define COMPONENTS_TRIG_CPU_ALLREDUCE_RECDBL_H
00015
00016 #include "sst/elements/portals4_sm/trig_cpu/application.h"
00017 #include "sst/elements/portals4_sm/trig_cpu/trig_cpu.h"
00018
00019 class allreduce_recdbl : public application {
00020 public:
00021 allreduce_recdbl(trig_cpu *cpu) : application(cpu)
00022 {
00023 in_buf = 1;
00024 out_buf = 0;
00025 }
00026
00027 bool
00028 operator()(Event *ev)
00029 {
00030 crBegin();
00031
00032
00033 for (adj = 0x1; adj <= num_nodes ; adj <<= 1); adj = adj >> 1;
00034 if (adj != num_nodes) {
00035 printf("recursive_doubling requires power of 2 nodes (%d)\n",
00036 num_nodes);
00037 exit(1);
00038 }
00039
00040
00041 start_time = cpu->getCurrentSimTimeNano();
00042 cpu->addBusyTime("200ns");
00043 crReturn();
00044
00045 out_buf = in_buf;
00046
00047 for (level = 0x1 ; level < num_nodes ; level <<= 1) {
00048 remote = my_id ^ level;
00049 while (!cpu->irecv(remote, &tmp_buf, handle)) { crReturn(); }
00050 cpu->isend(remote, &out_buf, 8);
00051 crReturn();
00052 while (! cpu->waitall()) { crReturn(); }
00053
00054 out_buf += tmp_buf;
00055 cpu->addBusyTime("100ns");
00056 crReturn();
00057 }
00058 crReturn();
00059
00060 trig_cpu::addTimeToStats(cpu->getCurrentSimTimeNano()-start_time);
00061
00062 assert(out_buf == (uint64_t) cpu->getNumNodes());
00063
00064 crFinish();
00065 return true;
00066 }
00067
00068 private:
00069 allreduce_recdbl();
00070 allreduce_recdbl(const application& a);
00071 void operator=(allreduce_recdbl const&);
00072
00073 SimTime_t start_time;
00074 int level;
00075 int adj, handle, remote;
00076 uint64_t in_buf, out_buf, tmp_buf;
00077 };
00078
00079 #endif // COMPONENTS_TRIG_CPU_ALLREDUCE_RECDBL_H