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 #include "ppsig.hh"
00051
00052 extern bool gVectorSwitch;
00053 extern bool gDeepFirstSwitch;
00054 extern bool gOpenMPSwitch;
00055 extern bool gSchedulerSwitch;
00056 extern int gVecSize;
00057 extern bool gUIMacroSwitch;
00058 extern int gVectorLoopVariant;
00059 extern bool gGroupTaskSwitch;
00060
00061 extern map<Tree, set<Tree> > gMetaDataSet;
00062 static int gTaskCount = 0;
00063
00064 void tab (int n, ostream& fout)
00065 {
00066 fout << '\n';
00067 while (n--) fout << '\t';
00068 }
00069
00070 bool Klass::fNeedPowerDef = false;
00071
00075 void Klass::setLoopProperty(Tree sig, Loop* l)
00076 {
00077 fLoopProperty.set(sig,l);
00078 }
00079
00083 bool Klass::getLoopProperty(Tree sig, Loop*& l)
00084 {
00085 return fLoopProperty.get(sig, l);
00086 }
00087
00092 void Klass::openLoop(const string& size)
00093 {
00094 fTopLoop = new Loop(fTopLoop, size);
00095
00096 }
00097
00103 void Klass::openLoop(Tree recsymbol, const string& size)
00104 {
00105 fTopLoop = new Loop(recsymbol, fTopLoop, size);
00106
00107 }
00108
00113 void Klass::closeLoop(Tree sig)
00114 {
00115 assert(fTopLoop);
00116 Loop* l = fTopLoop;
00117 fTopLoop = l->fEnclosingLoop;
00118 assert(fTopLoop);
00119
00120
00121 if (l->isEmpty() || l->hasRecDependencies()) {
00122
00123
00124 fTopLoop->absorb(l);
00125 delete l;
00126 } else {
00127
00128 if (sig) {
00129 setLoopProperty(sig,l);
00130
00131 } else {
00132
00133 }
00134
00135 fTopLoop->fBackwardLoopDependencies.insert(l);
00136 }
00137 }
00138
00142 void printlines(int n, list<string>& lines, ostream& fout)
00143 {
00144 list<string>::iterator s;
00145 for (s = lines.begin(); s != lines.end(); s++) {
00146 tab(n, fout); fout << *s;
00147 }
00148 }
00149
00153 void printdecllist(int n, const string& decl, list<string>& content, ostream& fout)
00154 {
00155 if (!content.empty()) {
00156 list<string>::iterator s;
00157 fout << "\\";
00158 tab(n, fout); fout << decl;
00159 string sep = "(";
00160 for (s = content.begin(); s != content.end(); s++) {
00161 fout << sep << *s;
00162 sep = ", ";
00163 }
00164 fout << ')';
00165 }
00166 }
00167
00171 void Klass::printLibrary(ostream& fout)
00172 {
00173 set<string> S;
00174 set<string>::iterator f;
00175
00176 string sep;
00177 collectLibrary(S);
00178 fout << "/* link with ";
00179 for (f = S.begin(), sep =": "; f != S.end(); f++, sep = ", ") {
00180 fout << sep << *f;
00181 }
00182 fout << " */\n";
00183 }
00184
00188 void Klass::printIncludeFile(ostream& fout)
00189 {
00190 set<string> S;
00191 set<string>::iterator f;
00192
00193 if (gOpenMPSwitch) {
00194 fout << "#include <omp.h>" << "\n";
00195 }
00196
00197 collectIncludeFile(S);
00198 for (f = S.begin(); f != S.end(); f++) {
00199 fout << "#include " << *f << "\n";
00200 }
00201 }
00202
00206 void Klass::printAdditionalCode(ostream& fout)
00207 {
00208 if (fNeedPowerDef) {
00209
00210 fout << "#include <cmath>" << endl;
00211 fout << "template <int N> inline float faustpower(float x) { return powf(x,N); } " << endl;
00212 fout << "template <int N> inline double faustpower(double x) { return pow(x,N); }" << endl;
00213 fout << "template <int N> inline int faustpower(int x) { return faustpower<N/2>(x) * faustpower<N-N/2>(x); } " << endl;
00214 fout << "template <> inline int faustpower<0>(int x) { return 1; }" << endl;
00215 fout << "template <> inline int faustpower<1>(int x) { return x; }" << endl;
00216 }
00217
00218 }
00219
00223 void Klass::printMetadata(int n, const map<Tree, set<Tree> >& S, ostream& fout)
00224 {
00225 tab(n,fout); fout << "static void metadata(Meta* m) \t{ ";
00226
00227 for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
00228 if (i->first != tree("author")) {
00229 tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **(i->second.begin()) << ");";
00230 } else {
00231 for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); j++) {
00232 if (j == i->second.begin()) {
00233 tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **j << ");" ;
00234 } else {
00235 tab(n+1,fout); fout << "m->declare(\"" << "contributor" << "\", " << **j << ");";
00236 }
00237 }
00238 }
00239 }
00240
00241 tab(n,fout); fout << "}" << endl;
00242 }
00243
00244 inline bool isElement(const set<Loop*>& S, Loop* l)
00245 {
00246 return S.find(l)!= S.end();
00247 }
00248
00252 void Klass::printLoopDeepFirst(int n, ostream& fout, Loop* l, set<Loop*>& visited)
00253 {
00254
00255 if (isElement(visited, l)) return;
00256
00257
00258 visited.insert(l);
00259
00260
00261 for (lset::const_iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
00262 printLoopDeepFirst(n, fout, *p, visited);
00263 }
00264
00265 tab(n, fout);
00266 tab(n, fout); fout << "// LOOP " << l << ", ORDER " << l->fOrder << endl;
00267 l->println(n+1, fout);
00268 }
00269
00273 static void computeUseCount(Loop* l)
00274 {
00275 l->fUseCount++;
00276 if (l->fUseCount == 1) {
00277 for (lset::iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
00278 computeUseCount(*p);
00279 }
00280 }
00281 }
00282
00286 static void groupSeqLoops(Loop* l)
00287 {
00288 int n = l->fBackwardLoopDependencies.size();
00289 if (n==0) {
00290 return;
00291 } else if (n==1) {
00292 Loop* f = *(l->fBackwardLoopDependencies.begin());
00293 if (f->fUseCount == 1) {
00294 l->concat(f);
00295 groupSeqLoops(l);
00296 } else {
00297 groupSeqLoops(f);
00298 }
00299 return;
00300 } else if (n > 1) {
00301 for (lset::iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
00302 groupSeqLoops(*p);
00303 }
00304 }
00305 }
00306
00307 #define WORK_STEALING_INDEX 0
00308 #define LAST_TASK_INDEX 1
00309 #define START_TASK_INDEX LAST_TASK_INDEX + 1
00310
00311 #define START_TASK_MAX 2
00312
00313 void Klass::buildTasksList()
00314 {
00315 lgraph G;
00316
00317 if (gGroupTaskSwitch) {
00318 computeUseCount(fTopLoop);
00319 groupSeqLoops(fTopLoop);
00320 }
00321
00322 sortGraph(fTopLoop, G);
00323 int index_task = START_TASK_INDEX;
00324
00325 addDeclCode("TaskGraph fGraph;");
00326 addDeclCode("FAUSTFLOAT** input;");
00327 addDeclCode("FAUSTFLOAT** output;");
00328 addDeclCode("volatile bool fIsFinished;");
00329 addDeclCode("int fFullCount;");
00330 addDeclCode("int fIndex;");
00331 addDeclCode("DSPThreadPool* fThreadPool;");
00332 addDeclCode("int fStaticNumThreads;");
00333 addDeclCode("int fDynamicNumThreads;");
00334
00335
00336 for (int l=G.size()-1; l>=0; l--) {
00337 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00338 for (lset::const_iterator p1 = (*p)->fBackwardLoopDependencies.begin(); p1!=(*p)->fBackwardLoopDependencies.end(); p1++) {
00339 (*p1)->fForwardLoopDependencies.insert((*p));
00340 }
00341 (*p)->fIndex = index_task;
00342 index_task++;
00343 }
00344 }
00345
00346
00347 vector<int> task_num;
00348 for (int l=G.size()-1; l>=0; l--) {
00349 lset::const_iterator next;
00350 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00351 if ((*p)->fBackwardLoopDependencies.size() == 0) {
00352 task_num.push_back((*p)->fIndex);
00353 }
00354 }
00355 }
00356
00357 if (task_num.size() < START_TASK_MAX) {
00358
00359
00360
00361 addZone3("if (cur_thread == 0) {");
00362
00363 Loop* keep = NULL;
00364 for (int l=G.size()-1; l>=0; l--) {
00365 lset::const_iterator next;
00366 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00367 if ((*p)->fBackwardLoopDependencies.size() == 0) {
00368 if (keep == NULL) {
00369 keep = *p;
00370 } else {
00371 addZone3(subst(" taskqueue.PushHead($0);", T((*p)->fIndex)));
00372 }
00373 }
00374 }
00375 }
00376
00377 if (keep != NULL) {
00378 addZone3(subst(" tasknum = $0;", T(keep->fIndex)));
00379 }
00380
00381 addZone3("} else {");
00382 addZone3(" tasknum = TaskQueue::GetNextTask(cur_thread, fDynamicNumThreads);");
00383 addZone3("}");
00384
00385 } else {
00386
00387
00388 addZone3(subst("int task_list_size = $0;", T((int)task_num.size())));
00389 stringstream buf;
00390 buf << "int task_list[" << task_num.size() << "] = {";
00391 for(size_t i = 0; i < task_num.size(); i++) {
00392 buf << task_num[i];
00393 if (i != (task_num.size() - 1))
00394 buf << ",";
00395 }
00396 buf << "};";
00397
00398 addZone3(buf.str());
00399 addZone3("taskqueue.InitTaskList(task_list_size, task_list, fDynamicNumThreads, cur_thread, tasknum);");
00400 }
00401
00402
00403 if (G[0].size() > 1) {
00404 addZone2c("// Initialize end task, if more than one input");
00405 addZone2c(subst("fGraph.InitTask($0,$1);", T(LAST_TASK_INDEX), T((int)G[0].size())));
00406 } else {
00407 addZone2c("// End task has only one input, so will be directly activated");
00408 }
00409
00410
00411 addZone2c("// Only initialize taks with more than one input");
00412 for (int l=G.size()-1; l>=0; l--) {
00413 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00414 if ((*p)->fBackwardLoopDependencies.size() > 1) {
00415 addZone2c(subst("fGraph.InitTask($0,$1);", T(START_TASK_INDEX + gTaskCount++), T((int)(*p)->fBackwardLoopDependencies.size())));
00416 } else {
00417 gTaskCount++;
00418 }
00419 }
00420 }
00421
00422 addInitCode("fStaticNumThreads = get_max_cpu();");
00423 addInitCode("fDynamicNumThreads = getenv(\"OMP_NUM_THREADS\") ? atoi(getenv(\"OMP_NUM_THREADS\")) : fStaticNumThreads;");
00424 addInitCode("fThreadPool = DSPThreadPool::Init();");
00425 addInitCode("fThreadPool->StartAll(fStaticNumThreads - 1, false);");
00426
00427 gTaskCount = 0;
00428 }
00429
00433 void Klass::printLoopGraphVector(int n, ostream& fout)
00434 {
00435 if (gGroupTaskSwitch) {
00436 computeUseCount(fTopLoop);
00437 groupSeqLoops(fTopLoop);
00438 }
00439
00440 lgraph G;
00441 sortGraph(fTopLoop, G);
00442
00443 #if 1
00444
00445 if (gVectorSwitch && gDeepFirstSwitch) {
00446 set<Loop*> visited;
00447 printLoopDeepFirst(n, fout, fTopLoop, visited);
00448 return;
00449 }
00450 #endif
00451
00452
00453 for (int l=G.size()-1; l>=0; l--) {
00454 if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
00455 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00456 (*p)->println(n, fout);
00457 }
00458 }
00459 }
00460
00464 void Klass::printLoopGraphOpenMP(int n, ostream& fout)
00465 {
00466 if (gGroupTaskSwitch) {
00467 computeUseCount(fTopLoop);
00468 groupSeqLoops(fTopLoop);
00469 }
00470
00471 lgraph G;
00472 sortGraph(fTopLoop, G);
00473
00474
00475 for (int l=G.size()-1; l>=0; l--) {
00476 tab(n, fout); fout << "// SECTION : " << G.size() - l;
00477 printLoopLevelOpenMP(n, G.size() - l, G[l], fout);
00478 }
00479 }
00480
00484 void Klass::printLoopGraphScheduler(int n, ostream& fout)
00485 {
00486 if (gGroupTaskSwitch) {
00487 computeUseCount(fTopLoop);
00488 groupSeqLoops(fTopLoop);
00489 }
00490
00491 lgraph G;
00492 sortGraph(fTopLoop, G);
00493
00494
00495 for (int l=G.size()-1; l>0; l--) {
00496 tab(n, fout); fout << "// SECTION : " << G.size() - l;
00497 printLoopLevelScheduler(n, G.size() - l, G[l], fout);
00498 }
00499
00500 printLastLoopLevelScheduler(n, G.size(), G[0], fout);
00501 }
00502
00503
00507 void Klass::printGraphDotFormat(ostream& fout)
00508 {
00509 lgraph G;
00510 sortGraph(fTopLoop, G);
00511
00512 fout << "strict digraph loopgraph {" << endl;
00513 fout << '\t' << "rankdir=LR;" << endl;
00514 fout << '\t' << "node[color=blue, fillcolor=lightblue, style=filled, fontsize=9];" << endl;
00515
00516 int lnum = 0;
00517
00518 for (int l=G.size()-1; l>=0; l--) {
00519
00520 for (lset::const_iterator t =G[l].begin(); t!=G[l].end(); t++) {
00521
00522 fout << '\t' << 'L'<<(*t)<<"[label=<<font face=\"verdana,bold\">L"<<lnum++<<"</font> : "<<(*t)<<">];"<<endl;
00523
00524 for (lset::const_iterator src = (*t)->fBackwardLoopDependencies.begin(); src!=(*t)->fBackwardLoopDependencies.end(); src++) {
00525
00526 fout << '\t' << 'L'<<(*src)<<"->"<<'L'<<(*t)<<';'<<endl;
00527 }
00528 }
00529 }
00530 fout << "}" << endl;
00531 }
00532
00536 void Klass::printLoopGraphInternal(int n, ostream& fout)
00537 {
00538 lgraph G;
00539 sortGraph(fTopLoop, G);
00540
00541
00542 for (int l=G.size()-1; l>=0; l--) {
00543 if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
00544 for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
00545 (*p)->printoneln(n, fout);
00546 }
00547 }
00548 }
00549
00553 void Klass::printLoopGraphScalar(int n, ostream& fout)
00554 {
00555 fTopLoop->printoneln(n, fout);
00556 }
00557
00561 static bool nonRecursiveLevel(const lset& L)
00562 {
00563 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00564 if ((*p)->fIsRecursive) return false;
00565 }
00566 return true;
00567 }
00568
00573 void Klass::printLoopLevelOpenMP(int n, int lnum, const lset& L, ostream& fout)
00574 {
00575 if (nonRecursiveLevel(L) && L.size()==1) {
00576 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00577 if ((*p)->isEmpty() == false) {
00578 tab(n, fout); fout << "#pragma omp single ";
00579 tab(n, fout); fout << "{ ";
00580 (*p)->println(n+1, fout);
00581 tab(n, fout); fout << "} ";
00582 }
00583 }
00584
00585 } else if (L.size() > 1) {
00586 tab(n, fout); fout << "#pragma omp sections ";
00587 tab(n, fout); fout << "{ ";
00588 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00589 tab(n+1, fout); fout << "#pragma omp section ";
00590 tab(n+1, fout); fout << "{";
00591 (*p)->println(n+2, fout);
00592 tab(n+1, fout); fout << "} ";
00593 }
00594 tab(n, fout); fout << "} ";
00595 } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
00596 tab(n, fout); fout << "#pragma omp single ";
00597 tab(n, fout); fout << "{ ";
00598 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00599 (*p)->println(n+1, fout);
00600 }
00601 tab(n, fout); fout << "} ";
00602 }
00603 }
00604
00609 void Klass::printLastLoopLevelScheduler(int n, int lnum, const lset& L, ostream& fout)
00610 {
00611 if (nonRecursiveLevel(L) && L.size() == 1 && !(*L.begin())->isEmpty()) {
00612
00613 lset::const_iterator p =L.begin();
00614 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00615 (*p)->println(n+1, fout);
00616 tab(n+1, fout); fout << "tasknum = LAST_TASK_INDEX;";
00617 tab(n+1, fout); fout << "break;";
00618 tab(n, fout); fout << "} ";
00619
00620 } else if (L.size() > 1) {
00621
00622 for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
00623 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00624 (*p)->println(n+1, fout);
00625 tab(n+1, fout); fout << "fGraph.ActivateOneOutputTask(taskqueue, LAST_TASK_INDEX, tasknum);";
00626 tab(n+1, fout); fout << "break;";
00627 tab(n, fout); fout << "} ";
00628 }
00629
00630 } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
00631
00632 lset::const_iterator p =L.begin();
00633 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00634 (*p)->println(n+1, fout);
00635 tab(n+1, fout); fout << "tasknum = LAST_TASK_INDEX;";
00636 tab(n+1, fout); fout << "break;";
00637 tab(n, fout); fout << "} ";
00638
00639 }
00640 }
00641
00642 void Klass::printOneLoopScheduler(lset::const_iterator p, int n, ostream& fout)
00643 {
00644 tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
00645 (*p)->println(n+1, fout);
00646
00647
00648 if ((*p)->fForwardLoopDependencies.size() == 1) {
00649
00650 lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin();
00651 if ((*p1)->fBackwardLoopDependencies.size () == 1) {
00652 tab(n+1, fout); fout << subst("tasknum = $0;", T((*p1)->fIndex));
00653 } else {
00654 tab(n+1, fout); fout << subst("fGraph.ActivateOneOutputTask(taskqueue, $0, tasknum);", T((*p1)->fIndex));
00655 }
00656
00657 } else {
00658
00659 Loop* keep = NULL;
00660
00661 for (lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin(); p1!=(*p)->fForwardLoopDependencies.end(); p1++) {
00662 if ((*p1)->fBackwardLoopDependencies.size () == 1) {
00663 keep = *p1;
00664 break;
00665 }
00666 }
00667
00668 if (keep == NULL) {
00669 tab(n+1, fout); fout << "tasknum = WORK_STEALING_INDEX;";
00670 }
00671
00672 for (lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin(); p1!=(*p)->fForwardLoopDependencies.end(); p1++) {
00673 if ((*p1)->fBackwardLoopDependencies.size () == 1) {
00674 if (*p1 != keep) {
00675 tab(n+1, fout); fout << subst("taskqueue.PushHead($0);", T((*p1)->fIndex));
00676 }
00677 } else {
00678 if (keep == NULL) {
00679 tab(n+1, fout); fout << subst("fGraph.ActivateOutputTask(taskqueue, $0, tasknum);", T((*p1)->fIndex));
00680 } else {
00681 tab(n+1, fout); fout << subst("fGraph.ActivateOutputTask(taskqueue, $0);", T((*p1)->fIndex));
00682 }
00683 }
00684 }
00685
00686 if (keep != NULL) {
00687 tab(n+1, fout); fout << subst("tasknum = $0;", T(keep->fIndex));
00688 } else {
00689 tab(n+1, fout); fout << "fGraph.GetReadyTask(taskqueue, tasknum);";
00690 }
00691 }
00692
00693 tab(n+1, fout); fout << "break;";
00694 tab(n, fout); fout << "} ";
00695 }
00696
00702 void Klass::printLoopLevelScheduler(int n, int lnum, const lset& L, ostream& fout)
00703 {
00704 if (nonRecursiveLevel(L) && L.size() == 1 && !(*L.begin())->isEmpty()) {
00705 printOneLoopScheduler(L.begin(), n, fout);
00706 } else if (L.size() > 1) {
00707 for (lset::const_iterator p = L.begin(); p != L.end(); p++) {
00708 printOneLoopScheduler(p, n, fout);
00709 }
00710 } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
00711 printOneLoopScheduler(L.begin(), n, fout);
00712 }
00713 }
00714
00718 void Klass::println(int n, ostream& fout)
00719 {
00720 list<Klass* >::iterator k;
00721
00722 if (gSchedulerSwitch) {
00723 tab(n,fout); fout << "class " << fKlassName << " : public " << fSuperKlassName << ", public Runnable {";
00724 } else {
00725 tab(n,fout); fout << "class " << fKlassName << " : public " << fSuperKlassName << "{";
00726 }
00727
00728 if (gUIMacroSwitch) {
00729 tab(n,fout); fout << " public:";
00730 } else {
00731 tab(n,fout); fout << " private:";
00732 }
00733
00734 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
00735
00736 printlines(n+1, fDeclCode, fout);
00737
00738 tab(n,fout); fout << " public:";
00739
00740 printMetadata(n+1, gMetaDataSet, fout);
00741
00742 if (gSchedulerSwitch) {
00743 tab(n+1,fout); fout << "virtual ~mydsp() \t{ "
00744 << "DSPThreadPool::Destroy()"
00745 << "; }";
00746 }
00747
00748 tab(n+1,fout); fout << "virtual int getNumInputs() \t{ "
00749 << "return " << fNumInputs
00750 << "; }";
00751 tab(n+1,fout); fout << "virtual int getNumOutputs() \t{ "
00752 << "return " << fNumOutputs
00753 << "; }";
00754
00755 tab(n+1,fout); fout << "static void classInit(int samplingFreq) {";
00756 printlines (n+2, fStaticInitCode, fout);
00757 tab(n+1,fout); fout << "}";
00758
00759 tab(n+1,fout); fout << "virtual void instanceInit(int samplingFreq) {";
00760 tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
00761 printlines (n+2, fInitCode, fout);
00762 tab(n+1,fout); fout << "}";
00763
00764 tab(n+1,fout); fout << "virtual void init(int samplingFreq) {";
00765 tab(n+2,fout); fout << "classInit(samplingFreq);";
00766 tab(n+2,fout); fout << "instanceInit(samplingFreq);";
00767 tab(n+1,fout); fout << "}";
00768
00769
00770 tab(n+1,fout); fout << "virtual void buildUserInterface(UI* interface) {";
00771 printlines (n+2, fUICode, fout);
00772 tab(n+1,fout); fout << "}";
00773
00774 printComputeMethod(n, fout);
00775
00776 tab(n,fout); fout << "};\n" << endl;
00777
00778 printlines(n, fStaticFields, fout);
00779
00780
00781 if (gUIMacroSwitch) {
00782 tab(n, fout); fout << "#ifdef FAUST_UIMACROS";
00783 tab(n+1,fout); fout << "#define FAUST_INPUTS " << fNumInputs;
00784 tab(n+1,fout); fout << "#define FAUST_OUTPUTS " << fNumOutputs;
00785 tab(n+1,fout); fout << "#define FAUST_ACTIVES " << fNumActives;
00786 tab(n+1,fout); fout << "#define FAUST_PASSIVES " << fNumPassives;
00787 printlines(n+1, fUIMacro, fout);
00788 tab(n, fout); fout << "#endif";
00789 }
00790
00791 fout << endl;
00792 }
00793
00797 void Klass::printComputeMethod(int n, ostream& fout)
00798 {
00799 if (gSchedulerSwitch) {
00800 printComputeMethodScheduler (n, fout);
00801 } else if (gOpenMPSwitch) {
00802 printComputeMethodOpenMP (n, fout);
00803 } else if (gVectorSwitch) {
00804 switch (gVectorLoopVariant) {
00805 case 0 : printComputeMethodVectorFaster(n, fout); break;
00806 case 1 : printComputeMethodVectorSimple(n, fout); break;
00807 default : cerr << "unknown loop variant " << gVectorLoopVariant << endl; exit(1);
00808 }
00809 } else {
00810 printComputeMethodScalar(n, fout);
00811 }
00812 }
00813
00814 void Klass::printComputeMethodScalar(int n, ostream& fout)
00815 {
00816 tab(n+1,fout); fout << subst("virtual void compute (int count, $0** input, $0** output) {", xfloat());
00817 printlines (n+2, fZone1Code, fout);
00818 printlines (n+2, fZone2Code, fout);
00819 printlines (n+2, fZone2bCode, fout);
00820 printlines (n+2, fZone3Code, fout);
00821 printLoopGraphScalar (n+2,fout);
00822 tab(n+1,fout); fout << "}";
00823 }
00824
00830 void Klass::printComputeMethodVectorFaster(int n, ostream& fout)
00831 {
00832
00833
00834 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
00835 printlines(n+2, fZone1Code, fout);
00836 printlines(n+2, fZone2Code, fout);
00837 printlines(n+2, fZone2bCode, fout);
00838
00839 tab(n+2,fout); fout << "int index;";
00840 tab(n+2,fout); fout << "for (index = 0; index <= fullcount - " << gVecSize << "; index += " << gVecSize << ") {";
00841 tab(n+3,fout); fout << "// compute by blocks of " << gVecSize << " samples";
00842 tab(n+3,fout); fout << "const int count = " << gVecSize << ";";
00843 printlines (n+3, fZone3Code, fout);
00844 printLoopGraphVector(n+3,fout);
00845 tab(n+2,fout); fout << "}";
00846
00847 tab(n+2,fout); fout << "if (index < fullcount) {";
00848 tab(n+3,fout); fout << "// compute the remaining samples if any";
00849 tab(n+3,fout); fout << "int count = fullcount-index;";
00850 printlines (n+3, fZone3Code, fout);
00851 printLoopGraphVector(n+3,fout);
00852 tab(n+2,fout); fout << "}";
00853 tab(n+1,fout); fout << "}";
00854 }
00855
00859 void Klass::printComputeMethodVectorSimple(int n, ostream& fout)
00860 {
00861
00862
00863 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
00864 printlines(n+2, fZone1Code, fout);
00865 printlines(n+2, fZone2Code, fout);
00866 printlines(n+2, fZone2bCode, fout);
00867 tab(n+2,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
00868 tab(n+3,fout); fout << "int count = min("<< gVecSize << ", fullcount-index);";
00869 printlines (n+3, fZone3Code, fout);
00870 printLoopGraphVector(n+3,fout);
00871 tab(n+2,fout); fout << "}";
00872 tab(n+1,fout); fout << "}";
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
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 void Klass::printComputeMethodOpenMP(int n, ostream& fout)
00931 {
00932
00933
00934 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
00935 printlines(n+2, fZone1Code, fout);
00936 printlines(n+2, fZone2Code, fout);
00937 tab(n+2,fout); fout << "#pragma omp parallel";
00938 printdecllist(n+3, "firstprivate", fFirstPrivateDecl, fout);
00939
00940 tab(n+2,fout); fout << "{";
00941 if (!fZone2bCode.empty()) {
00942 tab(n+3,fout); fout << "#pragma omp single";
00943 tab(n+3,fout); fout << "{";
00944 printlines(n+4, fZone2bCode, fout);
00945 tab(n+3,fout); fout << "}";
00946 }
00947
00948 tab(n+3,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
00949 tab(n+4,fout); fout << "int count = min ("<< gVecSize << ", fullcount-index);";
00950
00951 printlines (n+4, fZone3Code, fout);
00952 printLoopGraphOpenMP (n+4,fout);
00953
00954 tab(n+3,fout); fout << "}";
00955
00956 tab(n+2,fout); fout << "}";
00957 tab(n+1,fout); fout << "}";
00958 }
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029 void Klass::printComputeMethodScheduler (int n, ostream& fout)
01030 {
01031 tab(n+1,fout); fout << "void display() {";
01032 tab(n+2,fout); fout << "fGraph.Display();";
01033 tab(n+1,fout); fout << "}";
01034
01035 tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
01036
01037 tab(n+2,fout); fout << "GetRealTime();";
01038
01039 tab(n+2,fout); fout << "this->input = input;";
01040 tab(n+2,fout); fout << "this->output = output;";
01041
01042 tab(n+2,fout); fout << "StartMeasure();";
01043
01044 tab(n+2,fout); fout << "for (fIndex = 0; fIndex < fullcount; fIndex += " << gVecSize << ") {";
01045
01046 tab(n+3,fout); fout << "fFullCount = min ("<< gVecSize << ", fullcount-fIndex);";
01047 tab(n+3,fout); fout << "TaskQueue::Init();";
01048 printlines (n+3, fZone2cCode, fout);
01049
01050 tab(n+3,fout); fout << "fIsFinished = false;";
01051 tab(n+3,fout); fout << "fThreadPool->SignalAll(fDynamicNumThreads - 1, this);";
01052 tab(n+3,fout); fout << "computeThread(0);";
01053 tab(n+3,fout); fout << "while (!fThreadPool->IsFinished()) {}";
01054
01055 tab(n+2,fout); fout << "}";
01056
01057 tab(n+2,fout); fout << "StopMeasure(fStaticNumThreads, fDynamicNumThreads);";
01058
01059 tab(n+1,fout); fout << "}";
01060
01061 tab(n+1,fout); fout << "void computeThread(int cur_thread) {";
01062 printlines (n+2, fZone1Code, fout);
01063 printlines (n+2, fZone2Code, fout);
01064
01065 tab(n+2,fout); fout << "// Init graph state";
01066
01067 tab(n+2,fout); fout << "{";
01068 tab(n+3,fout); fout << "TaskQueue taskqueue(cur_thread);";
01069 tab(n+3,fout); fout << "int tasknum = -1;";
01070 tab(n+3,fout); fout << "int count = fFullCount;";
01071
01072
01073 tab(n+3,fout); fout << "// Init input and output";
01074 printlines (n+3, fZone3Code, fout);
01075
01076 tab(n+3,fout); fout << "while (!fIsFinished) {";
01077 tab(n+4,fout); fout << "switch (tasknum) {";
01078
01079
01080 tab(n+5, fout); fout << "case WORK_STEALING_INDEX: { ";
01081 tab(n+6, fout); fout << "tasknum = TaskQueue::GetNextTask(cur_thread, fDynamicNumThreads);";
01082 tab(n+6, fout); fout << "break;";
01083 tab(n+5, fout); fout << "} ";
01084
01085
01086 tab(n+5, fout); fout << "case LAST_TASK_INDEX: { ";
01087 tab(n+6, fout); fout << "fIsFinished = true;";
01088 tab(n+6, fout); fout << "break;";
01089 tab(n+5, fout); fout << "} ";
01090
01091 gTaskCount = START_TASK_INDEX ;
01092
01093
01094 printLoopGraphScheduler (n+5,fout);
01095
01096 tab(n+4,fout); fout << "}";
01097 tab(n+3,fout); fout << "}";
01098 tab(n+2,fout); fout << "}";
01099 tab(n+1,fout); fout << "}";
01100 }
01101
01105 void SigIntGenKlass::println(int n, ostream& fout)
01106 {
01107 list<Klass* >::iterator k;
01108
01109 tab(n,fout); fout << "class " << fKlassName << " {";
01110
01111 tab(n,fout); fout << " private:";
01112 tab(n+1,fout); fout << "int \tfSamplingFreq;";
01113
01114 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
01115
01116 printlines(n+1, fDeclCode, fout);
01117
01118 tab(n,fout); fout << " public:";
01119
01120 tab(n+1,fout); fout << "int getNumInputs() \t{ "
01121 << "return " << fNumInputs << "; }";
01122 tab(n+1,fout); fout << "int getNumOutputs() \t{ "
01123 << "return " << fNumOutputs << "; }";
01124
01125 tab(n+1,fout); fout << "void init(int samplingFreq) {";
01126 tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
01127 tab(n+1,fout); fout << "}";
01128
01129 tab(n+1,fout); fout << "void fill (int count, int output[]) {";
01130 printlines (n+2, fZone1Code, fout);
01131 printlines (n+2, fZone2Code, fout);
01132 printlines (n+2, fZone2bCode, fout);
01133 printlines (n+2, fZone3Code, fout);
01134 printLoopGraphInternal (n+2,fout);
01135 tab(n+1,fout); fout << "}";
01136
01137 tab(n,fout); fout << "};\n" << endl;
01138 }
01139
01143 void SigFloatGenKlass::println(int n, ostream& fout)
01144 {
01145 list<Klass* >::iterator k;
01146
01147 tab(n,fout); fout << "class " << fKlassName << " {";
01148
01149 tab(n,fout); fout << " private:";
01150 tab(n+1,fout); fout << "int \tfSamplingFreq;";
01151
01152 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
01153
01154 printlines(n+1, fDeclCode, fout);
01155
01156 tab(n,fout); fout << " public:";
01157
01158 tab(n+1,fout); fout << "int getNumInputs() \t{ "
01159 << "return " << fNumInputs << "; }";
01160 tab(n+1,fout); fout << "int getNumOutputs() \t{ "
01161 << "return " << fNumOutputs << "; }";
01162
01163 tab(n+1,fout); fout << "void init(int samplingFreq) {";
01164 tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
01165 printlines(n+2, fInitCode, fout);
01166 tab(n+1,fout); fout << "}";
01167
01168 tab(n+1,fout); fout << subst("void fill (int count, $0 output[]) {", ifloat());
01169 printlines (n+2, fZone1Code, fout);
01170 printlines (n+2, fZone2Code, fout);
01171 printlines (n+2, fZone2bCode, fout);
01172 printlines (n+2, fZone3Code, fout);
01173 printLoopGraphInternal(n+2,fout);
01174 tab(n+1,fout); fout << "}";
01175
01176 tab(n,fout); fout << "};\n" << endl;
01177 }
01178
01179 static void merge (set<string>& dst, set<string>& src)
01180 {
01181 set<string>::iterator i;
01182 for (i = src.begin(); i != src.end(); i++) dst.insert(*i);
01183 }
01184
01185 void Klass::collectIncludeFile(set<string>& S)
01186 {
01187 list<Klass* >::iterator k;
01188
01189 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->collectIncludeFile(S);
01190 merge(S, fIncludeFileSet);
01191 }
01192
01193 void Klass::collectLibrary(set<string>& S)
01194 {
01195 list<Klass* >::iterator k;
01196
01197 for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->collectLibrary(S);
01198 merge(S, fLibrarySet);
01199 }