75647964c665498c14c085def7ec43f4e0ae7ded
[jump.git] / dol / src / dol / visitor / epiphany / EpiphanyVisitor.java
1 package dol.visitor.Epiphany;
2
3 import java.util.Vector;
4
5 /* file management */
6 import java.io.File;
7 import java.io.FileNotFoundException;
8 import java.io.IOException;
9 import java.util.jar.JarFile;
10 import dol.util.JarCopier;
11 import dol.util.Copier;
12 import dol.util.Sed;
13
14 /* DOL elements */
15 import dol.visitor.PNVisitor;
16 import dol.datamodel.pn.Resource;
17 import dol.datamodel.pn.ProcessNetwork;
18 import dol.datamodel.pn.Process;
19 import dol.datamodel.pn.Channel;
20 import dol.datamodel.pn.Connection;
21 import dol.datamodel.pn.Port;
22
23 public class EpiphanyVisitor extends PNVisitor {
24         private String _epiphanyHostName = "EpiphanyHost";
25         private String _packageName;
26         private Vector<EpiphanyBuffer> _buffers = new Vector<EpiphanyBuffer>();
27         private Integer _numShmBufs = 0;
28
29         /* Constructor */
30         public EpiphanyVisitor(String packageName) {
31                 _packageName = packageName + _delimiter + "src";
32         }
33
34         /* ProcessNetwork Visitor */
35         public void visitComponent(ProcessNetwork pn) {
36                 try {
37                         /* create list of buffers */
38                         createBuffers(pn);
39
40                         /* copy static files */
41                         copyStaticFiles();
42
43                         /* create process wrappers
44                            TODO: fix _epiphanyHostName ?? */
45                         for (Process p : pn.getProcessList()) {
46                                 if(!_epiphanyHostName.equals(p.getBasename()))
47                                         createProcessWrapper(p);
48                         }
49
50                         /* create and copy shared header */
51                         createSharedHeader();
52
53                         /* create and copy host main application */
54                         createHostApplication(pn);
55
56                         /* create and copy Makefile */
57                         createMakefile(pn);
58
59                 } catch (Exception e) {
60                         System.out.println("Exception: " + e.getMessage());
61                         e.printStackTrace();
62                 }
63         }
64
65         /* Search for all structures of type
66            "Process-Port-Connection-Port-Channel-Port-Connection-Port-Process"
67            and save src/dst Process, src/dst Port and Channel */
68         private void createBuffers(ProcessNetwork pn)
69         {
70                 for(Connection c1 : pn.getConnectionList()) {
71                         for(Connection c2 : pn.getConnectionList()) {
72                                 if(c1 == c2) continue;
73
74                                 if(c1.getTarget() == c2.getOrigin() &&
75                                    "fifo".equals(c1.getTarget().getType()) &&
76                                    "fifo".equals(c2.getOrigin().getType())) {
77
78                                         Process src  = (Process)c1.getOrigin();
79                                         Port    srcP = c1.getOriginPort();
80                                         Process dst  = (Process)c2.getTarget();
81                                         Port    dstP = c2.getTargetPort();
82                                         Channel ch   = (Channel)c1.getTarget();
83
84                                         createBuffer(ch, src, srcP, dst, dstP);
85                                 }
86                         }
87                 }
88         }
89
90         /* create a buffer assignment structure */
91         private void createBuffer(Channel ch,
92                 Process src, Port srcP,
93                 Process dst, Port dstP)
94         {
95 //              TODO: all buffers are SHM buffers for now
96 //              if(src.getBasename().equals(_epiphanyHostName) ||
97 //                 dst.getBasename().equals(_epiphanyHostName)) {
98                         /* this is an SHM buffer */
99                         System.out.println("\tBuffer: " +
100                                 src.getName() + ":" + srcP.getName() +
101                                 " ==> " +
102                                 dst.getName() + ":" + dstP.getName() +
103                                 " (size " + ch.getSize() + ")" +
104                                 " as SHM:" + _numShmBufs);
105
106                         EpiphanyBuffer buf = new EpiphanyBuffer();
107                         buf.type = "shm";
108                         buf.srcProcess = src; buf.srcPort = srcP;
109                         buf.dstProcess = dst; buf.dstPort = dstP;
110                         buf.shmIndex = _numShmBufs; buf.size = ch.getSize();
111                         _buffers.add(buf);
112                         _numShmBufs++;
113
114 //              } else {
115                         /* this is an C2C buffer */
116 //                      System.out.println("C2CBUF: " +
117 //                              src.getBasename() + ":" + srcP.getBasename() +
118 //                              " ==> " +
119 //                              dst.getBasename() + ":" + dstP.getBasename() +
120 //                              " (size " + ch.getSize() + ")");
121 //              }
122         }
123
124         /* return buffer structure for a given process:port combination */
125         private EpiphanyBuffer getBuffer(Process process, Port port)
126                 throws Exception
127         {
128                 for(EpiphanyBuffer buf : _buffers) {
129                         if(port == buf.srcPort ||
130                            port == buf.dstPort) {
131                                 return(buf);
132                         }
133                 }
134
135                 throw new Exception("No buffer for '" + port + "' found!");
136         }
137
138         /* Copy a file from the JAR-file to some destination.
139            Copier() supports JAR-sources for directories only,
140            although it has a copyFile method. */
141         private void copyFile(File src, File dst) throws IOException {
142                 if(src.toString().contains("dol.jar!"))
143         {
144                         String jarName = src.toString();
145                         jarName = jarName.substring(jarName.indexOf("file:") + 5, jarName.lastIndexOf("!"));
146                         String srcName = src.toString();
147                                srcName = srcName.substring(src.toString().lastIndexOf("!") + 2);
148                                srcName = srcName.replaceAll("\\\\", "/");
149                         JarFile jar = new JarFile(jarName);
150                         JarCopier copier = new JarCopier();
151                         copier.copyFile(jar, srcName, dst.toString());
152                 } else {
153                         throw new IOException("Source file must be in JAR file.");
154                 }
155         }
156
157         /* create directories, copy processes and library */
158         private void copyStaticFiles() throws IOException,FileNotFoundException
159         {
160                 System.out.print("\tcopyStaticFiles(): ");
161
162                 /* create folders */
163                 System.out.print("directories, ");
164                 File dir;
165                 dir = new File(_packageName);
166                 dir.mkdirs();
167                 dir = new File(_packageName + _delimiter + "esrc");
168                 dir.mkdirs();
169                 dir = new File(_packageName + _delimiter + "hsrc");
170                 dir.mkdirs();
171                 dir = new File(_packageName + _delimiter + "lib");
172                 dir.mkdirs();
173                 dir = new File(_packageName + _delimiter + "bin");
174                 dir.mkdirs();
175
176                 /* copy processes */
177                 System.out.print("processes, ");
178                 File src  = new File("src");
179                 File dest = new File(_packageName + _delimiter + "esrc");
180                 new Copier().copy(src, dest);
181
182                 /* copy library */
183                 System.out.print("lib, ");
184                 String libPath = _ui.getMySystemCLib();
185                        libPath = libPath.replaceAll("systemC", "epiphany");
186                 src  = new File(libPath);
187                 dest = new File(_packageName + _delimiter + "lib");
188                 new Copier().copy(src, dest);
189
190                 System.out.println("finished!");
191         }
192
193         /* create a process_Wrapper.c file */
194         private void createProcessWrapper(Process p) throws Exception
195         {
196                 System.out.println("\tcreateProcessWrapper(): " +
197                         p.getName());
198
199                 /* copy template file */
200                 String filename = _packageName + _delimiter + "esrc" +
201                                   _delimiter + p.getName() + "_Wrapper.c";
202                 String template = _ui.getMySystemCLib() + _delimiter +
203                                   "process_Wrapper.c";
204                        template = template.replaceAll("systemC", "epiphany");
205                        template = template.replaceAll("lib", "template");
206
207                 File fFilename = new File(filename);
208                 File fTemplate = new File(template);
209                 copyFile(fTemplate, fFilename);
210
211                 /* handle this process' iterators */
212                 String instance = "";
213                 Vector<Integer> indices = p.getIteratorIndices();
214                 switch(indices.size()) {
215                 case 0: instance =
216                                 "0,0,0,0"; break;
217                 case 1: instance =
218                                 indices.elementAt(0) +
219                                 ",0,0,0"; break;
220                 case 2: instance =
221                                 indices.elementAt(0) +
222                                 indices.elementAt(1) +
223                                 ",0,0"; break;
224                 case 3: instance =
225                                 indices.elementAt(0) +
226                                 "," + indices.elementAt(1) +
227                                 "," + indices.elementAt(2) +
228                                 ",0"; break;
229                 case 4: instance =
230                                 indices.elementAt(0) +
231                                 "," + indices.elementAt(1) +
232                                 "," + indices.elementAt(2) +
233                                 "," + indices.elementAt(3); break;
234                 default:
235                         throw new Exception("Unsupported iterator dimension");
236                 }
237
238
239                 /* handle this process' ports */
240                 Integer portNum       = 0;
241                 String  portMapping   = "";
242                 String  portFunctions = "";
243                 for (Port port : p.getPortList()) {
244                         EpiphanyBuffer buf = getBuffer(p, port);
245
246                         /* port mapping */
247                         portMapping += "\t{ \"" + port.getName() + "\", size_" + portNum + ", level_" + portNum + ", ";
248                         portMapping += port.isInPort() ? "read_" + portNum + ", " : "NULL, ";
249                         portMapping += port.isOutPort() ? "write_" + portNum + ", " : "NULL, ";
250                         portMapping += "},\n";
251
252                         /* port access functions  - TODO: c2c buffers */
253                         if("shm".equals(buf.type)) {
254                                 Integer bufNum = buf.shmIndex;
255
256                                 portFunctions += "int size_" + portNum + "(void) { return(size_shm(&shm.buf" + bufNum + ")); }\n";
257                                 portFunctions += "int level_" + portNum + "(void) { return(level_shm(&shm.buf" + bufNum + ")); }\n";
258                                 if(port.isInPort()) {
259                                         portFunctions += "int read_" + portNum + "(void *buf, int len) { return(read_shm(&shm.buf" + bufNum + ", buf, len)); }\n";
260                                 }
261
262                                 if(port.isOutPort()) {
263                                         portFunctions += "int write_" + portNum + "(void *buf, int len) { return(write_shm(&shm.buf" + bufNum + ", buf, len)); }\n";
264                                 }
265                         } else {
266                                 throw new Exception("unknown port type");
267                         }
268
269                         portNum++;
270                 }
271
272                 /* replace information */
273                 Sed sed = new Sed();
274                 sed.sed(filename, "@@PROCESSNAME@@",   p.getBasename());
275                 sed.sed(filename, "@@INSTANCE@@",      instance);
276                 sed.sed(filename, "@@NUM_PORTS@@",     portNum.toString());
277                 sed.sed(filename, "@@PORTMAPPING@@",   portMapping);
278                 sed.sed(filename, "@@PORTFUNCTIONS@@", portFunctions);
279         }
280
281         /* create the shared.h header file */
282         private void createSharedHeader() throws Exception
283         {
284                 System.out.print("\tcreateSharedHeader(): ");
285
286                 /* copy template file */
287                 String filename = _packageName + _delimiter + "shared.h";
288                 String template = _ui.getMySystemCLib() + _delimiter +
289                                   "shared.h";
290                        template = template.replaceAll("systemC", "epiphany");
291                        template = template.replaceAll("lib", "template");
292                 File fFilename = new File(filename);
293                 File fTemplate = new File(template);
294                 copyFile(fTemplate, fFilename);
295
296                 /* generate replacement strings */
297                 String shmBufTypes = "";
298                 String shmBufs = "";
299                 for(EpiphanyBuffer buf : _buffers) {
300                         if("shm".equals(buf.type)) {
301                                 shmBufTypes +=
302                                 "\ntypedef struct {\n" +
303                                 "\tuint32_t rp;\n" +
304                                 "\tuint32_t wp;\n" +
305                                 "\tuint32_t size;\n" +
306                                 "\tchar     buf[" + buf.size + "];\n" +
307                                 "} PACKED buf" + buf.shmIndex + "_t;\n";
308
309                                 shmBufs +=
310                                 "\tbuf" + buf.shmIndex + "_t" +
311                                 "\tbuf" + buf.shmIndex + ";\n";
312                         }
313                 }
314
315                 /* do the replace */
316                 Sed sed = new Sed();
317                 sed.sed(filename, "@@SHM_BUF_STRUCTS@@", shmBufTypes);
318                 sed.sed(filename, "@@SHM_BUFS@@",        shmBufs);
319                 System.out.println("done!");
320         }
321
322         /* create the host application */
323         private void createHostApplication(ProcessNetwork pn) throws Exception
324         {
325                 System.out.print("\tcreateHostApplication(): ");
326
327                 /* copy template file */
328                 String filename = _packageName + _delimiter + "hsrc/main.c";
329                 String template = _ui.getMySystemCLib() + _delimiter +
330                                   "main.c";
331                        template = template.replaceAll("systemC", "epiphany");
332                        template = template.replaceAll("lib", "template");
333                 File fFilename = new File(filename);
334                 File fTemplate = new File(template);
335                 copyFile(fTemplate, fFilename);
336
337                 /* generate srec filenames */
338                 String srecFiles = "";
339                 Integer srecNum = 0;
340                 for(Process p : pn.getProcessList()) {
341                         /* TODO: fix _epiphanyHostName */
342                         if(!_epiphanyHostName.equals(p.getBasename())) {
343                                 srecFiles += "\t\"bin/" + p.getBasename() + ".srec\",\n";
344                                 srecNum++;
345                         }
346                 }
347
348                 /* generate shm buffer initialization code sequence */
349                 String shmBufInit = "";
350                 for(EpiphanyBuffer buf : _buffers) {
351                         if("shm".equals(buf.type)) {
352                                 String tmp = "\tshm.buf" + buf.shmIndex;
353
354                                 shmBufInit +=
355                                         tmp + ".size = " + buf.size + ";\n" +
356                                         tmp + ".rp   = 0;\n" +
357                                         tmp + ".wp   = 0;\n";
358                         }
359                 }
360
361                 /* do the replace */
362                 Sed sed = new Sed();
363                 sed.sed(filename, "@@SREC_FILES@@",   srecFiles);
364                 sed.sed(filename, "@@SREC_NUM@@",     srecNum.toString());
365                 sed.sed(filename, "@@SHM_BUF_INIT@@", shmBufInit);
366                 System.out.println("done!");
367         }
368
369         /* create Makefile */
370         private void createMakefile(ProcessNetwork pn) throws Exception
371         {
372                 System.out.print("\tcreateMakefile(): ");
373
374                 /* copy template file */
375                 String filename = _packageName + _delimiter + "Makefile";
376                 String template = _ui.getMySystemCLib() + _delimiter +
377                                   "Makefile";
378                        template = template.replaceAll("systemC", "epiphany");
379                        template = template.replaceAll("lib", "template");
380                 File fFilename = new File(filename);
381                 File fTemplate = new File(template);
382                 copyFile(fTemplate, fFilename);
383
384                 /* generate srec filenames */
385                 String srecFiles = "";
386                 for(Process p : pn.getProcessList()) {
387                         /* TODO: fix _epiphanyHostName */
388                         if(!_epiphanyHostName.equals(p.getBasename())) {
389                                 srecFiles += "\\$(DEST)/" +
390                                         p.getName() + ".srec ";
391                         }
392                 }
393
394                 /* generate .elf rules, because wrapper file names are
395                    non-obvious with iterated processes... */
396                 String elfRules = "";
397                 for(Process p : pn.getProcessList()) {
398                         elfRules +=
399                                 "\\$(EDEST)/" + p.getName() + ".elf: " +
400                                 "\\$(EDEST)/" + p.getBasename() + ".o " +
401                                 "\\$(EDEST)/" + p.getName() + "_Wrapper.o " +
402                                 "\\$(ECOMMON)\n";
403                         elfRules +=
404                                 "\t@\\$(ECHO) \"\\\\t(EPIPHANY) LINK\\\\t\\\\t\\$@\"\n" +
405                                 "\t@\\$(CC) -o \\$@ \\$^ \\$(LFLAGS)\n\n";
406                 }
407
408                 /* do the replace */
409                 Sed sed = new Sed();
410                 sed.sed(filename, "@@SREC_FILES@@", srecFiles);
411                 sed.sed(filename, "@@ELF_RULES@@",  elfRules);
412                 System.out.println("done!");
413         }
414 }