FAUST compiler  0.9.9.6b8
klass.cpp
Go to the documentation of this file.
1 /************************************************************************
2  ************************************************************************
3  FAUST compiler
4  Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale
5  ---------------------------------------------------------------------
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 
22 
23 
24  /**********************************************************************
25  - klass.cpp : class C++ a remplir (projet FAUST) -
26 
27 
28  Historique :
29  -----------
30  17-10-2001 : implementation initiale (yo)
31  18-10-2001 : Ajout de getFreshID (yo)
32  02-11-2001 : Ajout de sous classes (yo)
33  06-11-2001 : modif impression des classes (yo)
34 
35 ***********************************************************************/
36 
37 #include <stdio.h>
38 #include <iostream>
39 #include <sstream>
40 #include <string>
41 #include <list>
42 #include <map>
43 
44 #include "floats.hh"
45 #include "smartpointer.hh"
46 #include "klass.hh"
47 #include "uitree.hh"
48 #include "Text.hh"
49 #include "signals.hh"
50 #include "ppsig.hh"
51 #include "recursivness.hh"
52 
53 
54 extern int gFloatSize;
55 extern bool gVectorSwitch;
56 extern bool gDeepFirstSwitch;
57 extern bool gOpenMPSwitch;
58 extern bool gOpenMPLoop;
59 extern bool gSchedulerSwitch;
60 extern int gVecSize;
61 extern bool gUIMacroSwitch;
62 extern int gVectorLoopVariant;
63 extern bool gGroupTaskSwitch;
64 
65 extern map<Tree, set<Tree> > gMetaDataSet;
66 static int gTaskCount = 0;
67 
68 void tab (int n, ostream& fout)
69 {
70  fout << '\n';
71  while (n--) fout << '\t';
72 }
73 
74 bool Klass::fNeedPowerDef = false;
75 
80 {
81  fLoopProperty.set(sig,l);
82 }
83 
88 {
89  return fLoopProperty.get(sig, l);
90 }
91 
96 void Klass::openLoop(const string& size)
97 {
98  fTopLoop = new Loop(fTopLoop, size);
99  //cerr << "\nOPEN SHARED LOOP(" << size << ") ----> " << fTopLoop << endl;
100 }
101 
107 void Klass::openLoop(Tree recsymbol, const string& size)
108 {
109  fTopLoop = new Loop(recsymbol, fTopLoop, size);
110  //cerr << "\nOPEN REC LOOP(" << *recsymbol << ", " << size << ") ----> " << fTopLoop << endl;
111 }
112 
118 {
119  assert(fTopLoop);
120  Loop* l = fTopLoop;
122  assert(fTopLoop);
123 
124  //l->println(4, cerr);
125  //cerr << endl;
126 
127  Tree S = symlist(sig);
128  //cerr << "CLOSE LOOP :" << l << " with symbols " << *S << endl;
129  if (l->isEmpty() || fTopLoop->hasRecDependencyIn(S)) {
130  //cout << " will absorb" << endl;
131  // empty or dependent loop -> absorbed by enclosing one
132  //cerr << "absorbed by : " << fTopLoop << endl;
133  fTopLoop->absorb(l);
134  //delete l; HACK !!!
135  } else {
136  // cout << " will NOT absorb" << endl;
137  // we have an independent loop
138  setLoopProperty(sig,l); // associate the signal
140  // we need to indicate that all recursive symbols defined
141  // in this loop are defined in this loop
142  for (Tree lsym=l->fRecSymbolSet; !isNil(lsym); lsym=tl(lsym)) {
143  this->setLoopProperty(hd(lsym), l);
144  //cerr << "loop " << l << " defines " << *hd(lsym) << endl;
145  }
146  }
147  //cerr << "\n" << endl;
148 }
149 
153 void printlines(int n, list<string>& lines, ostream& fout)
154 {
155  list<string>::iterator s;
156  for (s = lines.begin(); s != lines.end(); s++) {
157  tab(n, fout); fout << *s;
158  }
159 }
160 
164 void printdecllist(int n, const string& decl, list<string>& content, ostream& fout)
165 {
166  if (!content.empty()) {
167  list<string>::iterator s;
168  fout << "\\";
169  tab(n, fout); fout << decl;
170  string sep = "(";
171  for (s = content.begin(); s != content.end(); s++) {
172  fout << sep << *s;
173  sep = ", ";
174  }
175  fout << ')';
176  }
177 }
178 
182 void Klass::printLibrary(ostream& fout)
183 {
184  set<string> S;
185  set<string>::iterator f;
186 
187  string sep;
188  collectLibrary(S);
189  fout << "/* link with ";
190  for (f = S.begin(), sep =": "; f != S.end(); f++, sep = ", ") {
191  fout << sep << *f;
192  }
193  fout << " */\n";
194 }
195 
199 void Klass::printIncludeFile(ostream& fout)
200 {
201  set<string> S;
202  set<string>::iterator f;
203 
204  if (gOpenMPSwitch) {
205  fout << "#include <omp.h>" << "\n";
206  }
207 
209  for (f = S.begin(); f != S.end(); f++) {
210  fout << "#include " << *f << "\n";
211  }
212 }
213 
217 void Klass::printAdditionalCode(ostream& fout)
218 {
219  if (fNeedPowerDef) {
220  // Add faustpower definition to C++ code
221  fout << "#ifndef FAUSTPOWER" << endl;
222  fout << "#define FAUSTPOWER" << endl;
223  fout << "#include <cmath>" << endl;
224  fout << "template <int N> inline float faustpower(float x) { return powf(x,N); } " << endl;
225  fout << "template <int N> inline double faustpower(double x) { return pow(x,N); }" << endl;
226  if (gFloatSize == 3) fout << "template <int N> inline long double faustpower(long double x) { return powl(x,N); }" << endl;
227  fout << "template <int N> inline int faustpower(int x) { return faustpower<N/2>(x) * faustpower<N-N/2>(x); } " << endl;
228  fout << "template <> inline int faustpower<0>(int x) { return 1; }" << endl;
229  fout << "template <> inline int faustpower<1>(int x) { return x; }" << endl;
230  fout << "#endif" << endl;
231  }
232 
233 }
234 
238 void Klass::printMetadata(int n, const map<Tree, set<Tree> >& S, ostream& fout)
239 {
240  tab(n,fout); fout << "static void metadata(Meta* m) \t{ ";
241 
242  for (map<Tree, set<Tree> >::iterator i = gMetaDataSet.begin(); i != gMetaDataSet.end(); i++) {
243  if (i->first != tree("author")) {
244  tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **(i->second.begin()) << ");";
245  } else {
246  for (set<Tree>::iterator j = i->second.begin(); j != i->second.end(); j++) {
247  if (j == i->second.begin()) {
248  tab(n+1,fout); fout << "m->declare(\"" << *(i->first) << "\", " << **j << ");" ;
249  } else {
250  tab(n+1,fout); fout << "m->declare(\"" << "contributor" << "\", " << **j << ");";
251  }
252  }
253  }
254  }
255 
256  tab(n,fout); fout << "}" << endl;
257 }
258 
259 inline bool isElement(const set<Loop*>& S, Loop* l)
260 {
261  return S.find(l)!= S.end();
262 }
263 
267 void Klass::printLoopDeepFirst(int n, ostream& fout, Loop* l, set<Loop*>& visited)
268 {
269  // avoid printing already printed loops
270  if (isElement(visited, l)) return;
271 
272  // remember we have printed this loop
273  visited.insert(l);
274 
275  // print the dependencies loops (that need to be computed before this one)
276  for (lset::const_iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
277  printLoopDeepFirst(n, fout, *p, visited);
278  }
279  // the print the loop itself
280  tab(n, fout);
281  tab(n, fout); fout << "// LOOP " << l << ", ORDER " << l->fOrder << endl;
282  l->println(n+1, fout);
283 }
284 
288 static void computeUseCount(Loop* l)
289 {
290  l->fUseCount++;
291  if (l->fUseCount == 1) {
292  for (lset::iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
293  computeUseCount(*p);
294  }
295  }
296 }
297 
301 static void groupSeqLoops(Loop* l)
302 {
303  int n = (int)l->fBackwardLoopDependencies.size();
304  if (n==0) {
305  return;
306  } else if (n==1) {
307  Loop* f = *(l->fBackwardLoopDependencies.begin());
308  if (f->fUseCount == 1) {
309  l->concat(f);
310  groupSeqLoops(l);
311  } else {
312  groupSeqLoops(f);
313  }
314  return;
315  } else if (n > 1) {
316  for (lset::iterator p =l->fBackwardLoopDependencies.begin(); p!=l->fBackwardLoopDependencies.end(); p++) {
317  groupSeqLoops(*p);
318  }
319  }
320 }
321 
322 #define WORK_STEALING_INDEX 0
323 #define LAST_TASK_INDEX 1
324 #define START_TASK_INDEX LAST_TASK_INDEX + 1
325 
326 #define START_TASK_MAX 2
327 
329 {
330  lgraph G;
331 
332  if (gGroupTaskSwitch) {
335  }
336 
337  sortGraph(fTopLoop, G);
338  int index_task = START_TASK_INDEX;
339 
340  addDeclCode("TaskGraph fGraph;");
341  addDeclCode("FAUSTFLOAT** input;");
342  addDeclCode("FAUSTFLOAT** output;");
343  addDeclCode("volatile bool fIsFinished;");
344  addDeclCode("int fFullCount;");
345  addDeclCode("int fIndex;");
346  addDeclCode("DSPThreadPool* fThreadPool;");
347  addDeclCode("int fStaticNumThreads;");
348  addDeclCode("int fDynamicNumThreads;");
349 
350  // Compute forward dependencies
351  for (int l=(int)G.size()-1; l>=0; l--) {
352  for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
353  for (lset::const_iterator p1 = (*p)->fBackwardLoopDependencies.begin(); p1!=(*p)->fBackwardLoopDependencies.end(); p1++) {
354  (*p1)->fForwardLoopDependencies.insert((*p));
355  }
356  (*p)->fIndex = index_task;
357  index_task++;
358  }
359  }
360 
361  // Compute ready tasks list
362  vector<int> task_num;
363  for (int l=(int)G.size()-1; l>=0; l--) {
364  lset::const_iterator next;
365  for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
366  if ((*p)->fBackwardLoopDependencies.size() == 0) {
367  task_num.push_back((*p)->fIndex);
368  }
369  }
370  }
371 
372  if (task_num.size() < START_TASK_MAX) {
373 
374  // Push ready tasks thread 0, execute one task directly
375 
376  addZone3("if (cur_thread == 0) {");
377 
378  Loop* keep = NULL;
379  for (int l=(int)G.size()-1; l>=0; l--) {
380  lset::const_iterator next;
381  for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
382  if ((*p)->fBackwardLoopDependencies.size() == 0) {
383  if (keep == NULL) {
384  keep = *p;
385  } else {
386  addZone3(subst(" taskqueue.PushHead($0);", T((*p)->fIndex)));
387  }
388  }
389  }
390  }
391 
392  if (keep != NULL) {
393  addZone3(subst(" tasknum = $0;", T(keep->fIndex)));
394  }
395 
396  addZone3("} else {");
397  addZone3(" tasknum = TaskQueue::GetNextTask(cur_thread, fDynamicNumThreads);");
398  addZone3("}");
399 
400  } else {
401 
402  // Cut ready tasks list and have each thread (dynamically) use a subpart
403  addZone3(subst("int task_list_size = $0;", T((int)task_num.size())));
404  stringstream buf;
405  buf << "int task_list[" << task_num.size() << "] = {";
406  for(size_t i = 0; i < task_num.size(); i++) {
407  buf << task_num[i];
408  if (i != (task_num.size() - 1))
409  buf << ",";
410  }
411  buf << "};";
412 
413  addZone3(buf.str());
414  addZone3("taskqueue.InitTaskList(task_list_size, task_list, fDynamicNumThreads, cur_thread, tasknum);");
415  }
416 
417  // Last stage connected to end task
418  if (G[0].size() > 1) {
419  addZone2c("// Initialize end task, if more than one input");
420  addZone2c(subst("fGraph.InitTask($0,$1);", T(LAST_TASK_INDEX), T((int)G[0].size())));
421  } else {
422  addZone2c("// End task has only one input, so will be directly activated");
423  }
424 
425  // Compute init section
426  addZone2c("// Only initialize taks with more than one input");
427  for (int l=(int)G.size()-1; l>=0; l--) {
428  for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
429  if ((*p)->fBackwardLoopDependencies.size() > 1) { // Only initialize taks with more than 1 input, since taks with one input are "directly" activated.
430  addZone2c(subst("fGraph.InitTask($0,$1);", T(START_TASK_INDEX + gTaskCount++), T((int)(*p)->fBackwardLoopDependencies.size())));
431  } else {
432  gTaskCount++;
433  }
434  }
435  }
436 
437  addInitCode("fStaticNumThreads = get_max_cpu();");
438  addInitCode("fDynamicNumThreads = getenv(\"OMP_NUM_THREADS\") ? atoi(getenv(\"OMP_NUM_THREADS\")) : fStaticNumThreads;");
439  addInitCode("fThreadPool = DSPThreadPool::Init();");
440  addInitCode("fThreadPool->StartAll(fStaticNumThreads - 1, false);");
441 
442  gTaskCount = 0;
443 }
444 
448 void Klass::printLoopGraphVector(int n, ostream& fout)
449 {
450  if (gGroupTaskSwitch) {
453  }
454 
455  lgraph G;
456  sortGraph(fTopLoop, G);
457 
458 #if 1
459  // EXPERIMENTAL
461  set<Loop*> visited;
462  printLoopDeepFirst(n, fout, fTopLoop, visited);
463  return;
464  }
465 #endif
466 
467  // normal mode
468  for (int l=(int)G.size()-1; l>=0; l--) {
469  if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
470  for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
471  (*p)->println(n, fout);
472  }
473  }
474 }
475 
479 void Klass::printLoopGraphOpenMP(int n, ostream& fout)
480 {
481  if (gGroupTaskSwitch) {
484  }
485 
486  lgraph G;
487  sortGraph(fTopLoop, G);
488 
489  // OpenMP mode : add OpenMP directives
490  for (int l=(int)G.size()-1; l>=0; l--) {
491  tab(n, fout); fout << "// SECTION : " << G.size() - l;
492  printLoopLevelOpenMP(n, (int)G.size() - l, G[l], fout);
493  }
494 }
495 
499 void Klass::printLoopGraphScheduler(int n, ostream& fout)
500 {
501  if (gGroupTaskSwitch) {
504  }
505 
506  lgraph G;
507  sortGraph(fTopLoop, G);
508 
509  // OpenMP mode : add OpenMP directives
510  for (int l=(int)G.size()-1; l>0; l--) {
511  tab(n, fout); fout << "// SECTION : " << G.size() - l;
512  printLoopLevelScheduler(n, (int)G.size() - l, G[l], fout);
513  }
514 
515  printLastLoopLevelScheduler(n, (int)G.size(), G[0], fout);
516 }
517 
518 
522 void Klass::printGraphDotFormat(ostream& fout)
523 {
524  lgraph G;
525  sortGraph(fTopLoop, G);
526 
527  fout << "strict digraph loopgraph {" << endl;
528  fout << '\t' << "rankdir=LR;" << endl;
529  fout << '\t' << "node[color=blue, fillcolor=lightblue, style=filled, fontsize=9];" << endl;
530 
531  int lnum = 0; // used for loop numbers
532  // for each level of the graph
533  for (int l=(int)G.size()-1; l>=0; l--) {
534  // for each task in the level
535  for (lset::const_iterator t =G[l].begin(); t!=G[l].end(); t++) {
536  // print task label "Lxxx : 0xffffff"
537  fout << '\t' << 'L'<<(*t)<<"[label=<<font face=\"verdana,bold\">L"<<lnum++<<"</font> : "<<(*t)<<">];"<<endl;
538  // for each source of the task
539  for (lset::const_iterator src = (*t)->fBackwardLoopDependencies.begin(); src!=(*t)->fBackwardLoopDependencies.end(); src++) {
540  // print the connection Lxxx -> Lyyy;
541  fout << '\t' << 'L'<<(*src)<<"->"<<'L'<<(*t)<<';'<<endl;
542  }
543  }
544  }
545  fout << "}" << endl;
546 }
547 
551 void Klass::printLoopGraphInternal(int n, ostream& fout)
552 {
553  lgraph G;
554  sortGraph(fTopLoop, G);
555 
556  // normal mode
557  for (int l=(int)G.size()-1; l>=0; l--) {
558  if (gVectorSwitch) { tab(n, fout); fout << "// SECTION : " << G.size() - l; }
559  for (lset::const_iterator p =G[l].begin(); p!=G[l].end(); p++) {
560  (*p)->printoneln(n, fout);
561  }
562  }
563 }
564 
568 void Klass::printLoopGraphScalar(int n, ostream& fout)
569 {
570  fTopLoop->printoneln(n, fout);
571 }
572 
576 static bool nonRecursiveLevel(const lset& L)
577 {
578  for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
579  if ((*p)->fIsRecursive) return false;
580  }
581  return true;
582 }
583 
588 void Klass::printLoopLevelOpenMP(int n, int lnum, const lset& L, ostream& fout)
589 {
590  if (nonRecursiveLevel(L) && L.size()==1) {
591  for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
592  if ((*p)->isEmpty() == false) {
593  if (gOpenMPLoop) {
594  (*p)->printParLoopln(n, fout);
595  } else {
596  tab(n, fout); fout << "#pragma omp single ";
597  tab(n, fout); fout << "{ ";
598  (*p)->println(n+1, fout);
599  tab(n, fout); fout << "} ";
600  }
601  }
602  }
603 
604  } else if (L.size() > 1) {
605  tab(n, fout); fout << "#pragma omp sections ";
606  tab(n, fout); fout << "{ ";
607  for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
608  tab(n+1, fout); fout << "#pragma omp section ";
609  tab(n+1, fout); fout << "{";
610  (*p)->println(n+2, fout);
611  tab(n+1, fout); fout << "} ";
612  }
613  tab(n, fout); fout << "} ";
614  } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
615  tab(n, fout); fout << "#pragma omp single ";
616  tab(n, fout); fout << "{ ";
617  for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
618  (*p)->println(n+1, fout);
619  }
620  tab(n, fout); fout << "} ";
621  }
622 }
623 
628 void Klass::printLastLoopLevelScheduler(int n, int lnum, const lset& L, ostream& fout)
629 {
630  if (nonRecursiveLevel(L) && L.size() == 1 && !(*L.begin())->isEmpty()) {
631 
632  lset::const_iterator p =L.begin();
633  tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
634  (*p)->println(n+1, fout);
635  tab(n+1, fout); fout << "tasknum = LAST_TASK_INDEX;";
636  tab(n+1, fout); fout << "break;";
637  tab(n, fout); fout << "} ";
638 
639  } else if (L.size() > 1) {
640 
641  for (lset::const_iterator p =L.begin(); p!=L.end(); p++) {
642  tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
643  (*p)->println(n+1, fout);
644  tab(n+1, fout); fout << "fGraph.ActivateOneOutputTask(taskqueue, LAST_TASK_INDEX, tasknum);";
645  tab(n+1, fout); fout << "break;";
646  tab(n, fout); fout << "} ";
647  }
648 
649  } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
650 
651  lset::const_iterator p =L.begin();
652  tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
653  (*p)->println(n+1, fout);
654  tab(n+1, fout); fout << "tasknum = LAST_TASK_INDEX;";
655  tab(n+1, fout); fout << "break;";
656  tab(n, fout); fout << "} ";
657 
658  }
659 }
660 
661 void Klass::printOneLoopScheduler(lset::const_iterator p, int n, ostream& fout)
662 {
663  tab(n, fout); fout << "case " << gTaskCount++ << ": { ";
664  (*p)->println(n+1, fout);
665 
666  // One output only
667  if ((*p)->fForwardLoopDependencies.size() == 1) {
668 
669  lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin();
670  if ((*p1)->fBackwardLoopDependencies.size () == 1) {
671  tab(n+1, fout); fout << subst("tasknum = $0;", T((*p1)->fIndex));
672  } else {
673  tab(n+1, fout); fout << subst("fGraph.ActivateOneOutputTask(taskqueue, $0, tasknum);", T((*p1)->fIndex));
674  }
675 
676  } else {
677 
678  Loop* keep = NULL;
679  // Find one output with only one backward dependencies
680  for (lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin(); p1!=(*p)->fForwardLoopDependencies.end(); p1++) {
681  if ((*p1)->fBackwardLoopDependencies.size () == 1) {
682  keep = *p1;
683  break;
684  }
685  }
686 
687  if (keep == NULL) {
688  tab(n+1, fout); fout << "tasknum = WORK_STEALING_INDEX;";
689  }
690 
691  for (lset::const_iterator p1 = (*p)->fForwardLoopDependencies.begin(); p1!=(*p)->fForwardLoopDependencies.end(); p1++) {
692  if ((*p1)->fBackwardLoopDependencies.size () == 1) { // Task is the only input
693  if (*p1 != keep) {
694  tab(n+1, fout); fout << subst("taskqueue.PushHead($0);", T((*p1)->fIndex));
695  }
696  } else {
697  if (keep == NULL) {
698  tab(n+1, fout); fout << subst("fGraph.ActivateOutputTask(taskqueue, $0, tasknum);", T((*p1)->fIndex));
699  } else {
700  tab(n+1, fout); fout << subst("fGraph.ActivateOutputTask(taskqueue, $0);", T((*p1)->fIndex));
701  }
702  }
703  }
704 
705  if (keep != NULL) {
706  tab(n+1, fout); fout << subst("tasknum = $0;", T(keep->fIndex)); // Last one
707  } else {
708  tab(n+1, fout); fout << "fGraph.GetReadyTask(taskqueue, tasknum);"; // Last one
709  }
710  }
711 
712  tab(n+1, fout); fout << "break;";
713  tab(n, fout); fout << "} ";
714 }
715 
721 void Klass::printLoopLevelScheduler(int n, int lnum, const lset& L, ostream& fout)
722 {
723  if (nonRecursiveLevel(L) && L.size() == 1 && !(*L.begin())->isEmpty()) {
724  printOneLoopScheduler(L.begin(), n, fout);
725  } else if (L.size() > 1) {
726  for (lset::const_iterator p = L.begin(); p != L.end(); p++) {
727  printOneLoopScheduler(p, n, fout);
728  }
729  } else if (L.size() == 1 && !(*L.begin())->isEmpty()) {
730  printOneLoopScheduler(L.begin(), n, fout);
731  }
732 }
733 
737 void Klass::println(int n, ostream& fout)
738 {
739  list<Klass* >::iterator k;
740 
741  tab(n,fout); fout << "#ifndef FAUSTCLASS " << endl;
742  fout << "#define FAUSTCLASS "<< fKlassName << endl;
743  fout << "#endif" << endl;
744 
745  if (gSchedulerSwitch) {
746  tab(n,fout); fout << "class " << fKlassName << " : public " << fSuperKlassName << ", public Runnable {";
747  } else {
748  tab(n,fout); fout << "class " << fKlassName << " : public " << fSuperKlassName << " {";
749  }
750 
751  if (gUIMacroSwitch) {
752  tab(n,fout); fout << " public:";
753  } else {
754  tab(n,fout); fout << " private:";
755  }
756 
757  for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
758 
759  printlines(n+1, fDeclCode, fout);
760 
761  tab(n,fout); fout << " public:";
762 
763  printMetadata(n+1, gMetaDataSet, fout);
764 
765  if (gSchedulerSwitch) {
766  tab(n+1,fout); fout << "virtual ~" << fKlassName << "() \t{ "
767  << "DSPThreadPool::Destroy()"
768  << "; }";
769  }
770 
771  tab(n+1,fout); fout << "virtual int getNumInputs() \t{ "
772  << "return " << fNumInputs
773  << "; }";
774  tab(n+1,fout); fout << "virtual int getNumOutputs() \t{ "
775  << "return " << fNumOutputs
776  << "; }";
777 
778  tab(n+1,fout); fout << "static void classInit(int samplingFreq) {";
779  printlines (n+2, fStaticInitCode, fout);
780  tab(n+1,fout); fout << "}";
781 
782  tab(n+1,fout); fout << "virtual void instanceInit(int samplingFreq) {";
783  tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
784  printlines (n+2, fInitCode, fout);
785  tab(n+1,fout); fout << "}";
786 
787  tab(n+1,fout); fout << "virtual void init(int samplingFreq) {";
788  tab(n+2,fout); fout << "classInit(samplingFreq);";
789  tab(n+2,fout); fout << "instanceInit(samplingFreq);";
790  tab(n+1,fout); fout << "}";
791 
792 
793  tab(n+1,fout); fout << "virtual void buildUserInterface(UI* interface) {";
794  printlines (n+2, fUICode, fout);
795  tab(n+1,fout); fout << "}";
796 
797  printComputeMethod(n, fout);
798 
799  tab(n,fout); fout << "};\n" << endl;
800 
801  printlines(n, fStaticFields, fout);
802 
803  // generate user interface macros if needed
804  if (gUIMacroSwitch) {
805  tab(n, fout); fout << "#ifdef FAUST_UIMACROS";
806  tab(n+1,fout); fout << "#define FAUST_INPUTS " << fNumInputs;
807  tab(n+1,fout); fout << "#define FAUST_OUTPUTS " << fNumOutputs;
808  tab(n+1,fout); fout << "#define FAUST_ACTIVES " << fNumActives;
809  tab(n+1,fout); fout << "#define FAUST_PASSIVES " << fNumPassives;
810  printlines(n+1, fUIMacro, fout);
811  tab(n, fout); fout << "#endif";
812  }
813 
814  fout << endl;
815 }
816 
820 void Klass::printComputeMethod(int n, ostream& fout)
821 {
822  if (gSchedulerSwitch) {
823  printComputeMethodScheduler (n, fout);
824  } else if (gOpenMPSwitch) {
825  printComputeMethodOpenMP (n, fout);
826  } else if (gVectorSwitch) {
827  switch (gVectorLoopVariant) {
828  case 0 : printComputeMethodVectorFaster(n, fout); break;
829  case 1 : printComputeMethodVectorSimple(n, fout); break;
830  default : cerr << "unknown loop variant " << gVectorLoopVariant << endl; exit(1);
831  }
832  } else {
833  printComputeMethodScalar(n, fout);
834  }
835 }
836 
837 void Klass::printComputeMethodScalar(int n, ostream& fout)
838 {
839  tab(n+1,fout); fout << subst("virtual void compute (int count, $0** input, $0** output) {", xfloat());
840  printlines (n+2, fZone1Code, fout);
841  printlines (n+2, fZone2Code, fout);
842  printlines (n+2, fZone2bCode, fout);
843  printlines (n+2, fZone3Code, fout);
844  printLoopGraphScalar (n+2,fout);
845  tab(n+1,fout); fout << "}";
846 }
847 
853 void Klass::printComputeMethodVectorFaster(int n, ostream& fout)
854 {
855  // in vector mode we need to split loops in smaller pieces not larger
856  // than gVecSize
857  tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
858  printlines(n+2, fZone1Code, fout);
859  printlines(n+2, fZone2Code, fout);
860  printlines(n+2, fZone2bCode, fout);
861 
862  tab(n+2,fout); fout << "int index;";
863  tab(n+2,fout); fout << "for (index = 0; index <= fullcount - " << gVecSize << "; index += " << gVecSize << ") {";
864  tab(n+3,fout); fout << "// compute by blocks of " << gVecSize << " samples";
865  tab(n+3,fout); fout << "const int count = " << gVecSize << ";";
866  printlines (n+3, fZone3Code, fout);
867  printLoopGraphVector(n+3,fout);
868  tab(n+2,fout); fout << "}";
869 
870  tab(n+2,fout); fout << "if (index < fullcount) {";
871  tab(n+3,fout); fout << "// compute the remaining samples if any";
872  tab(n+3,fout); fout << "int count = fullcount-index;";
873  printlines (n+3, fZone3Code, fout);
874  printLoopGraphVector(n+3,fout);
875  tab(n+2,fout); fout << "}";
876  tab(n+1,fout); fout << "}";
877 }
878 
882 void Klass::printComputeMethodVectorSimple(int n, ostream& fout)
883 {
884  // in vector mode we need to split loops in smaller pieces not larger
885  // than gVecSize
886  tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
887  printlines(n+2, fZone1Code, fout);
888  printlines(n+2, fZone2Code, fout);
889  printlines(n+2, fZone2bCode, fout);
890  tab(n+2,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
891  tab(n+3,fout); fout << "int count = min("<< gVecSize << ", fullcount-index);";
892  printlines (n+3, fZone3Code, fout);
893  printLoopGraphVector(n+3,fout);
894  tab(n+2,fout); fout << "}";
895  tab(n+1,fout); fout << "}";
896 }
897 
898 /*
899 void Klass::printComputeMethodVectorFix0 (int n, ostream& fout)
900 {
901  // in vector mode we need to split loops in smaller pieces not larger
902  // than gVecSize
903  tab(n+1,fout); fout << "virtual void compute (int fullcount, float** input, float** output) {";
904  printlines(n+2, fZone1Code, fout);
905  printlines(n+2, fZone2Code, fout);
906  printlines(n+2, fZone2bCode, fout);
907  tab(n+2,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
908  tab(n+3,fout); fout << "if (fullcount >= index + " << gVecSize << ") {";
909  tab(n+4,fout); fout << "// compute by blocks of " << gVecSize << " samples";
910  tab(n+4,fout); fout << "const int count = " << gVecSize << ";"; // temporaire
911  printlines(n+4, fZone3Code, fout);
912  printLoopGraph (n+4,fout);
913  tab(n+3,fout); fout << "} else if (fullcount > index) {";
914  //tab(n+3,fout); fout << "int count = min ("<< gVecSize << ", fullcount-index);";
915  tab(n+4,fout); fout << "// compute the remaining samples";
916  tab(n+4,fout); fout << "int count = fullcount-index;" ;
917  printlines(n+4, fZone3Code, fout);
918  printLoopGraph (n+4,fout);
919  tab(n+3,fout); fout << "}";
920  tab(n+2,fout); fout << "}";
921  tab(n+1,fout); fout << "}";
922 }
923 
924 void Klass::printComputeMethodVectorFix1 (int n, ostream& fout)
925 {
926  // in vector mode we need to split loops in smaller pieces not larger
927  // than gVecSize
928  tab(n+1,fout); fout << "virtual void compute (int fullcount, float** input, float** output) {";
929  printlines(n+2, fZone1Code, fout);
930  printlines(n+2, fZone2Code, fout);
931  printlines(n+2, fZone2bCode, fout);
932 
933  tab(n+2,fout); fout << "int \tblock;";
934  tab(n+2,fout); fout << "for (block = 0; block < fullcount/" << gVecSize << "; block++) {";
935  tab(n+3,fout); fout << "// compute by blocks of " << gVecSize << " samples";
936  tab(n+3,fout); fout << "const int index = block*" << gVecSize << ";";
937  tab(n+3,fout); fout << "const int count = " << gVecSize << ";"; // temporaire
938  printlines(n+3, fZone3Code, fout);
939  printLoopGraph (n+3,fout);
940  tab(n+2,fout); fout << "}";
941 
942  tab(n+2,fout); fout << "if (fullcount%" << gVecSize << " != 0) {";
943  //tab(n+3,fout); fout << "int count = min ("<< gVecSize << ", fullcount-index);";
944  tab(n+3,fout); fout << "// compute the remaining samples";
945  tab(n+3,fout); fout << "const int index = block*" << gVecSize << ";";
946  tab(n+3,fout); fout << "int count = fullcount%" << gVecSize << ";" ;
947  printlines(n+3, fZone3Code, fout);
948  printLoopGraph (n+3,fout);
949  tab(n+2,fout); fout << "}";
950  tab(n+1,fout); fout << "}";
951 }*/
952 
953 void Klass::printComputeMethodOpenMP(int n, ostream& fout)
954 {
955  // in openMP mode we need to split loops in smaller pieces not larger
956  // than gVecSize and add OpenMP pragmas
957  tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
958  printlines(n+2, fZone1Code, fout);
959  printlines(n+2, fZone2Code, fout);
960  tab(n+2,fout); fout << "#pragma omp parallel";
961  printdecllist(n+3, "firstprivate", fFirstPrivateDecl, fout);
962 
963  tab(n+2,fout); fout << "{";
964  if (!fZone2bCode.empty()) {
965  tab(n+3,fout); fout << "#pragma omp single";
966  tab(n+3,fout); fout << "{";
967  printlines(n+4, fZone2bCode, fout);
968  tab(n+3,fout); fout << "}";
969  }
970 
971  tab(n+3,fout); fout << "for (int index = 0; index < fullcount; index += " << gVecSize << ") {";
972  tab(n+4,fout); fout << "int count = min ("<< gVecSize << ", fullcount-index);";
973 
974  printlines (n+4, fZone3Code, fout);
975  printLoopGraphOpenMP (n+4,fout);
976 
977  tab(n+3,fout); fout << "}";
978 
979  tab(n+2,fout); fout << "}";
980  tab(n+1,fout); fout << "}";
981 }
982 
983 /*
984 void Klass::printComputeMethodScheduler (int n, ostream& fout)
985 {
986  tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
987  printlines (n+2, fZone1Code, fout);
988  printlines (n+2, fZone2Code, fout);
989 
990  // Init input and output
991  tab(n+2,fout); fout << "// Init input and output";
992  printlines (n+2, fZone3aCode, fout);
993  printlines (n+2, fZone3bCode, fout);
994 
995  tab(n+2,fout); fout << "// Init graph state";
996  tab(n+2,fout); fout << "initState(fTasksList);";
997  tab(n+2,fout); fout << "bool is_finished = false;";
998  tab(n+2,fout); fout << "unsigned int index_in = 0;";
999  tab(n+2,fout); fout << "unsigned int index_out = 0;";
1000  tab(n+2,fout); fout << "int count = min ("<< gVecSize << ", fullcount);";
1001 
1002  tab(n+2,fout); fout << "InitSchedulingMap();";
1003  tab(n+2,fout); fout << "#pragma omp parallel";
1004  printdecllist(n+3, "firstprivate", fFirstPrivateDecl, fout);
1005 
1006  tab(n+2,fout); fout << "{";
1007  tab(n+3,fout); fout << "while (!is_finished) {";
1008  tab(n+4,fout); fout << "Task* task = searchTaskToAcquire(fTasksList);";
1009  tab(n+4,fout); fout << "if (task != NULL) {";
1010  tab(n+5,fout); fout << "bool last_cycle_for_thread = false;";
1011  tab(n+5,fout); fout << "do {";
1012  tab(n+6,fout); fout << "AddTaskToScheduling(task);";
1013  tab(n+6,fout); fout << "switch (task->fNum) {";
1014 
1015  // DSP tasks
1016  printLoopGraph (n+7,fout);
1017 
1018  // Input task
1019  tab(n+7, fout); fout << "case " << gTaskCount++ << ": { ";
1020  printlines (n+8, fZone6Code, fout);
1021  tab(n+8, fout); fout << "index_in += count;";
1022  tab(n+8, fout); fout << "last_cycle_for_thread = (index_in > fullcount);";
1023  tab(n+8, fout); fout << "break;";
1024  tab(n+7, fout); fout << "} ";
1025 
1026  // Output task
1027  tab(n+7, fout); fout << "case " << gTaskCount++ << ": { ";
1028  printlines (n+8, fZone7Code, fout);
1029  tab(n+8, fout); fout << "index_out += count;";
1030  tab(n+8, fout); fout << "last_cycle_for_thread = (index_out > fullcount);";
1031  tab(n+8, fout); fout << "break;";
1032  tab(n+7, fout); fout << "} ";
1033 
1034  // End task
1035  tab(n+7, fout); fout << "case " << gTaskCount++ << ": { ";
1036  tab(n+8, fout); fout << "is_finished = ((index_in >= fullcount) && (index_out >= fullcount));";
1037  tab(n+8, fout); fout << "break;";
1038  tab(n+7, fout); fout << "} ";
1039 
1040  tab(n+6,fout); fout << "}";
1041  tab(n+6,fout); fout << "if (last_cycle_for_thread) break;";
1042 
1043  tab(n+5,fout); fout << "} while ((task = task->concludeAndTryToAcquireNext()) != NULL);";
1044  tab(n+4,fout); fout << "}";
1045  tab(n+3,fout); fout << "}";
1046  tab(n+2,fout); fout << "}";
1047  tab(n+2,fout); fout << "PrintSchedulingMap();";
1048  tab(n+1,fout); fout << "}";
1049 }
1050 */
1051 
1052 void Klass::printComputeMethodScheduler (int n, ostream& fout)
1053 {
1054  tab(n+1,fout); fout << "void display() {";
1055  tab(n+2,fout); fout << "fGraph.Display();";
1056  tab(n+1,fout); fout << "}";
1057 
1058  tab(n+1,fout); fout << subst("virtual void compute (int fullcount, $0** input, $0** output) {", xfloat());
1059 
1060  tab(n+2,fout); fout << "GetRealTime();";
1061 
1062  tab(n+2,fout); fout << "this->input = input;";
1063  tab(n+2,fout); fout << "this->output = output;";
1064 
1065  tab(n+2,fout); fout << "StartMeasure();";
1066 
1067  tab(n+2,fout); fout << "for (fIndex = 0; fIndex < fullcount; fIndex += " << gVecSize << ") {";
1068 
1069  tab(n+3,fout); fout << "fFullCount = min ("<< gVecSize << ", fullcount-fIndex);";
1070  tab(n+3,fout); fout << "TaskQueue::Init();";
1071  printlines (n+3, fZone2cCode, fout);
1072 
1073  tab(n+3,fout); fout << "fIsFinished = false;";
1074  tab(n+3,fout); fout << "fThreadPool->SignalAll(fDynamicNumThreads - 1, this);";
1075  tab(n+3,fout); fout << "computeThread(0);";
1076  tab(n+3,fout); fout << "while (!fThreadPool->IsFinished()) {}";
1077 
1078  tab(n+2,fout); fout << "}";
1079 
1080  tab(n+2,fout); fout << "StopMeasure(fStaticNumThreads, fDynamicNumThreads);";
1081 
1082  tab(n+1,fout); fout << "}";
1083 
1084  tab(n+1,fout); fout << "void computeThread(int cur_thread) {";
1085  printlines (n+2, fZone1Code, fout);
1086  printlines (n+2, fZone2Code, fout);
1087 
1088  tab(n+2,fout); fout << "// Init graph state";
1089 
1090  tab(n+2,fout); fout << "{";
1091  tab(n+3,fout); fout << "TaskQueue taskqueue(cur_thread);";
1092  tab(n+3,fout); fout << "int tasknum = -1;";
1093  tab(n+3,fout); fout << "int count = fFullCount;";
1094 
1095  // Init input and output
1096  tab(n+3,fout); fout << "// Init input and output";
1097  printlines (n+3, fZone3Code, fout);
1098 
1099  tab(n+3,fout); fout << "while (!fIsFinished) {";
1100  tab(n+4,fout); fout << "switch (tasknum) {";
1101 
1102  // Work stealing task
1103  tab(n+5, fout); fout << "case WORK_STEALING_INDEX: { ";
1104  tab(n+6, fout); fout << "tasknum = TaskQueue::GetNextTask(cur_thread, fDynamicNumThreads);";
1105  tab(n+6, fout); fout << "break;";
1106  tab(n+5, fout); fout << "} ";
1107 
1108  // End task
1109  tab(n+5, fout); fout << "case LAST_TASK_INDEX: { ";
1110  tab(n+6, fout); fout << "fIsFinished = true;";
1111  tab(n+6, fout); fout << "break;";
1112  tab(n+5, fout); fout << "} ";
1113 
1115 
1116  // DSP tasks
1117  printLoopGraphScheduler (n+5,fout);
1118 
1119  tab(n+4,fout); fout << "}";
1120  tab(n+3,fout); fout << "}";
1121  tab(n+2,fout); fout << "}";
1122  tab(n+1,fout); fout << "}";
1123 }
1124 
1128 void SigIntGenKlass::println(int n, ostream& fout)
1129 {
1130  list<Klass* >::iterator k;
1131 
1132  tab(n,fout); fout << "class " << fKlassName << " {";
1133 
1134  tab(n,fout); fout << " private:";
1135  tab(n+1,fout); fout << "int \tfSamplingFreq;";
1136 
1137  for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
1138 
1139  printlines(n+1, fDeclCode, fout);
1140 
1141  tab(n,fout); fout << " public:";
1142 
1143  tab(n+1,fout); fout << "int getNumInputs() \t{ "
1144  << "return " << fNumInputs << "; }";
1145  tab(n+1,fout); fout << "int getNumOutputs() \t{ "
1146  << "return " << fNumOutputs << "; }";
1147 
1148  tab(n+1,fout); fout << "void init(int samplingFreq) {";
1149  tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
1150  printlines(n+2, fInitCode, fout);
1151  tab(n+1,fout); fout << "}";
1152 
1153  tab(n+1,fout); fout << "void fill (int count, int output[]) {";
1154  printlines (n+2, fZone1Code, fout);
1155  printlines (n+2, fZone2Code, fout);
1156  printlines (n+2, fZone2bCode, fout);
1157  printlines (n+2, fZone3Code, fout);
1158  printLoopGraphInternal (n+2,fout);
1159  tab(n+1,fout); fout << "}";
1160 
1161  tab(n,fout); fout << "};\n" << endl;
1162 }
1163 
1167 void SigFloatGenKlass::println(int n, ostream& fout)
1168 {
1169  list<Klass* >::iterator k;
1170 
1171  tab(n,fout); fout << "class " << fKlassName << " {";
1172 
1173  tab(n,fout); fout << " private:";
1174  tab(n+1,fout); fout << "int \tfSamplingFreq;";
1175 
1176  for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->println(n+1, fout);
1177 
1178  printlines(n+1, fDeclCode, fout);
1179 
1180  tab(n,fout); fout << " public:";
1181 
1182  tab(n+1,fout); fout << "int getNumInputs() \t{ "
1183  << "return " << fNumInputs << "; }";
1184  tab(n+1,fout); fout << "int getNumOutputs() \t{ "
1185  << "return " << fNumOutputs << "; }";
1186 
1187  tab(n+1,fout); fout << "void init(int samplingFreq) {";
1188  tab(n+2,fout); fout << "fSamplingFreq = samplingFreq;";
1189  printlines(n+2, fInitCode, fout);
1190  tab(n+1,fout); fout << "}";
1191 
1192  tab(n+1,fout); fout << subst("void fill (int count, $0 output[]) {", ifloat());
1193  printlines (n+2, fZone1Code, fout);
1194  printlines (n+2, fZone2Code, fout);
1195  printlines (n+2, fZone2bCode, fout);
1196  printlines (n+2, fZone3Code, fout);
1197  printLoopGraphInternal(n+2,fout);
1198  tab(n+1,fout); fout << "}";
1199 
1200  tab(n,fout); fout << "};\n" << endl;
1201 }
1202 
1203 static void merge (set<string>& dst, set<string>& src)
1204 {
1205  set<string>::iterator i;
1206  for (i = src.begin(); i != src.end(); i++) dst.insert(*i);
1207 }
1208 
1209 void Klass::collectIncludeFile(set<string>& S)
1210 {
1211  list<Klass* >::iterator k;
1212 
1213  for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->collectIncludeFile(S);
1214  merge(S, fIncludeFileSet);
1215 }
1216 
1217 void Klass::collectLibrary(set<string>& S)
1218 {
1219  list<Klass* >::iterator k;
1220 
1221  for (k = fSubClassList.begin(); k != fSubClassList.end(); k++) (*k)->collectLibrary(S);
1222  merge(S, fLibrarySet);
1223 }
list< string > fDeclCode
Definition: klass.hh:79
void addZone2c(const string &str)
Definition: klass.hh:171
void println(int n, ostream &fout)
print the loop
Definition: loop.cpp:134
static bool nonRecursiveLevel(const lset &L)
returns true if all the loops are non recursive
Definition: klass.cpp:576
void buildTasksList()
Definition: klass.cpp:328
virtual void println(int n, ostream &fout)
Print an auxillary C++ class corresponding to an integer init signal.
Definition: klass.cpp:1128
int gFloatSize
Definition: main.cpp:153
virtual void printComputeMethodVectorFaster(int n, ostream &fout)
Uses loops of constant gVecSize boundary in order to provide the C compiler with more optimisation op...
Definition: klass.cpp:853
set< Loop * > lset
Definition: graphSorting.hh:10
void collectLibrary(set< string > &S)
Definition: klass.cpp:1217
void tab(int n, ostream &fout)
Definition: klass.cpp:68
Loop * fTopLoop
active loops currently open
Definition: klass.hh:102
#define LAST_TASK_INDEX
Definition: klass.cpp:323
void setLoopProperty(Tree sig, Loop *l)
Store the loop used to compute a signal.
Definition: klass.cpp:79
virtual void printAdditionalCode(ostream &fout)
Print additional functions required by the generated code.
Definition: klass.cpp:217
static void merge(set< string > &dst, set< string > &src)
Definition: klass.cpp:1203
void collectIncludeFile(set< string > &S)
Definition: klass.cpp:1209
list< string > fInitCode
Definition: klass.hh:82
virtual void printComputeMethodVectorSimple(int n, ostream &fout)
Simple loop layout, generally less efficient than printComputeMethodVectorFaster. ...
Definition: klass.cpp:882
virtual void println(int n, ostream &fout)
Print a full C++ class corresponding to a Faust dsp.
Definition: klass.cpp:737
int gVectorLoopVariant
Definition: main.cpp:141
Loop *const fEnclosingLoop
Loop from which this one originated.
Definition: loop.hh:56
list< string > fZone3Code
private every sub block
Definition: klass.hh:100
list< string > fZone2Code
first private
Definition: klass.hh:97
int fNumInputs
Definition: klass.hh:69
void printlines(int n, list< string > &lines, ostream &fout)
Print a list of lines.
Definition: klass.cpp:153
list< string > fZone2bCode
single once per block
Definition: klass.hh:98
A CTree = (Node x [CTree]) is a Node associated with a list of subtrees called branches.
Definition: tree.hh:109
void openLoop(const string &size)
Open a non-recursive loop on top of the stack of open loops.
Definition: klass.cpp:96
virtual void printLoopGraphInternal(int n, ostream &fout)
Print the loop graph (used for internals classes)
Definition: klass.cpp:551
virtual void printComputeMethod(int n, ostream &fout)
Print Compute() method according to the various switch.
Definition: klass.cpp:820
Tree hd(Tree l)
Definition: list.hh:133
static bool fNeedPowerDef
true when faustpower definition is needed
Definition: klass.hh:61
const char * xfloat()
Definition: floats.cpp:49
bool gSchedulerSwitch
Definition: main.cpp:145
list< string > fStaticFields
static fields after class
Definition: klass.hh:81
#define START_TASK_MAX
Definition: klass.cpp:326
void closeLoop(Tree sig)
Close the top loop and either keep it or absorb it within its enclosing loop.
Definition: klass.cpp:117
virtual void printOneLoopScheduler(lset::const_iterator p, int n, ostream &fout)
Definition: klass.cpp:661
list< string > fUIMacro
Definition: klass.hh:84
vector< lset > lgraph
Definition: graphSorting.hh:12
int fUseCount
how many loops depend on this one
Definition: loop.hh:68
virtual void printGraphDotFormat(ostream &fout)
Print the loop graph in dot format.
Definition: klass.cpp:522
list< string > fZone2cCode
single once per block
Definition: klass.hh:99
void addInitCode(const string &str)
Definition: klass.hh:151
virtual void printComputeMethodScalar(int n, ostream &fout)
Definition: klass.cpp:837
int fNumActives
number of active controls in the UI (sliders, buttons, etc.)
Definition: klass.hh:71
bool isNil(Tree l)
Definition: list.hh:137
void set(Tree t, const P &data)
Definition: property.hh:22
void concat(Loop *l)
Definition: loop.cpp:237
static int gTaskCount
Definition: klass.cpp:66
static void computeUseCount(Loop *l)
Compute how many time each loop is used in a DAG.
Definition: klass.cpp:288
bool isEmpty()
true when the loop doesn't contain any line of code
Definition: loop.cpp:74
virtual void printLoopLevelOpenMP(int n, int lnum, const lset &L, ostream &fout)
Print the 'level' of the loop graph as a set of parallel loops.
Definition: klass.cpp:588
virtual void println(int n, ostream &fout)
Print an auxillary C++ class corresponding to an float init signal.
Definition: klass.cpp:1167
list< string > fFirstPrivateDecl
first private declarations
Definition: klass.hh:94
#define START_TASK_INDEX
Definition: klass.cpp:324
void printoneln(int n, ostream &fout)
print the loop in scalar mode
Definition: loop.cpp:214
bool getLoopProperty(Tree sig, Loop *&l)
Returns the loop used to compute a signal.
Definition: klass.cpp:87
Tree fRecSymbolSet
recursive loops define a set of recursive symbol
Definition: loop.hh:55
string subst(const string &model, const vector< string > &args)
Text substitution.
Definition: Text.cpp:47
set< string > fLibrarySet
Definition: klass.hh:75
virtual void printIncludeFile(ostream &fout)
Print the required include files.
Definition: klass.cpp:199
void printdecllist(int n, const string &decl, list< string > &content, ostream &fout)
Print a list of elements (e1, e2,...)
Definition: klass.cpp:164
virtual void printLoopGraphOpenMP(int n, ostream &fout)
Print the loop graph as a serie of parallel loops.
Definition: klass.cpp:479
virtual void printLoopDeepFirst(int n, ostream &fout, Loop *l, set< Loop * > &visited)
Print a loop graph deep first.
Definition: klass.cpp:267
string T(char *c)
Definition: Text.cpp:158
int fNumPassives
number of passive widgets in the UI (bargraphs, etc.)
Definition: klass.hh:72
bool isElement(const set< Loop * > &S, Loop *l)
Definition: klass.cpp:259
bool get(Tree t, P &data)
Definition: property.hh:32
int fNumOutputs
Definition: klass.hh:70
bool gOpenMPLoop
Definition: main.cpp:144
map< Tree, set< Tree > > gMetaDataSet
Definition: main.cpp:91
void absorb(Loop *l)
absorb a loop inside this one
Definition: loop.cpp:113
bool hasRecDependencyIn(Tree S)
returns true is this loop or its ancestors define a symbol in S
Definition: loop.cpp:63
bool gUIMacroSwitch
Definition: main.cpp:148
bool gDeepFirstSwitch
Definition: main.cpp:139
void sortGraph(Loop *root, lgraph &V)
Topological sort of an acyclic graph of loops.
static void groupSeqLoops(Loop *l)
Group together sequences of loops.
Definition: klass.cpp:301
string fKlassName
Definition: klass.hh:67
virtual void printComputeMethodScheduler(int n, ostream &fout)
Definition: klass.cpp:1052
Tree tree(const Node &n)
Definition: tree.hh:186
virtual void printLoopGraphScheduler(int n, ostream &fout)
Print the loop graph as a serie of parallel loops.
Definition: klass.cpp:499
virtual void printLoopGraphVector(int n, ostream &fout)
Print the loop graph (used for vector code)
Definition: klass.cpp:448
list< string > fStaticInitCode
static init code for class constant tables
Definition: klass.hh:80
virtual void printComputeMethodOpenMP(int n, ostream &fout)
Definition: klass.cpp:953
string fSuperKlassName
Definition: klass.hh:68
int gVecSize
Definition: main.cpp:140
property< Loop * > fLoopProperty
loops used to compute some signals
Definition: klass.hh:103
int fOrder
used during topological sort
Definition: loop.hh:65
bool gVectorSwitch
Definition: main.cpp:138
Tree symlist(Tree sig)
list< Klass * > fSubClassList
Definition: klass.hh:77
virtual void printLastLoopLevelScheduler(int n, int lnum, const lset &L, ostream &fout)
Print the 'level' of the loop graph as a set of parallel loops.
Definition: klass.cpp:628
virtual void printLibrary(ostream &fout)
Print the required C++ libraries as comments in source code.
Definition: klass.cpp:182
set< string > fIncludeFileSet
Definition: klass.hh:74
Definition: loop.hh:52
list< string > fUICode
Definition: klass.hh:83
Tree tl(Tree l)
Definition: list.hh:134
void addZone3(const string &str)
Definition: klass.hh:172
virtual void printLoopLevelScheduler(int n, int lnum, const lset &L, ostream &fout)
Print the 'level' of the loop graph as a set of parallel loops.
Definition: klass.cpp:721
virtual void printLoopGraphScalar(int n, ostream &fout)
Print the loop graph (scalar mode)
Definition: klass.cpp:568
list< string > fZone1Code
shared vectors
Definition: klass.hh:96
const char * ifloat()
Definition: floats.cpp:46
int fIndex
used during scheduler mode code generation
Definition: loop.hh:66
set< Loop * > fBackwardLoopDependencies
Loops that must be computed before this one.
Definition: loop.hh:59
bool gGroupTaskSwitch
Definition: main.cpp:146
void addDeclCode(const string &str)
Definition: klass.hh:149
bool gOpenMPSwitch
Definition: main.cpp:143
virtual void printMetadata(int n, const map< Tree, set< Tree > > &S, ostream &fout)
Print metadata declaration.
Definition: klass.cpp:238