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 "algorithm.h"
00017 #include "trig_cpu.h"
00018
00019 class allreduce_recdbl : public algorithm {
00020 public:
00021 allreduce_recdbl(trig_cpu *cpu) : algorithm(cpu)
00022 {
00023 }
00024
00025 bool
00026 operator()(Event *ev)
00027 {
00028 int adj, handle, remote;
00029 remote = my_id ^ level;
00030
00031 switch (state) {
00032 case 0:
00033
00034 for (adj = 0x1; adj <= num_nodes ; adj <<= 1); adj = adj >> 1;
00035 if (adj != num_nodes) {
00036 printf("recursive_doubling requires power of 2 nodes (%d)\n",
00037 num_nodes);
00038 exit(1);
00039 }
00040
00041
00042 start_time = cpu->getCurrentSimTimeNano();
00043 cpu->addBusyTime("200ns");
00044
00045 level = 0x1;
00046 state = 1;
00047 break;
00048
00049 case 1:
00050
00051
00052
00053 if (cpu->recv(remote, NULL, handle)) state = 2;
00054 break;
00055
00056 case 2:
00057
00058
00059
00060 cpu->send(remote, 0);
00061 state = 3;
00062 break;
00063
00064 case 3:
00065
00066
00067
00068
00069
00070 if (! cpu->waitall()) break;
00071
00072
00073 cpu->addBusyTime("100ns");
00074
00075 level <<= 1;
00076 state = (level < num_nodes) ? 1 : 4;
00077 break;
00078
00079 case 4:
00080 trig_cpu::addTimeToStats(cpu->getCurrentSimTimeNano()-start_time);
00081 state = 0;
00082 return true;
00083
00084 default:
00085 printf("recursive doubling: unhandled state: %d\n", state);
00086 exit(1);
00087 }
00088
00089 return false;
00090 }
00091
00092 private:
00093 allreduce_recdbl();
00094 allreduce_recdbl(const algorithm& a);
00095 void operator=(allreduce_recdbl const&);
00096
00097 SimTime_t start_time;
00098 int level;
00099 };
00100
00101 #endif // COMPONENTS_TRIG_CPU_ALLREDUCE_RECDBL_H