SDAG: ensure that necessary data structure is initialized
[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   for(list<CEntry*>::iterator en=entryList.begin(); en != entryList.end(); ++en) {
79     container->lookforCEntry(*en);
80   }
81 }
82
83 void CParsedFile::generateEntryList(void)
84 {
85   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
86     (*cn)->sdagCon->generateEntryList(entryList, NULL);
87   }
88 }
89
90 void CParsedFile::generateConnectEntryList(void)
91 {
92   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
93     (*cn)->sdagCon->generateConnectEntryList(connectEntryList);
94   }
95 }
96
97 void CParsedFile::generateCode(XStr& decls, XStr& defs)
98 {
99   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
100     (*cn)->sdagCon->setNext(0, 0);
101     (*cn)->sdagCon->generateCode(decls, defs, *cn);
102   }
103 }
104
105 void CParsedFile::generateEntries(XStr& decls, XStr& defs)
106 {
107   decls << "public:\n";
108   for(list<SdagConstruct *>::iterator sc=connectEntryList.begin(); sc != connectEntryList.end(); ++sc)
109     (*sc)->generateConnectEntries(decls);
110   for(list<CEntry*>::iterator en = entryList.begin(); en != entryList.end(); ++en) {
111     (*en)->generateCode(decls, defs);
112   }
113 }
114
115 void CParsedFile::generateInitFunction(XStr& decls, XStr& defs)
116 {
117   decls << "public:\n";
118   decls << "  std::auto_ptr<CDep> __cDep;\n";
119
120   XStr name = "_sdag_init";
121   generateSignature(decls, defs, container, false, "void", &name, false, NULL);
122   defs << "    __cDep.reset(new CDep(" << numEntries << "," << numWhens << "));\n";
123   CEntry *en;
124   for(list<CEntry*>::iterator en=entryList.begin(); en != entryList.end(); ++en) {
125     (*en)->generateDeps(defs);
126   }
127   endMethod(defs);
128
129   // Backwards compatibility
130   XStr oldname = "__sdag_init";
131   generateSignature(decls, defs, container, false, "void", &oldname, false, NULL);
132   endMethod(defs);
133 }
134
135
136 /**
137     Create a merging point for each of the places where multiple
138     dependencies lead into some future task.
139
140     Used by Isaac's critical path detection
141 */
142 void CParsedFile::generateDependencyMergePoints(XStr& decls)
143 {
144   decls << " \n";
145
146   // Each when statement will have a set of message dependencies, and
147   // also the dependencies from completion of previous task
148   for(int i=0;i<numWhens;i++){
149     decls << "  MergeablePathHistory _when_" << i << "_PathMergePoint; /* For Critical Path Detection */ \n";
150   }
151
152   // The end of each overlap block will have multiple paths that merge
153   // before the subsequent task is executed
154   for(int i=0;i<numOlists;i++){
155     decls << "  MergeablePathHistory olist__co" << i << "_PathMergePoint; /* For Critical Path Detection */ \n";
156   }
157 }
158
159 void CParsedFile::generatePupFunction(XStr& decls)
160 {
161   decls << "public:\n";
162   decls << "  void __sdag_pup(PUP::er& p) {\n";
163   decls << "    if (__cDep.get()) { __cDep->pup(p); }\n";
164   decls << "  }\n";
165 }
166
167 void CParsedFile::generateRegisterEp(XStr& decls, XStr& defs)
168 {
169   XStr name = "__sdag_register";
170   generateSignature(decls, defs, container, true, "void", &name, false, NULL);
171
172   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
173     if ((*cn)->sdagCon != 0) {
174       (*cn)->sdagCon->generateRegisterEp(defs);
175     }
176   }
177   endMethod(defs);
178 }
179
180 void CParsedFile::generateTraceEp(XStr& decls, XStr& defs)
181 {
182   for(std::list<Entry*>::iterator cn = nodeList.begin(); cn != nodeList.end(); ++cn) {
183     if ((*cn)->sdagCon != 0) {
184       (*cn)->sdagCon->generateTraceEp(decls, defs, container);
185     }
186   }
187 }
188
189 }