dol: initial dol commit
[jump.git] / dol / src / dol / visitor / cbe / CbeProcessVisitor.java
1 /* $Id: CbeProcessVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
2 package dol.visitor.cbe;
3
4 import java.io.File;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.OutputStream;
8 import java.io.PrintStream;
9 import java.util.HashMap;
10 import java.util.Vector;
11
12 import dol.datamodel.pn.Port;
13 import dol.datamodel.pn.Process;
14 import dol.datamodel.pn.ProcessNetwork;
15 import dol.datamodel.pn.SourceCode;
16 import dol.util.CodePrintStream;
17 import dol.util.Copier;
18 import dol.util.Sed;
19 import dol.visitor.PNVisitor;
20
21 /**
22  * This class is a class for a visitor that is used to generate the main
23  * makefile for the application.
24  *
25  * @author lschor, 2008-10-30
26  *
27  * Revision:
28  * 2008-10-30: Updated the file for the CBE
29  * 2008-11-08: Add double buffering
30  */
31 public class CbeProcessVisitor extends PNVisitor {
32
33     /**
34      * Constructor.
35      *
36      * @param dir target directory
37      */
38     public CbeProcessVisitor(String dir, HashMap<Port, Integer> portMap) {
39         _dir = dir;
40         _portMap = portMap;
41     }
42
43     /**
44      *
45      * @param x process network that needs to be processed
46      */
47     public void visitComponent(ProcessNetwork x) {
48         try {
49             Vector<String> pList = new Vector<String>();
50
51             for (Process p : x.getProcessList()) {
52                 String basename = p.getBasename();
53                 if (!pList.contains(basename)) {
54                     pList.add(basename);
55                     p.accept(this);
56                 }
57             }
58         } catch (Exception e) {
59             System.out.println("CbeProcessVisitor: exception "
60                     + "occured: " + e.getMessage());
61             e.printStackTrace();
62         }
63     }
64
65     /**
66      * Visit process.
67      *
68      * @param p process that needs to be processed
69      */
70     public void visitComponent(Process p)
71     {
72         // Differ if the process is a source/sink or a normal process
73         // - Source/Sink: Mapped to the PPE
74         // - Normal process: Mapped to the SPE
75
76         if (p.getNumOfInports() > 0 && p.getNumOfOutports() > 0)
77         {
78             createSPEWrapper(p);
79         }
80         else
81         {
82             createPPEWrapper(p);
83         }
84     }
85
86     /**
87      * Creates a Wrapper for an SPE process
88      *
89      * @param p process that needs to be processed
90      */
91     protected void createSPEWrapper(Process p)
92     {
93         try {
94
95             // Create of each process an own folder
96             // add to this folder the source, the wrapper and a makefile
97             String processDir = _dir + _delimiter + "spu_"
98                     + p.getBasename();
99             File dir = new File(processDir);
100             dir.mkdirs();
101
102             // Create the filename for the new wrapper
103             String filename = processDir + _delimiter + "spu_"
104                     + p.getBasename() + "_wrapper.c";
105             File process_file = new File(filename);
106             File pattern_file = new File(_dir + _delimiter + _tempDirName
107                     + _delimiter + "spu_process_wrapper_template.c");
108             new Copier().copyFile(pattern_file, process_file);
109
110             String includes = "";
111             for (SourceCode code : p.getSrcList()) {
112                 includes += "#include \"" + code.getLocality() + "\""
113                         + System.getProperty("line.separator");
114             }
115
116             Sed sed = new Sed();
117             // Replace the include of the main c-file
118             sed.sed(filename, "//#include \"@PROCESSNAME@.c\"", includes);
119             // Replace the process-name in the whole file
120             sed.sed(filename, "@PROCESSNAME@", p.getBasename());
121
122             // Go through all source files
123             for (SourceCode sourceCode : p.getSrcList()) {
124                 // Copy the files to the new folder
125                 String oldFilename = _dir
126                         + _delimiter
127                         + sourceCode.getLocality().replaceAll(
128                                 "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
129                 filename = processDir
130                         + _delimiter
131                         + sourceCode.getLocality().replaceAll(
132                                 "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
133
134                 if (new File(filename).exists()) {
135                     new File(filename).delete();
136                 }
137
138                 new File(oldFilename).renameTo(new File(filename));
139
140                 // Copy also the c-files
141                 if ((oldFilename.substring(oldFilename.length() - 2))
142                         .equals(".h")) {
143                     String newFileNameC = filename.substring(0, filename
144                             .length() - 2) + ".c";
145                     if (new File(newFileNameC).exists()) {
146                         new File(newFileNameC).delete();
147                     }
148                     new File(oldFilename.substring(
149                             0, oldFilename.length() - 2)
150                             + ".c").renameTo(new File(newFileNameC));
151                 }
152
153                 // Update the files for the DOL project
154                 sed.sed(filename, "<dol.h>", "\"dol.h\"");
155
156                 // Create the port list
157                 for (Port port : p.getPortList()) {
158                     Integer portId = _portMap.get(port);
159                     if (!port.getBasename().equals(port.getName())) {
160                         for (Port port2 : p.getPortList()) {
161                             if (port2.getBasename().equals(
162                                     port.getBasename())) {
163                                 if (_portMap.get(port2) <
164                                         _portMap.get(port)) {
165                                     portId = _portMap.get(port2);
166                                 }
167                             }
168                         }
169                     }
170
171                     // Update the port list with the base names
172                     sed.sed(filename, "(#define[ ]+PORT_\\w*[ ]+)\"?"
173                             + port.getBasename() + "\"?", "$1 " + portId);
174                 }
175
176                 // Create the makefile for the process
177                 createMakefile(p);
178             }
179         } catch (Exception e) {
180             System.out.println("CbeProcessVisitor: exception "
181                     + "occured: " + e.getMessage());
182             e.printStackTrace();
183         }
184     }
185
186     /**
187      * Creates a Wrapper for an SPE process
188      *
189      * @param p process that needs to be processed
190      */
191     protected void createPPEWrapper(Process p)
192     {
193         try {
194             // Create of each process an own folder
195             // add to this folder the source, the wrapper and a makefile
196             String processDir = _dir + _delimiter + "ppu_"
197                     + p.getBasename();
198             File dir = new File(processDir);
199             dir.mkdirs();
200
201             // Create the filename for the new wrapper
202             String filename = processDir + _delimiter + "ppu_"
203                     + p.getBasename() + "_wrapper.c";
204             File process_file = new File(filename);
205             File pattern_file = new File(_dir + _delimiter + _tempDirName
206                     + _delimiter + "ppu_process_wrapper_template.c");
207             new Copier().copyFile(pattern_file, process_file);
208
209             String includes = "";
210             for (SourceCode code : p.getSrcList()) {
211                 includes += "#include \"" + code.getLocality() + "\""
212                         + System.getProperty("line.separator");
213             }
214
215             Sed sed = new Sed();
216             // Replace the include of the main c-file
217             sed.sed(filename, "//#include \"@PROCESSNAME@.c\"", includes);
218             // Replace the process-name in the whole file
219             sed.sed(filename, "@PROCESSNAME@", p.getBasename());
220
221             // Go through all source files
222             for (SourceCode sourceCode : p.getSrcList()) {
223                 // Copy the files to the new folder
224                 String oldFilename = _dir
225                         + _delimiter
226                         + sourceCode.getLocality().replaceAll(
227                                 "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
228                 filename = processDir
229                         + _delimiter
230                         + sourceCode.getLocality().replaceAll(
231                                 "(.*)\\.[cC][pP]*[pP]*", "$1\\.h");
232
233                 if (new File(filename).exists()) {
234                     new File(filename).delete();
235                 }
236
237                 new File(oldFilename).renameTo(new File(filename));
238
239                 // Copy also the c-files
240                 if ((oldFilename.substring(oldFilename.length() - 2))
241                         .equals(".h")) {
242                     String newFileNameC = filename.substring(0, filename
243                             .length() - 2)
244                             + ".c";
245                     if (new File(newFileNameC).exists()) {
246                         new File(newFileNameC).delete();
247                     }
248                     new File(oldFilename.substring(
249                             0, oldFilename.length() - 2)
250                             + ".c").renameTo(new File(newFileNameC));
251                 }
252
253                 // Update the files for the DOL project
254                 sed.sed(filename, "<dol.h>", "\"dol.h\"");
255
256                 // Create the port list
257                 for (Port port : p.getPortList()) {
258                     Integer portId = _portMap.get(port);
259                     if (!port.getBasename().equals(port.getName())) {
260                         for (Port port2 : p.getPortList()) {
261                             if (port2.getBasename().equals(
262                                     port.getBasename())) {
263                                 if (_portMap.get(port2) <
264                                         _portMap.get(port)) {
265                                     portId = _portMap.get(port2);
266                                 }
267                             }
268                         }
269                     }
270
271                     // Update the port list with the base names
272                     sed.sed(filename, "(#define[ ]+PORT_\\w*[ ]+)\"?"
273                             + port.getBasename() + "\"?", "$1 " + portId);
274                 }
275
276             }
277         } catch (Exception e) {
278             System.out.println("CbeProcessVisitor: exception "
279                     + "occured: " + e.getMessage());
280             e.printStackTrace();
281         }
282     }
283
284     /**
285      * Create the makefile for a special process -> Each subprocess
286      * gets its own makefile
287      *
288      * @param p process for which the makefile should be created
289      */
290     protected void createMakefile(Process p) {
291         try {
292             // Directory of the process
293             String processDir = _dir + _delimiter + "spu_"
294                     + p.getBasename();
295
296             // Create the filename for the new wrapper
297             String filename = processDir + _delimiter + "Makefile";
298             // File makefile = new File(filename);
299
300             OutputStream file;
301
302             file = new FileOutputStream(filename);
303
304             PrintStream _makefilePS = new CodePrintStream(file);
305
306             _makefilePS.println("# Makefile for process " + p.getName());
307             _makefilePS.println("");
308
309             String dependency = "all: spu_" + p.getBasename()
310                     + "_wrapper.c ../lib/ProcessWrapper.h "
311                     + "../lib/ProcessFifo.h";
312
313             for (SourceCode code: p.getSrcList())
314             {
315                 dependency += " " + code.getLocality();
316             }
317
318             _makefilePS.println(dependency);
319             _makefilePS.println("\t spu-g++ -I .. -I ../lib -g -o spu_"
320                     + p.getBasename() + "_wrapper spu_" + p.getBasename()
321                     + "_wrapper.c -ftree-vectorize -lm -mtune=cell -O3 "
322                     + "-fmodulo-sched -funroll-loops -ffast-math");
323             _makefilePS.println("clean: ");
324             _makefilePS.println("\t rm spu_" + p.getBasename()
325                     + "_wrapper");
326             _makefilePS.println();
327
328         } catch (FileNotFoundException e) {
329             System.out.println("CbeProcessVisitor - Makefile: exception "
330                     + "occured: " + e.getMessage());
331             e.printStackTrace();
332         }
333     }
334
335     protected String _dir = null;
336     protected HashMap<Port, Integer> _portMap;
337
338     protected static String _libDirName = "lib";
339     protected static String _tempDirName = "template";
340 }