00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef COMPONENTS_TRIG_CPU_BCAST_TREE_TRIGGERED_H
00014 #define COMPONENTS_TRIG_CPU_BCAST_TREE_TRIGGERED_H
00015
00016 #include "algorithm.h"
00017 #include "trig_cpu.h"
00018 #include "portals.h"
00019 #include <string.h>
00020
00021 class bcast_tree_triggered : public algorithm {
00022 public:
00023 bcast_tree_triggered(trig_cpu *cpu) : algorithm(cpu), init(false)
00024 {
00025 radix = cpu->getRadix();
00026 ptl = cpu->getPortalsHandle();
00027
00028 msg_size = cpu->getMessageSize();
00029 chunk_size = cpu->getChunkSize();
00030
00031
00032 boost::tie(my_root, my_children) = buildBinomialTree(radix);
00033 num_children = my_children.size();
00034
00035 in_buf = (char*) malloc(msg_size);
00036 for (i = 0 ; i < msg_size ; ++i) {
00037 in_buf[i] = i % 255;
00038 }
00039 out_buf = (char*) malloc(msg_size);
00040 bounce_buf = (char*) malloc(chunk_size);
00041 }
00042
00043 bool
00044 operator()(Event *ev)
00045 {
00046 ptl_md_t md;
00047 ptl_me_t me;
00048
00049 crBegin();
00050
00051 if (!init) {
00052
00053 ptl->PtlCTAlloc(PTL_CT_OPERATION, bounce_ct_h);
00054 crReturn();
00055 me.start = bounce_buf;
00056 me.length = chunk_size;
00057 me.match_bits = 0x0;
00058 me.ignore_bits = 0x0;
00059 me.ct_handle = bounce_ct_h;
00060 ptl->PtlMEAppend(PT_BOUNCE, me, PTL_PRIORITY_LIST, NULL, bounce_me_h);
00061 crReturn();
00062
00063 md.start = bounce_buf;
00064 md.length = chunk_size;
00065 md.eq_handle = PTL_EQ_NONE;
00066 md.ct_handle = PTL_CT_NONE;
00067 ptl->PtlMDBind(md, &bounce_md_h);
00068 crReturn();
00069
00070 init = true;
00071 }
00072
00073
00074
00075 start_time = cpu->getCurrentSimTimeNano();
00076 cpu->addBusyTime("200ns");
00077 crReturn();
00078
00079
00080 ptl->PtlCTAlloc(PTL_CT_OPERATION, out_me_ct_h);
00081 crReturn();
00082 me.start = out_buf;
00083 me.length = msg_size;
00084 me.match_bits = 0x0;
00085 me.ignore_bits = 0x0;
00086 me.ct_handle = out_me_ct_h;
00087 ptl->PtlMEAppend(PT_OUT, me, PTL_PRIORITY_LIST, NULL, out_me_h);
00088 crReturn();
00089
00090 ptl->PtlCTAlloc(PTL_CT_OPERATION, out_md_ct_h);
00091 crReturn();
00092 md.start = out_buf;
00093 md.length = msg_size;
00094 md.eq_handle = PTL_EQ_NONE;
00095 md.ct_handle = out_md_ct_h;
00096 ptl->PtlMDBind(md, &out_md_h);
00097 crReturn();
00098
00099
00100 if (my_id == my_root) {
00101
00102 memcpy(out_buf, in_buf, msg_size);
00103
00104 for (j = 0 ; j < msg_size ; j += chunk_size) {
00105 for (i = 0 ; i < num_children ; ++i) {
00106 ptl->PtlPut(bounce_md_h, 0, 0, 0, my_children[i],
00107 PT_BOUNCE, 0x0, 0, NULL, 0);
00108 crReturn();
00109 }
00110 }
00111
00112 } else {
00113 for (j = 0 ; j < msg_size ; j += chunk_size) {
00114
00115 comm_size = (msg_size - j > chunk_size) ?
00116 chunk_size : msg_size - j;
00117 ptl->PtlTriggeredGet(out_md_h, j, comm_size, my_root,
00118 PT_OUT, 0x0, NULL, j, bounce_ct_h,
00119 j / chunk_size);
00120 crReturn();
00121
00122
00123 for (i = 0 ; i < num_children ; ++i) {
00124 ptl->PtlTriggeredPut(bounce_md_h, 0, 0, 0, my_children[i],
00125 PT_BOUNCE, 0x0, 0, NULL, 0, out_md_ct_h,
00126 j / chunk_size);
00127 crReturn();
00128 }
00129 }
00130
00131
00132 count = (msg_size + chunk_size - 1) / chunk_size;
00133 ptl->PtlTriggeredCTInc(bounce_ct_h, -count, bounce_ct_h, count);
00134 crReturn();
00135 }
00136
00137 if (num_children > 0) {
00138
00139 count = num_children * ((msg_size + chunk_size - 1) / chunk_size);
00140 while (!ptl->PtlCTWait(out_me_ct_h, count)) { crReturn(); }
00141 } else {
00142
00143 count = (msg_size + chunk_size - 1) / chunk_size;
00144 while (!ptl->PtlCTWait(out_md_ct_h, count)) { crReturn(); }
00145 }
00146 crReturn();
00147
00148 ptl->PtlCTFree(out_me_ct_h);
00149 crReturn();
00150 ptl->PtlMEUnlink(out_me_h);
00151 crReturn();
00152 ptl->PtlCTFree(out_md_ct_h);
00153 crReturn();
00154 ptl->PtlMDRelease(out_md_h);
00155 crReturn();
00156
00157 trig_cpu::addTimeToStats(cpu->getCurrentSimTimeNano()-start_time);
00158
00159 crFinish();
00160 return true;
00161 }
00162
00163 private:
00164 bcast_tree_triggered();
00165 bcast_tree_triggered(const algorithm& a);
00166 void operator=(bcast_tree_triggered const&);
00167
00168 bool init;
00169 portals *ptl;
00170
00171 SimTime_t start_time;
00172 int radix;
00173 int i, j;
00174
00175 int msg_size;
00176 int chunk_size;
00177 int comm_size;
00178 int count;
00179
00180 char *in_buf;
00181 char *out_buf;
00182 char *bounce_buf;
00183
00184 ptl_handle_ct_t bounce_ct_h;
00185 ptl_handle_me_t bounce_me_h;
00186 ptl_handle_md_t bounce_md_h;
00187
00188 ptl_handle_ct_t out_me_ct_h;
00189 ptl_handle_me_t out_me_h;
00190 ptl_handle_ct_t out_md_ct_h;
00191 ptl_handle_md_t out_md_h;
00192
00193 ptl_handle_ct_t ack_ct_h;
00194 ptl_handle_me_t ack_me_h;
00195 ptl_handle_md_t ack_md_h;
00196
00197 int my_root;
00198 std::vector<int> my_children;
00199 int num_children;
00200
00201 static const int PT_BOUNCE = 0;
00202 static const int PT_ACK = 1;
00203 static const int PT_OUT = 2;
00204 };
00205
00206 #endif // COMPONENTS_TRIG_CPU_BCAST_TREE_TRIGGERED_H