20431c162581107e0962ccd687afea3fcb51d570
[charm.git] / src / xlat-i / sdag / CParsedFile.C
1 #include "CParsedFile.h"
2 #include <algorithm>
3
4 using std::for_each;
5 using std::list;
6
7 namespace xi {
8
9 /*void CParsedFile::print(int indent)
10 {
11   for(CEntry *ce=entryList.begin(); !entryList.end(); ce=entryList.next())
12   {
13     ce->print(indent);
14     printf("\n");
15   }
16   for(SdagConstruct *cn=nodeList.begin(); !nodeList.end(); cn=nodeList.next())
17   {
18     cn->print(indent);
19     printf("\n");
20   }
21 }
22 */
23 XStr *CParsedFile::className = NULL;
24
25   template <typename T>
26   struct SdagConCall {
27     void (SdagConstruct::*fn)(T);
28     T arg;
29
30     SdagConCall(void (SdagConstruct::*fn_)(T), const T& arg_) : fn(fn_), arg(arg_) { }
31     void operator()(Entry *e) {
32       if (e->sdagCon) {
33         (e->sdagCon->*fn)(arg);
34       }
35     }
36   };
37
38   template <>
39   struct SdagConCall<void> {
40     void (SdagConstruct::*fn)();
41     SdagConCall(void (SdagConstruct::*fn_)()) : fn(fn_) { }
42     void operator()(Entry *e) {
43       if (e->sdagCon) {
44         (e->sdagCon->*fn)();
45       }
46     }
47   };
48
49 void CParsedFile::doProcess(XStr& classname, XStr& decls, XStr& defs) {
50   className = &classname;
51   decls << "#define " << classname << "_SDAG_CODE \n";
52
53   for_each(nodeList.begin(), nodeList.end(), SdagConCall<void>(&SdagConstruct::numberNodes));
54   for_each(nodeList.begin(), nodeList.end(), SdagConCall<void>(&SdagConstruct::labelNodes));
55   for_each(nodeList.begin(), nodeList.end(), SdagConCall<int>(&SdagConstruct::propagateState, 0));
56   generateConnectEntryList();
57   for_each(nodeList.begin(), nodeList.end(), SdagConCall<void>(&SdagConstruct::generateTrace));
58   generateEntryList();
59   mapCEntry();
60
61   generateCode(decls, defs);
62   generateEntries(decls, defs);
63   generateInitFunction(decls, defs);
64   generatePupFunction(decls);
65   generateRegisterEp(decls, defs);
66   generateTraceEp(decls, defs);
67
68 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
69   generateDependencyMergePoints(decls); // for Isaac's Critical Path Detection
70 #endif
71
72   decls.line_append_padding('\\');
73   decls << "\n";
74 }
75
76 void CParsedFile::mapCEntry(void)
77 {
78   CEntry *en;
79   for(en=entryList.begin(); !entryList.end(); en=entryList.next()) {
80     container->lookforCEntry(en);
81   }
82 }
83
84 void CParsedFile::generateEntryList(void)
85 {
86   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
87     (*cn)->sdagCon->generateEntryList(entryList, (SdagConstruct*)0);
88   }
89 }
90
91 void CParsedFile::generateConnectEntryList(void)
92 {
93   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
94     (*cn)->sdagCon->generateConnectEntryList(connectEntryList);
95   }
96 }
97
98 void CParsedFile::generateCode(XStr& decls, XStr& defs)
99 {
100   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
101     (*cn)->sdagCon->setNext(0, 0);
102     (*cn)->sdagCon->generateCode(decls, defs, *cn);
103   }
104 }
105
106 void CParsedFile::generateEntries(XStr& decls, XStr& defs)
107 {
108   CEntry *en;
109   decls << "public:\n";
110   for(list<SdagConstruct *>::iterator sc=connectEntryList.begin(); sc != connectEntryList.end(); ++sc)
111     (*sc)->generateConnectEntries(decls);
112   for(en=entryList.begin(); !entryList.end(); en=entryList.next()) {
113     en->generateCode(decls, defs);
114   }
115 }
116
117 void CParsedFile::generateInitFunction(XStr& decls, XStr& defs)
118 {
119   decls << "public:\n";
120   decls << "  CDep *__cDep;\n";
121
122   XStr name = "_sdag_init";
123   generateSignature(decls, defs, container, false, "void", &name, false, NULL);
124   defs << "    __cDep = new CDep(" << numEntries << "," << numWhens << ");\n";
125   CEntry *en;
126   for(en=entryList.begin(); !entryList.end(); en=entryList.next()) {
127     en->generateDeps(defs);
128   }
129   endMethod(defs);
130
131   // Backwards compatibility
132   XStr oldname = "__sdag_init";
133   generateSignature(decls, defs, container, false, "void", &oldname, false, NULL);
134   endMethod(defs);
135 }
136
137
138 /**
139     Create a merging point for each of the places where multiple
140     dependencies lead into some future task.
141
142     Used by Isaac's critical path detection
143 */
144 void CParsedFile::generateDependencyMergePoints(XStr& decls)
145 {
146   decls << " \n";
147
148   // Each when statement will have a set of message dependencies, and
149   // also the dependencies from completion of previous task
150   for(int i=0;i<numWhens;i++){
151     decls << "  MergeablePathHistory _when_" << i << "_PathMergePoint; /* For Critical Path Detection */ \n";
152   }
153
154   // The end of each overlap block will have multiple paths that merge
155   // before the subsequent task is executed
156   for(int i=0;i<numOlists;i++){
157     decls << "  MergeablePathHistory olist__co" << i << "_PathMergePoint; /* For Critical Path Detection */ \n";
158   }
159 }
160
161 void CParsedFile::generatePupFunction(XStr& decls)
162 {
163   decls << "public:\n";
164   decls << "  void __sdag_pup(PUP::er& p) {\n";
165   decls << "    if (__cDep) { __cDep->pup(p); }\n";
166   decls << "  }\n";
167 }
168
169 void CParsedFile::generateRegisterEp(XStr& decls, XStr& defs)
170 {
171   XStr name = "__sdag_register";
172   generateSignature(decls, defs, container, true, "void", &name, false, NULL);
173
174   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
175     if ((*cn)->sdagCon != 0) {
176       (*cn)->sdagCon->generateRegisterEp(defs);
177     }
178   }
179   endMethod(defs);
180 }
181
182 void CParsedFile::generateTraceEp(XStr& decls, XStr& defs)
183 {
184   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
185     if ((*cn)->sdagCon != 0) {
186       (*cn)->sdagCon->generateTraceEp(decls, defs, container);
187     }
188   }
189 }
190
191 }