00001 #include "charm++.h"
00002 #include "tempo.h"
00003
00004 Tempo::Tempo(void)
00005 {
00006 tempoMessages = CmmNew();
00007 thread_id = CthSelf();
00008 sleeping = 0;
00009 }
00010
00011 void Tempo::ckTempoRecv(int tag1, int tag2, void *buffer, int buflen)
00012 {
00013 int tags[2];
00014 TempoMessage *msg = 0;
00015 while(1) {
00016 tags[0] = tag1; tags[1] = tag2;
00017 msg = (TempoMessage *) CmmGet(tempoMessages, 2, tags, 0);
00018 if (msg) break;
00019 sleeping = 1;
00020 thread_id = CthSelf();
00021 CthSuspend();
00022 }
00023 if (msg->length < buflen)
00024 buflen = msg->length;
00025 memcpy(buffer, msg->data, buflen);
00026 delete msg;
00027 }
00028
00029 void Tempo::ckTempoRecv(int tag, void *buffer, int buflen)
00030 {
00031 ckTempoRecv(tag, TEMPO_ANY, buffer, buflen);
00032 }
00033
00034
00035 void
00036 Tempo::ckTempoSend(int tag1,int tag2,void *buffer,int buflen, CkChareID cid)
00037 {
00038 TempoMessage *msg = new (&buflen, 0) TempoMessage(tag1, tag2, buflen, buffer);
00039 CProxy_TempoChare ptc(cid);
00040 ptc.tempoGeneric(msg);
00041 }
00042
00043
00044 void
00045 Tempo::ckTempoSend(int tag, void *buffer, int buflen, CkChareID cid)
00046 {
00047 ckTempoSend(tag, TEMPO_ANY, buffer, buflen, cid);
00048 }
00049
00050 void Tempo::tempoGeneric(TempoMessage *themsg)
00051 {
00052 int tags[2];
00053 tags[0] = themsg->tag1; tags[1] = themsg->tag2;
00054 CmmPut(tempoMessages, 2, tags, themsg);
00055 if (sleeping) {
00056 sleeping = 0;
00057 CthAwaken(thread_id);
00058 }
00059 }
00060
00061 int Tempo::ckTempoProbe(int tag1, int tag2)
00062 {
00063 int tags[2];
00064 tags[0] = tag1; tags[1] = tag2;
00065 return (CmmProbe(tempoMessages, 2, tags, 0)!=0);
00066 }
00067
00068 int Tempo::ckTempoProbe(int tag)
00069 {
00070 return ckTempoProbe(tag, TEMPO_ANY);
00071 }
00072
00073
00074 void
00075 TempoGroup::ckTempoBcast(int tag, void *buffer, int buflen, CkGroupID bocid)
00076 {
00077 TempoMessage *msg = new (&buflen,0) TempoMessage(tag,BCAST_TAG,buflen,buffer);
00078 CProxy_TempoGroup ptg(bocid);
00079 ptg.tempoGeneric(msg);
00080 }
00081
00082
00083 void
00084 TempoGroup::ckTempoSendBranch(int tag1, int tag2, void *buffer, int buflen,
00085 CkGroupID bocid, int processor)
00086 {
00087 TempoMessage *msg = new (&buflen, 0) TempoMessage(tag1, tag2, buflen, buffer);
00088 CProxy_TempoGroup ptg(bocid);
00089 ptg[processor].tempoGeneric(msg);
00090 }
00091
00092
00093 void
00094 TempoGroup::ckTempoSendBranch(int tag, void *buffer, int buflen,
00095 CkGroupID bocid, int processor)
00096 {
00097 ckTempoSendBranch(tag, TEMPO_ANY, buffer, buflen, bocid, processor);
00098 }
00099
00100 void
00101 TempoGroup::ckTempoSendBranch(int tag1, int tag2, void *buffer,
00102 int buflen, int processor)
00103 {
00104 ckTempoSendBranch(tag1, tag2, buffer, buflen, thisgroup, processor);
00105 }
00106
00107 void
00108 TempoGroup::ckTempoSendBranch(int tag, void *buffer, int buflen, int processor)
00109 {
00110 ckTempoSendBranch(tag, TEMPO_ANY, buffer, buflen, processor);
00111 }
00112
00113 void
00114 TempoGroup::ckTempoBcast(int sender, int tag, void *buffer, int buflen)
00115 {
00116 if(sender)
00117 TempoGroup::ckTempoBcast(tag, buffer, buflen, thisgroup);
00118 ckTempoRecv(tag, BCAST_TAG, buffer, buflen);
00119 }
00120
00121
00122 void
00123 TempoArray::ckTempoSendElem(int tag1, int tag2, void *buffer, int buflen,
00124 CkArrayID aid, int idx)
00125 {
00126 TempoMessage *msg = new (&buflen, 0) TempoMessage(tag1, tag2, buflen, buffer);
00127 CProxy_TempoArray pta(aid);
00128 pta[idx].tempoGeneric(msg);
00129 }
00130
00131
00132 void
00133 TempoArray::ckTempoSendElem(int tag,void *buffer,int buflen,CkArrayID aid, int idx)
00134 {
00135 ckTempoSendElem(tag, TEMPO_ANY, buffer, buflen, aid, idx);
00136 }
00137
00138 void
00139 TempoArray::ckTempoSendElem(int tag1, int tag2, void *buffer, int buflen,
00140 int idx)
00141 {
00142 ckTempoSendElem(tag1, tag2, buffer, buflen, thisArrayID, idx);
00143 }
00144
00145 void
00146 TempoArray::ckTempoSendElem(int tag, void *buffer, int buflen, int idx)
00147 {
00148 ckTempoSendElem(tag, TEMPO_ANY, buffer, buflen, idx);
00149 }
00150
00151 void
00152 TempoArray::ckTempoBarrier(void)
00153 {
00154 if(thisIndex) {
00155 ckTempoSendElem(BARR_TAG, nGOps, (void*) 0, 0, 0);
00156 ckTempoRecv(BARR_TAG, nGOps, (void*) 0, 0);
00157 } else {
00158 int i;
00159 for(i=1;i<ckGetArraySize();i++)
00160 ckTempoRecv(BARR_TAG, nGOps, (void *) 0, 0);
00161 for(i=1;i<ckGetArraySize();i++)
00162 ckTempoSendElem(BARR_TAG, nGOps, (void *) 0, 0, i);
00163 }
00164 nGOps++;
00165 }
00166
00167 void
00168 TempoArray::ckTempoBcast(int sender, int tag, void *buffer, int buflen)
00169 {
00170 if(sender) {
00171 int i;
00172 for(i=0;i<ckGetArraySize();i++)
00173 ckTempoSendElem(tag, BCAST_TAG+nGOps, buffer, buflen, i);
00174 }
00175 ckTempoRecv(tag, BCAST_TAG+nGOps, buffer, buflen);
00176 nGOps++;
00177 }
00178
00179 static void doOp(int op, int type, int count, void *inbuf, void *outbuf)
00180 {
00181 switch(type) {
00182 case TEMPO_FLOAT :
00183 {
00184 float *a, *b;
00185 a = (float *) inbuf;
00186 b = (float *) outbuf;
00187 for(int i=0; i<count; i++) {
00188 switch(op) {
00189 case TEMPO_MIN : if(b[i]>a[i]) b[i]=a[i]; break;
00190 case TEMPO_MAX : if(b[i]<a[i]) b[i]=a[i]; break;
00191 case TEMPO_SUM : b[i] += a[i]; break;
00192 case TEMPO_PROD :b[i] *= a[i]; break;
00193 }
00194 }
00195 }
00196 break;
00197 case TEMPO_INT :
00198 {
00199 int *a, *b;
00200 a = (int *) inbuf;
00201 b = (int *) outbuf;
00202 for(int i=0; i<count; i++) {
00203 switch(op) {
00204 case TEMPO_MIN : if(b[i]>a[i]) b[i]=a[i]; break;
00205 case TEMPO_MAX : if(b[i]<a[i]) b[i]=a[i]; break;
00206 case TEMPO_SUM : b[i] += a[i]; break;
00207 case TEMPO_PROD :b[i] *= a[i]; break;
00208 }
00209 }
00210 }
00211 break;
00212 case TEMPO_DOUBLE:
00213 {
00214 double *a, *b;
00215 a = (double *) inbuf;
00216 b = (double *) outbuf;
00217 for(int i=0; i<count; i++) {
00218 switch(op) {
00219 case TEMPO_MIN : if(b[i]>a[i]) b[i]=a[i]; break;
00220 case TEMPO_MAX : if(b[i]<a[i]) b[i]=a[i]; break;
00221 case TEMPO_SUM : b[i] += a[i]; break;
00222 case TEMPO_PROD :b[i] *= a[i]; break;
00223 }
00224 }
00225 }
00226 break;
00227 }
00228 }
00229
00230 void
00231 TempoArray::ckTempoReduce(int root, int op, void *inbuf, void *outbuf,
00232 int count, int type)
00233 {
00234 int size = count;
00235 switch(type) {
00236 case TEMPO_FLOAT : size *= sizeof(float); break;
00237 case TEMPO_INT : size *= sizeof(int); break;
00238 case TEMPO_DOUBLE : size *= sizeof(double); break;
00239 }
00240 if(thisIndex==root) {
00241 memcpy(outbuf, inbuf, size);
00242 void *tbuf = malloc(size);
00243 _MEMCHECK(tbuf);
00244 for(int i=0; i<ckGetArraySize()-1; i++) {
00245 ckTempoRecv(REDUCE_TAG, nGOps, tbuf, size);
00246 doOp(op, type, count, tbuf, outbuf);
00247 }
00248 free(tbuf);
00249 } else {
00250 ckTempoSendElem(REDUCE_TAG, nGOps, inbuf, size, root);
00251 }
00252 nGOps++;
00253 }
00254
00255 void
00256 TempoArray::ckTempoAllReduce(int op, void *inbuf, void *outbuf,
00257 int count, int type)
00258 {
00259 ckTempoReduce(0, op, inbuf, outbuf, count, type);
00260 int size = count;
00261 switch(type) {
00262 case TEMPO_FLOAT : size *= sizeof(float); break;
00263 case TEMPO_INT : size *= sizeof(int); break;
00264 case TEMPO_DOUBLE : size *= sizeof(double); break;
00265 }
00266 ckTempoBcast(thisIndex==0, REDUCE_TAG, outbuf, size);
00267 }
00268
00269 #include "tempo.def.h"