00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <stdio.h>
00038 #include <iostream>
00039 #include <sstream>
00040 #include <string>
00041 #include <list>
00042 #include <map>
00043
00044 #include "floats.hh"
00045 #include "smartpointer.hh"
00046 #include "klass.hh"
00047 #include "uitree.hh"
00048 #include "Text.hh"
00049 #include "signals.hh"
00050
00051 extern bool gVectorSwitch;
00052 extern bool gDeepFirstSwitch;
00053 extern bool gOpenMPSwitch;
00054 extern bool gSchedulerSwitch;
00055 extern int gVecSize;
00056 extern bool gUIMacroSwitch;
00057 extern int gVectorLoopVariant;
00058 extern bool gGroupTaskSwitch;
00059
00060 extern map<Tree, set<Tree> > gMetaDataSet;
00061 static int gTaskCount = 0;
00062
00063 void tab (int n, ostream& fout)
00064 {
00065 fout << '\n';
00066 while (n--) fout << '\t';
00067 }
00068
00072 void Klass::setLoopProperty(Tree sig, Loop* l)
00073 {
00074 fLoopProperty.set(sig,l);
00075 }
00076
00080 bool Klass::getLoopProperty(Tree sig, Loop*& l)
00081 {
00082 return fLoopProperty.get(sig, l);
00083 }
00084
00089 void Klass::openLoop(const string& size)
00090 {
00091 fTopLoop = new Loop(fTopLoop, size);
00092 }
00093
00099 void Klass::openLoop(Tree recsymbol, const string& size)
00100 {
00101 fTopLoop = new Loop(recsymbol, fTopLoop, size);
00102
00103 }
00104
00109 void Klass::closeLoop(Tree sig)
00110 {
00111 assert(fTopLoop);
00112 Loop* l = fTopLoop;
00113 fTopLoop = l->fEnclosingLoop;
00114 assert(fTopLoop);
00115
00116
00117 if (l->isEmpty() || l->hasRecDependencies()) {
00118
00119 fTopLoop->absorb(l);
00120 delete l;
00121 } else {
00122
00123 if (sig) setLoopProperty(sig,l);
00124 fTopLoop->fBackwardLoopDependencies.insert(l);
00125 }
00126 }
00127
00131 void printlines(int n, list<string>& lines, ostream& fout)
00132 {
00133 list<string>::iterator s;
00134 for (s = lines.begin(); s != lines.end(); s++) {
00135 tab(n, fout); fout << *s;
00136 }
00137 }
00138
00142 void printdecllist(int n, const string& decl, list<string>& content, ostream& fout)
00143 {
00144 if (!content.empty()) {
00145 list<string>::iterator s;
00146 fout << "\\";
00147 tab(n, fout); fout << decl;
00148 string sep = "(";
00149 for (s = content.begin(); s != content.end(); s++) {
00150 fout << sep << *s;
00151 sep = ", ";
00152 }
00153 fout << ')';
00154 }
00155 }
00156
00160 void Klass::printLibrary(ostream& fout)
00161 {
00162 set<string> S;
00163 set<string>::iterator f;
00164
00165 string sep;
00166 collectLibrary(S);
00167 fout << "/* link with ";
00168 for (f = S.begin(), sep =": "; f != S.end(); f++, sep = ", ") {
00169 fout << sep << *f;
00170 }
00171 fout << " */\n";
00172 }
00173
00177 void Klass::printIncludeFile(ostream& fout)
00178 {
00179 set<string> S;
00180 set<string>::iterator f;
00181
00182 if (gOpenMPSwitch) {
00183 fout << "#include <omp.h>" << "\n";
00184 }
00185
00186 collectIncludeFile(S);
00187 for (f = S.begin(); f != S.end(); f++) {
00188 fout << "#include " << *f << "\n";
00189 }
00190 }
00191
00195 void Klass::printMetadata(int n, const map<Tree, set<Tree> >& S, ostream& fout)
00196 {
00197 tab(n,fout); fout << "static void metadata(Meta* m) \t{ ";
00198
00199 for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
00200 if (i->first != tree("author")) {
00201 tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **(i->second.begin()) << ");";
00202 } else {
00203 for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); j++) {
00204 if (j == i->second.begin()) {
00205 tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **j << ");" ;
00206 } else {
00207 tab(n+1,fout); fout << "m->declare(\"" << "contributor" << "\", " << **j << ");";
00208 }
00209 }
00210 }
00211 }
00212
00213 tab(n,fout); fout << "}" << endl;
00214 }
00215
00216 inline bool isElement(const set<Loop*>& S, Loop* l)
00217 {
00218 return S.find(l)!= S.end();
00219 }
00220
00224 void Klass::printLoopDeepFirst(int n, ostream& fout, Loop* l, set<Loop*>& visited)
00225 {
00226
00227 if (isElement(visited, l)) return;
00228
00229
00230 visited.insert(l);
00231
00232
00233 for (lset::const_iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
00234 printLoopDeepFirst(n, fout, *p, visited);
00235 }
00236
00237 tab(n, fout);
00238 tab(n, fout); fout << "// LOOP " << l << ", ORDER " << l->fOrder << endl;
00239 l->println(n+1, fout);
00240 }
00241
00245 static void computeUseCount(Loop* l)
00246 {
00247 l->fUseCount++;
00248 if (l->fUseCount == 1) {
00249 for (lset::iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
00250 computeUseCount(*p);
00251 }
00252 }
00253 }
00254
00258 static void groupSeqLoops(Loop* l)
00259 {
00260 int n = l->fBackwardLoopDependencies.size();
00261 if (n==0) {
00262 return;
00263 } else if (n==1) {
00264 Loop* f = *(l->fBackwardLoopDependencies.begin());
00265 if (f->fUseCount == 1) {
00266 l->concat(f);
00267 groupSeqLoops(l);
00268 } else {
00269 groupSeqLoops(f);
00270 }
00271 return;
00272 } else if (n > 1) {
00273 for (lset::iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
00274 groupSeqLoops(*p);
00275 }
00276 }
00277 }
00278
00279 #define WORK_STEALING_INDEX 0
00280 #define LAST_TASK_INDEX 1
00281 #define START_TASK_INDEX LAST_TASK_INDEX + 1
00282
00283 #define START_TASK_MAX 2
00284
00285 void Klass::buildTasksList()
00286 {
00287 lgraph G;
00288
00289 if (gGroupTaskSwitch) {
00290 computeUseCount(fTopLoop);
00291 groupSeqLoops(fTopLoop);
00292 }
00293
00294 sortGraph(fTopLoop, G);
00295 int index_task = START_TASK_INDEX;
00296
00297 addDeclCode("TaskGraph fGraph;");
00298 addDeclCode("FAUSTFLOAT** input;");
00299 addDeclCode("FAUSTFLOAT** output;");
00300 addDeclCode("volatile bool fIsFinished;");
00301 addDeclCode("int fFullCount;");
00302 addDeclCode("int fIndex;");
00303 addDeclCode("DSPThreadPool fThreadPool;");
00304 addDeclCode("int fStaticNumThreads;");
00305 addDeclCode("int fDynamicNumThreads;");
00306
00307
00308 for (int l=G.size()-1; l>=0; l--) {
00309 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00310 for (lset::const_iterator p1 = (*p)->fBackwardLoopDependencies.begin(); p1!=(*p)->fBackwardLoopDependencies.end(); p1++) {
00311 (*p1)->fForwardLoopDependencies.insert((*p));
00312 }
00313 (*p)->fIndex = index_task;
00314 index_task++;
00315 }
00316 }
00317
00318
00319 vector<int> task_num;
00320 for (int l=G.size()-1; l>=0; l--) {
00321 lset::const_iterator next;
00322 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00323 if ((*p)->fBackwardLoopDependencies.size() == 0) {
00324 task_num.push_back((*p)->fIndex);
00325 }
00326 }
00327 }
00328
00329 if (task_num.size() < START_TASK_MAX) {
00330
00331
00332
00333 addZone3("if (cur_thread == 0) {");
00334
00335 Loop* keep = NULL;
00336 for (int l=G.size()-1; l>=0; l--) {
00337 lset::const_iterator next;
00338 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00339 if ((*p)->fBackwardLoopDependencies.size() == 0) {
00340 if (keep == NULL) {
00341 keep = *p;
00342 } else {
00343 addZone3(subst(" taskqueue.PushHead($0);", T((*p)->fIndex)));
00344 }
00345 }
00346 }
00347 }
00348
00349 if (keep != NULL) {
00350 addZone3(subst(" tasknum = $0;", T(keep->fIndex)));
00351 }
00352
00353 addZone3("} else {");
00354 addZone3(" tasknum = TaskQueue::GetNextTask(cur_thread);");
00355 addZone3("}");
00356
00357 } else {
00358
00359
00360 addZone3(subst("int task_list_size = $0;", T((int)task_num.size())));
00361 stringstream buf;
00362 buf << "int task_list[" << task_num.size() << "] = {";
00363 for(size_t i = 0; i < task_num.size(); i++) {
00364 buf << task_num[i];
00365 if (i != (task_num.size() - 1))
00366 buf << ",";
00367 }
00368 buf << "};";
00369
00370 addZone3(buf.str());
00371 addZone3("taskqueue.InitTaskList(task_list_size, task_list, fDynamicNumThreads, cur_thread, tasknum);");
00372 }
00373
00374
00375 addZone2c("// Initialize end task");
00376 addZone2c(subst("fGraph.InitTask($0,$1);", T(LAST_TASK_INDEX), T((int)G[0].size())));
00377
00378
00379 addZone2c("// Only initialize tasks with inputs");
00380 for (int l=G.size()-1; l>=0; l--) {
00381 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00382 if ((*p)->fBackwardLoopDependencies.size() > 0) {
00383 addZone2c(subst("fGraph.InitTask($0,$1);", T(START_TASK_INDEX + gTaskCount++), T((int)(*p)->fBackwardLoopDependencies.size())));
00384 } else {
00385 gTaskCount++;
00386 }
00387 }
00388 }
00389
00390 addInitCode("fStaticNumThreads = get_max_cpu();");
00391 addInitCode("fDynamicNumThreads = getenv(\"OMP_NUM_THREADS\") ? atoi(getenv(\"OMP_NUM_THREADS\")) : fStaticNumThreads;");
00392 addInitCode("fThreadPool.StartAll(fStaticNumThreads - 1, false, this);");
00393
00394 gTaskCount = 0;
00395 }
00396
00400 void Klass::printLoopGraphVector(int n, ostream& fout)
00401 {
00402 if (gGroupTaskSwitch) {
00403 computeUseCount(fTopLoop);
00404 groupSeqLoops(fTopLoop);
00405 }
00406
00407 lgraph G;
00408 sortGraph(fTopLoop, G);
00409
00410 #if 1
00411
00412 if (gVectorSwitch && gDeepFirstSwitch) {
00413 set<Loop*> visited;
00414 printLoopDeepFirst(n, fout, fTopLoop, visited);
00415 return;
00416 }
00417 #endif
00418
00419
00420 for (int l=G.size()-1; l>=0; l--) {
00421 if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
00422 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00423 (*p)->println(n, fout);
00424 }
00425 }
00426 }
00427
00431 void Klass::printLoopGraphOpenMP(int n, ostream& fout)
00432 {
00433 if (gGroupTaskSwitch) {
00434 computeUseCount(fTopLoop);
00435 groupSeqLoops(fTopLoop);
00436 }
00437
00438 lgraph G;
00439 sortGraph(fTopLoop, G);
00440
00441
00442 for (int l=G.size()-1; l>=0; l--) {
00443 tab(n, fout); fout << "// SECTION : " << G.size() - l;
00444 printLoopLevelOpenMP(n, G.size() - l, G[l], fout);
00445 }
00446 }
00447
00451 void Klass::printLoopGraphScheduler(int n, ostream& fout)
00452 {
00453 if (gGroupTaskSwitch) {
00454 computeUseCount(fTopLoop);
00455 groupSeqLoops(fTopLoop);
00456 }
00457
00458 lgraph G;
00459 sortGraph(fTopLoop, G);
00460
00461
00462 for (int l=G.size()-1; l>0; l--) {
00463 tab(n, fout); fout << "// SECTION : " << G.size() - l;
00464 printLoopLevelScheduler(n, G.size() - l, G[l], fout);
00465 }
00466
00467 printLastLoopLevelScheduler(n, G.size(), G[0], fout);
00468 }
00469
00473 void Klass::printLoopGraphInternal(int n, ostream& fout)
00474 {
00475 lgraph G;
00476 sortGraph(fTopLoop, G);
00477
00478
00479 for (int l=G.size()-1; l>=0; l--) {
00480 if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
00481 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00482 (*p)->printoneln(n, fout);
00483 }
00484 }
00485 }
00486
00487
00488
00489
00490 void Klass::printLoopGraphScalar(int n, ostream& fout)
00491 {
00492 fTopLoop->printoneln(n, fout);
00493 }
00494
00498 static bool nonRecursiveLevel(const lset& L)
00499 {
00500 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00501 if ((*p)->fIsRecursive) return false;
00502 }
00503 return true;
00504 }
00505
00510 void Klass::printLoopLevelOpenMP(int n, int lnum, const lset& L, ostream& fout)
00511 {
00512 if (nonRecursiveLevel(L) && L.size()==1) {
00513 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00514 if ((*p)->isEmpty() == false) {
00515 tab(n, fout); fout << "#pragma omp single ";
00516 tab(n, fout); fout << "{ ";
00517 (*p)->println(n+1, fout);
00518 tab(n, fout); fout << "} ";
00519 }
00520 }
00521
00522 } else if (L.size() > 1) {
00523 tab(n, fout); fout << "#pragma omp sections ";
00524 tab(n, fout); fout << "{ ";
00525 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00526 tab(n+1, fout); fout << "#pragma omp section ";
00527 tab(n+1, fout); fout << "{";
00528 (*p)->println(n+2, fout);
00529 tab(n+1, fout); fout << "} ";
00530 }
00531 tab(n, fout); fout << "} ";
00532 } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
00533 tab(n, fout); fout << "#pragma omp single ";
00534 tab(n, fout); fout << "{ ";
00535 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00536 (*p)->println(n+1, fout);
00537 }
00538 tab(n, fout); fout << "} ";
00539 }
00540 }
00541
00546 void Klass::printLastLoopLevelScheduler(int n, int lnum, const lset& L, ostream& fout)
00547 {
00548 if (nonRecursiveLevel(L) && L.size() == 1 && !(*L.begin())->isEmpty()) {
00549
00550 lset::const_iterator p =L.begin();
00551 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00552 (*p)->println(n+1, fout);
00553 tab(n+1, fout); fout << "tasknum = LAST_TASK_INDEX;";
00554 tab(n+1, fout); fout << "break;";
00555 tab(n, fout); fout << "} ";
00556
00557 } else if (L.size() > 1) {
00558
00559 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00560 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00561 (*p)->println(n+1, fout);
00562 tab(n+1, fout); fout << "fGraph.ActivateOneOutputTask(taskqueue, LAST_TASK_INDEX, tasknum);";
00563 tab(n+1, fout); fout << "break;";
00564 tab(n, fout); fout << "} ";
00565 }
00566
00567 } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
00568
00569 lset::const_iterator p =L.begin();
00570 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00571 (*p)->println(n+1, fout);
00572 tab(n+1, fout); fout << "tasknum = LAST_TASK_INDEX;";
00573 tab(n+1, fout); fout << "break;";
00574 tab(n, fout); fout << "} ";
00575
00576 }
00577 }
00578
00579 void Klass::printOneLoopScheduler(lset::const_iterator p, int n, ostream& fout)
00580 {
00581 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00582 (*p)->println(n+1, fout);
00583
00584
00585 if ((*p)->fForwardLoopDependencies.size() == 1) {
00586
00587 lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin();
00588 if ((*p1)->fBackwardLoopDependencies.size () == 1) {
00589 tab(n+1, fout); fout << subst("tasknum = $0;", T((*p1)->fIndex));
00590 } else {
00591 tab(n+1, fout); fout << subst("fGraph.ActivateOneOutputTask(taskqueue, $0, tasknum);", T((*p1)->fIndex));
00592 }
00593
00594 } else {
00595
00596 Loop* keep = NULL;
00597
00598 for (lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin(); p1!=(*p)->fForwardLoopDependencies.end(); p1++) {
00599 if ((*p1)->fBackwardLoopDependencies.size () == 1) {
00600 keep = *p1;
00601 break;
00602 }
00603 }
00604
00605 if (keep == NULL) {
00606 tab(n+1, fout); fout << "tasknum = WORK_STEALING_INDEX;";
00607 }
00608
00609 for (lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin(); p1!=(*p)->fForwardLoopDependencies.end(); p1++) {
00610 if ((*p1)->fBackwardLoopDependencies.size () == 1) {
00611 if (*p1 != keep) {
00612 tab(n+1, fout); fout << subst("taskqueue.PushHead($0);", T((*p1)->fIndex));
00613 }
00614 } else {
00615 if (keep == NULL) {
00616 tab(n+1, fout); fout << subst("fGraph.ActivateOutputTask(taskqueue, $0, tasknum);", T((*p1)->fIndex));
00617 } else {
00618 tab(n+1, fout); fout << subst("fGraph.ActivateOutputTask(taskqueue, $0);", T((*p1)->fIndex));
00619 }
00620 }
00621 }
00622
00623 if (keep != NULL) {
00624 tab(n+1, fout); fout << subst("tasknum = $0;", T(keep->fIndex));
00625 } else {
00626 tab(n+1, fout); fout << "fGraph.GetReadyTask(taskqueue, tasknum);";
00627 }
00628 }
00629
00630 tab(n+1, fout); fout << "break;";
00631 tab(n, fout); fout << "} ";
00632 }
00633
00639 void Klass::printLoopLevelScheduler(int n, int lnum, const lset& L, ostream& fout)
00640 {
00641 if (nonRecursiveLevel(L) && L.size() == 1 && !(*L.begin())->isEmpty()) {
00642 printOneLoopScheduler(L.begin(), n, fout);
00643 } else if (L.size() > 1) {
00644 for (lset::const_iterator p = L.begin(); p != L.end(); p++) {
00645 printOneLoopScheduler(p, n, fout);
00646 }
00647 } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
00648 printOneLoopScheduler(L.begin(), n, fout);
00649 }
00650 }
00651
00655 void Klass::println(int n, ostream& fout)
00656 {
00657 list<Klass* >::iterator k;
00658
00659 if (gSchedulerSwitch) {
00660 tab(n,fout); fout << "class " << fKlassName << " : public " << fSuperKlassName << ", public Runnable {";
00661 } else {
00662 tab(n,fout); fout << "class " << fKlassName << " : public " << fSuperKlassName << "{";
00663 }
00664
00665 if (gUIMacroSwitch) {
00666 tab(n,fout); fout << " public:";
00667 } else {
00668 tab(n,fout); fout << " private:";
00669 }
00670
00671 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
00672
00673 printlines(n+1, fDeclCode, fout);
00674
00675 tab(n,fout); fout << " public:";
00676
00677 printMetadata(n+1, gMetaDataSet, fout);
00678 tab(n+1,fout); fout << "virtual int getNumInputs() \t{ "
00679 << "return " << fNumInputs
00680 << "; }";
00681 tab(n+1,fout); fout << "virtual int getNumOutputs() \t{ "
00682 << "return " << fNumOutputs
00683 << "; }";
00684
00685 tab(n+1,fout); fout << "static void classInit(int samplingFreq) {";
00686 printlines (n+2, fStaticInitCode, fout);
00687 tab(n+1,fout); fout << "}";
00688
00689 tab(n+1,fout); fout << "virtual void instanceInit(int samplingFreq) {";
00690 tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
00691 printlines (n+2, fInitCode, fout);
00692 tab(n+1,fout); fout << "}";
00693
00694 tab(n+1,fout); fout << "virtual void init(int samplingFreq) {";
00695 tab(n+2,fout); fout << "classInit(samplingFreq);";
00696 tab(n+2,fout); fout << "instanceInit(samplingFreq);";
00697 tab(n+1,fout); fout << "}";
00698
00699
00700 tab(n+1,fout); fout << "virtual void buildUserInterface(UI* interface) {";
00701 printlines (n+2, fUICode, fout);
00702 tab(n+1,fout); fout << "}";
00703
00704 printComputeMethod(n, fout);
00705
00706 tab(n,fout); fout << "};\n" << endl;
00707
00708 printlines(n, fStaticFields, fout);
00709
00710
00711 if (gUIMacroSwitch) {
00712 tab(n, fout); fout << "#ifdef FAUST_UIMACROS";
00713 tab(n+1,fout); fout << "#define FAUST_INPUTS " << fNumInputs;
00714 tab(n+1,fout); fout << "#define FAUST_OUTPUTS " << fNumOutputs;
00715 tab(n+1,fout); fout << "#define FAUST_ACTIVES " << fNumActives;
00716 tab(n+1,fout); fout << "#define FAUST_PASSIVES " << fNumPassives;
00717 printlines(n+1, fUIMacro, fout);
00718 tab(n, fout); fout << "#endif";
00719 }
00720
00721 fout << endl;
00722 }
00723
00727 void Klass::printComputeMethod(int n, ostream& fout)
00728 {
00729 if (gSchedulerSwitch) {
00730 printComputeMethodScheduler (n, fout);
00731 } else if (gOpenMPSwitch) {
00732 printComputeMethodOpenMP (n, fout);
00733 } else if (gVectorSwitch) {
00734 switch (gVectorLoopVariant) {
00735 case 0 : printComputeMethodVectorFaster(n, fout); break;
00736 case 1 : printComputeMethodVectorSimple(n, fout); break;
00737 default : cerr << "unknown loop variant " << gVectorLoopVariant << endl; exit(1);
00738 }
00739 } else {
00740 printComputeMethodScalar(n, fout);
00741 }
00742 }
00743
00744 void Klass::printComputeMethodScalar(int n, ostream& fout)
00745 {
00746 tab(n+1,fout); fout << subst("virtual void compute (int count, $0** input, $0** output) {", xfloat());
00747 printlines (n+2, fZone1Code, fout);
00748 printlines (n+2, fZone2Code, fout);
00749 printlines (n+2, fZone2bCode, fout);
00750 printlines (n+2, fZone3Code, fout);
00751 printLoopGraphScalar (n+2,fout);
00752 tab(n+1,fout); fout << "}";
00753 }
00754
00760 void Klass::printComputeMethodVectorFaster(int n, ostream& fout)
00761 {
00762
00763
00764 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
00765 printlines(n+2, fZone1Code, fout);
00766 printlines(n+2, fZone2Code, fout);
00767 printlines(n+2, fZone2bCode, fout);
00768
00769 tab(n+2,fout); fout << "int index;";
00770 tab(n+2,fout); fout << "for (index = 0; index <= fullcount - " << gVecSize << "; index += " << gVecSize << ") {";
00771 tab(n+3,fout); fout << "// compute by blocks of " << gVecSize << " samples";
00772 tab(n+3,fout); fout << "const int count = " << gVecSize << ";";
00773 printlines (n+3, fZone3Code, fout);
00774 printLoopGraphVector(n+3,fout);
00775 tab(n+2,fout); fout << "}";
00776
00777 tab(n+2,fout); fout << "if (index < fullcount) {";
00778 tab(n+3,fout); fout << "// compute the remaining samples if any";
00779 tab(n+3,fout); fout << "int count = fullcount-index;";
00780 printlines (n+3, fZone3Code, fout);
00781 printLoopGraphVector(n+3,fout);
00782 tab(n+2,fout); fout << "}";
00783 tab(n+1,fout); fout << "}";
00784 }
00785
00789 void Klass::printComputeMethodVectorSimple(int n, ostream& fout)
00790 {
00791
00792
00793 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
00794 printlines(n+2, fZone1Code, fout);
00795 printlines(n+2, fZone2Code, fout);
00796 printlines(n+2, fZone2bCode, fout);
00797 tab(n+2,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
00798 tab(n+3,fout); fout << "int count = min("<< gVecSize << ", fullcount-index);";
00799 printlines (n+3, fZone3Code, fout);
00800 printLoopGraphVector(n+3,fout);
00801 tab(n+2,fout); fout << "}";
00802 tab(n+1,fout); fout << "}";
00803 }
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 void Klass::printComputeMethodOpenMP(int n, ostream& fout)
00861 {
00862
00863
00864 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
00865 printlines(n+2, fZone1Code, fout);
00866 printlines(n+2, fZone2Code, fout);
00867 tab(n+2,fout); fout << "#pragma omp parallel";
00868 printdecllist(n+3, "firstprivate", fFirstPrivateDecl, fout);
00869
00870 tab(n+2,fout); fout << "{";
00871 if (!fZone2bCode.empty()) {
00872 tab(n+3,fout); fout << "#pragma omp single";
00873 tab(n+3,fout); fout << "{";
00874 printlines(n+4, fZone2bCode, fout);
00875 tab(n+3,fout); fout << "}";
00876 }
00877
00878 tab(n+3,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
00879 tab(n+4,fout); fout << "int count = min ("<< gVecSize << ", fullcount-index);";
00880
00881 printlines (n+4, fZone3Code, fout);
00882 printLoopGraphOpenMP (n+4,fout);
00883
00884 tab(n+3,fout); fout << "}";
00885
00886 tab(n+2,fout); fout << "}";
00887 tab(n+1,fout); fout << "}";
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 void Klass::printComputeMethodScheduler (int n, ostream& fout)
00960 {
00961 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
00962
00963 tab(n+2,fout); fout << "GetRealTime();";
00964
00965 tab(n+2,fout); fout << "this->input = input;";
00966 tab(n+2,fout); fout << "this->output = output;";
00967
00968 tab(n+2,fout); fout << "StartMeasure();";
00969
00970 tab(n+2,fout); fout << "for (fIndex = 0; fIndex < fullcount; fIndex += " << gVecSize << ") {";
00971
00972 tab(n+3,fout); fout << "fFullCount = min ("<< gVecSize << ", fullcount-fIndex);";
00973 tab(n+3,fout); fout << "TaskQueue::Init();";
00974 printlines (n+3, fZone2cCode, fout);
00975
00976 tab(n+3,fout); fout << "fIsFinished = false;";
00977 tab(n+3,fout); fout << "fThreadPool.SignalAll(fDynamicNumThreads - 1);";
00978 tab(n+3,fout); fout << "computeThread(0);";
00979 tab(n+3,fout); fout << "while (!fThreadPool.IsFinished()) {}";
00980
00981 tab(n+2,fout); fout << "}";
00982
00983 tab(n+2,fout); fout << "StopMeasure(fStaticNumThreads, fDynamicNumThreads);";
00984
00985 tab(n+1,fout); fout << "}";
00986
00987 tab(n+1,fout); fout << "void computeThread(int cur_thread) {";
00988 printlines (n+2, fZone1Code, fout);
00989 printlines (n+2, fZone2Code, fout);
00990
00991 tab(n+2,fout); fout << "// Init graph state";
00992
00993 tab(n+2,fout); fout << "{";
00994 tab(n+3,fout); fout << "TaskQueue taskqueue;";
00995 tab(n+3,fout); fout << "int tasknum = -1;";
00996 tab(n+3,fout); fout << "int count = fFullCount;";
00997
00998
00999 tab(n+3,fout); fout << "// Init input and output";
01000 printlines (n+3, fZone3Code, fout);
01001
01002 tab(n+3,fout); fout << "while (!fIsFinished) {";
01003 tab(n+4,fout); fout << "switch (tasknum) {";
01004
01005
01006 tab(n+5, fout); fout << "case WORK_STEALING_INDEX: { ";
01007 tab(n+6, fout); fout << "tasknum = TaskQueue::GetNextTask(cur_thread);";
01008 tab(n+6, fout); fout << "break;";
01009 tab(n+5, fout); fout << "} ";
01010
01011
01012 tab(n+5, fout); fout << "case LAST_TASK_INDEX: { ";
01013 tab(n+6, fout); fout << "fIsFinished = true;";
01014 tab(n+6, fout); fout << "break;";
01015 tab(n+5, fout); fout << "} ";
01016
01017 gTaskCount = START_TASK_INDEX ;
01018
01019
01020 printLoopGraphScheduler (n+5,fout);
01021
01022 tab(n+4,fout); fout << "}";
01023 tab(n+3,fout); fout << "}";
01024 tab(n+2,fout); fout << "}";
01025 tab(n+1,fout); fout << "}";
01026 }
01027
01031 void SigIntGenKlass::println(int n, ostream& fout)
01032 {
01033 list<Klass* >::iterator k;
01034
01035 tab(n,fout); fout << "class " << fKlassName << " {";
01036
01037 tab(n,fout); fout << " private:";
01038 tab(n+1,fout); fout << "int \tfSamplingFreq;";
01039
01040 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
01041
01042 printlines(n+1, fDeclCode, fout);
01043
01044 tab(n,fout); fout << " public:";
01045
01046 tab(n+1,fout); fout << "int getNumInputs() \t{ "
01047 << "return " << fNumInputs << "; }";
01048 tab(n+1,fout); fout << "int getNumOutputs() \t{ "
01049 << "return " << fNumOutputs << "; }";
01050
01051 tab(n+1,fout); fout << "void init(int samplingFreq) {";
01052 tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
01053 tab(n+1,fout); fout << "}";
01054
01055 tab(n+1,fout); fout << "void fill (int count, int output[]) {";
01056 printlines (n+2, fZone1Code, fout);
01057 printlines (n+2, fZone2Code, fout);
01058 printlines (n+2, fZone2bCode, fout);
01059 printlines (n+2, fZone3Code, fout);
01060 printLoopGraphInternal (n+2,fout);
01061 tab(n+1,fout); fout << "}";
01062
01063 tab(n,fout); fout << "};\n" << endl;
01064 }
01065
01069 void SigFloatGenKlass::println(int n, ostream& fout)
01070 {
01071 list<Klass* >::iterator k;
01072
01073 tab(n,fout); fout << "class " << fKlassName << " {";
01074
01075 tab(n,fout); fout << " private:";
01076 tab(n+1,fout); fout << "int \tfSamplingFreq;";
01077
01078 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
01079
01080 printlines(n+1, fDeclCode, fout);
01081
01082 tab(n,fout); fout << " public:";
01083
01084 tab(n+1,fout); fout << "int getNumInputs() \t{ "
01085 << "return " << fNumInputs << "; }";
01086 tab(n+1,fout); fout << "int getNumOutputs() \t{ "
01087 << "return " << fNumOutputs << "; }";
01088
01089 tab(n+1,fout); fout << "void init(int samplingFreq) {";
01090 tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
01091 printlines(n+2, fInitCode, fout);
01092 tab(n+1,fout); fout << "}";
01093
01094 tab(n+1,fout); fout << subst("void fill (int count, $0 output[]) {", ifloat());
01095 printlines (n+2, fZone1Code, fout);
01096 printlines (n+2, fZone2Code, fout);
01097 printlines (n+2, fZone2bCode, fout);
01098 printlines (n+2, fZone3Code, fout);
01099 printLoopGraphInternal(n+2,fout);
01100 tab(n+1,fout); fout << "}";
01101
01102 tab(n,fout); fout << "};\n" << endl;
01103 }
01104
01105 static void merge (set<string>& dst, set<string>& src)
01106 {
01107 set<string>::iterator i;
01108 for (i = src.begin(); i != src.end(); i++) dst.insert(*i);
01109 }
01110
01111 void Klass::collectIncludeFile(set<string>& S)
01112 {
01113 list<Klass* >::iterator k;
01114
01115 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->collectIncludeFile(S);
01116 merge(S, fIncludeFileSet);
01117 }
01118
01119 void Klass::collectLibrary(set<string>& S)
01120 {
01121 list<Klass* >::iterator k;
01122
01123 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->collectLibrary(S);
01124 merge(S, fLibrarySet);
01125 }