1 /* $Id: CbeModuleVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
2 package dol.visitor.cbe;
4 import java.io.FileOutputStream;
5 import java.io.OutputStream;
6 import java.util.HashMap;
7 import java.util.Vector;
9 import dol.datamodel.pn.Channel;
10 import dol.datamodel.pn.Port;
11 import dol.datamodel.pn.Process;
12 import dol.datamodel.pn.ProcessNetwork;
13 import dol.main.UserInterface;
14 import dol.util.CodePrintStream;
15 import dol.visitor.PNVisitor;
18 * This class is a class for a visitor that is used to generate
21 * @author lschor, 2008-10-30
24 * 2008-10-30: Updated the file for the CBE
25 * 2008-11-08: Add double buffering
26 * 2008-11-16: Add new fifo implementation and defines for measurement
27 * 2008-11-21: Sink/Source do not run on the SPE, but on the PPE (as Linux
30 public class CbeModuleVisitor extends PNVisitor {
35 * @param dir path of this file
37 public CbeModuleVisitor(String dir, HashMap<Port, Integer> portMap) {
43 * Visit process network.
45 * @param x process network that needs to be rendered
47 public void visitComponent(ProcessNetwork x) {
49 _ui = UserInterface.getInstance();
50 String filename = _dir + _delimiter + "ppu_main.c";
51 OutputStream file = new FileOutputStream(filename);
52 _mainPS = new CodePrintStream(file);
54 //create header section
55 _mainPS.println("// ========================");
56 _mainPS.println("// ppu_main.c file");
57 _mainPS.println("// ========================");
61 _mainPS.println("#include \"ppu_main.h\"");
65 _mainPS.println("// include main function for a workloop");
66 _mainPS.println("#include \"ppu_main_workloop.h\"");
69 // Function to create and run one SPE thread
70 _mainPS.println("// create and run one SPE thread");
71 _mainPS.println("void *spu_pthread(void *arg) {");
72 _mainPS.println("\t spu_data_t *datp = (spu_data_t *)arg;");
73 _mainPS.println("\t uint32_t entry = SPE_DEFAULT_ENTRY;");
74 _mainPS.println("\t printf(\")PPE: spe thread starts\\n\");");
75 _mainPS.println("\t if (spe_context_run(datp->spe_ctx, "
76 + "&entry, 0, datp->argp, NULL, NULL) < 0) {");
77 _mainPS.println("\t\t perror (\"Failed running context\"); "
79 _mainPS.println("\t}");
80 _mainPS.println("\t printf(\")PPE: spe thread stops\\n\");");
81 _mainPS.println("\t pthread_exit(NULL);");
85 // Declaration of the Header function for the PPE-Wrappers
86 Vector<String> processList = new Vector<String>();
87 for (Process p : x.getProcessList()) {
88 String basename = p.getBasename();
89 if (!processList.contains(basename)) {
90 processList.add(basename);
91 if (!(p.getNumOfInports() > 0
92 && p.getNumOfOutports() > 0))
93 _mainPS.println("void *" + basename
94 + "_wrapper( void *ptr );");
99 // Create the port_id and the port_queue_id arrays to send
101 for (Process process : x.getProcessList()) {
102 String processName = process.getName();
103 _mainPS.println("volatile uint32_t "+ processName
105 + roundDMA(process.getPortList().size())
106 + "] __attribute__ ((aligned(16))); ");
107 _mainPS.println("volatile uint32_t " + processName
109 + roundDMA(process.getPortList().size())
110 + "] __attribute__ ((aligned(16)));");
111 _mainPS.println("volatile char " + processName
112 + "_name[256] __attribute__ ((aligned(16)));");
116 // Create the main function
117 _mainPS.println("int main()");
118 _mainPS.println("{");
121 _mainPS.println("#ifdef MEASURE_APPLICATION");
122 _mainPS.println("\tstruct timeval t_ppe_start, t_ppe_end;");
123 _mainPS.println("\tgettimeofday(&t_ppe_start,NULL);");
124 _mainPS.println("#endif");
127 _mainPS.println("#ifdef MEASURE_SET_UP_SPE_THREAD");
128 _mainPS.println("\tstruct timeval t_ppe_setup_start, "
129 + "t_ppe_setup_end;");
130 _mainPS.println("\tgettimeofday(&t_ppe_setup_start,NULL);");
131 _mainPS.println("#endif");
134 // List with all process to be open
135 _mainPS.println("\tchar spe_names[NUM_SPES][60] = {");
137 for (Process process : x.getProcessList()) {
138 if (process.getNumOfInports() > 0
139 && process.getNumOfOutports() > 0) {
141 String processName = process.getBasename();
142 _mainPS.println("\t\t\"spu_" + processName + "/spu_"
143 + processName + "_wrapper\""
144 + (count == x.getProcessList().size()
148 _mainPS.println("\t};");
150 _mainPS.println("\t// Initialize the fifo, we use");
151 _mainPS.println("\tint j; ");
152 _mainPS.println("\tfor (j = 0; j < NUM_FIFO; j++)");
153 _mainPS.println("\t{");
154 _mainPS.println("\t\tlocBuf[j] = "
155 + "(char*)malloc(MAXELEMENT * sizeof(char));");
156 _mainPS.println("\t\tlocBufCount[j] = 0;");
157 _mainPS.println("\t\tlocBufStart[j] = 0;");
158 _mainPS.println("\t\tpthread_mutex_init(&(mutex[j]), NULL);");
159 _mainPS.println("\t}");
161 //connect ports to channels
162 HashMap<Channel, Integer> channel_map =
163 new HashMap<Channel, Integer>();
166 for (Channel c : x.getChannelList()) {
167 channel_map.put(c, j++);
170 // Init the SPE control structure
171 _mainPS.println("\t//Initiate SPEs control structure");
172 _mainPS.println("\tint num = 0; ");
173 _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
174 _mainPS.println("\t\tdata[num].argp = (void *)&(ctx[num]);");
175 _mainPS.println("\t}");
178 // Add to each process the ports and the queues
179 _mainPS.println("\t //Add to each process the ports and the "
182 for (Process process : x.getProcessList()) {
183 String processName = process.getName();
185 for (Port port : process.getPortList()) {
186 Channel c = (Channel)(port.getPeerResource());
188 _mainPS.println("\t" + processName + "_port_id["
190 + _portMap.get(port) + ";");
191 _mainPS.println("\t" + processName + "_port_queue_id["
193 + channel_map.get(c) + ";");
198 if (process.getNumOfInports() > 0
199 && process.getNumOfOutports() > 0) {
200 _mainPS.println("\tctx[" + j + "]"
201 + ".port_id = (uint64_t)"
202 + processName + "_port_id;");
203 _mainPS.println("\tctx[" + j + "]"
204 + ".port_queue_id = (uint64_t)"
205 + processName + "_port_queue_id;");
206 _mainPS.println("\tctx[" + j + "]"
207 + ".number_of_ports = " + i + ";");
208 _mainPS.println("\tctx[" + j + "]"
209 + ".is_detached = 0;");
210 _mainPS.println("\tstrcpy((char *)" + processName
212 + processName + "\");");
213 _mainPS.println("\tctx[" + j + "]"
214 + ".processName = (uint64_t) " + processName
216 _mainPS.println("\tctx[" + j + "]"
217 + ".processNameLen = ((strlen((char *)"
218 + processName + "_name) + 15) & ~15);");
222 // Process is Sink or source
224 _mainPS.println("\tProcessWrapper *"
226 + "_Process_Wrapper = (ProcessWrapper*)"
227 + "malloc(sizeof(ProcessWrapper)); ");
228 _mainPS.println("\t" + process.getName()
229 + "_Process_Wrapper->port_id = " + processName
231 _mainPS.println("\t" + process.getName()
232 + "_Process_Wrapper->port_queue_id = "
233 + processName + "_port_queue_id;");
234 _mainPS.println("\t" + process.getName()
235 + "_Process_Wrapper->number_of_ports = "
237 _mainPS.println("\t" + process.getName()
238 + "_Process_Wrapper->is_detached = 0;");
239 _mainPS.println("\t" + process.getName()
240 + "_Process_Wrapper->name = (char*)malloc("
241 + "strlen(\"" + processName + "\"));");
242 _mainPS.println("\tstrcpy(" + process.getName()
243 + "_Process_Wrapper->name, \"" + processName
245 _mainPS.println("\t" + process.getName()
246 + "_Process_Wrapper->locBuf = locBuf;");
247 _mainPS.println("\t" + process.getName()
248 + "_Process_Wrapper->MAXELEMENT = "
250 _mainPS.println("\t" + process.getName()
251 + "_Process_Wrapper->locBufCount = "
253 _mainPS.println("\t" + process.getName()
254 + "_Process_Wrapper->locBufStart = "
256 _mainPS.println("\t" + process.getName()
257 + "_Process_Wrapper->processFinished = "
258 + "&processFinished;");
259 _mainPS.println("\t" + process.getName()
260 + "_Process_Wrapper->mutex = mutex;");
261 _mainPS.println("\t" + process.getName()
262 + "_Process_Wrapper->mutexProcessNr = "
263 + "&mutexProcessNr;");
268 _mainPS.println("\t// Loop on all SPEs and for each perform "
270 _mainPS.println("\t// - create SPE context");
271 _mainPS.println("\t// - open images of SPE programs into main "
273 _mainPS.println("\t// <spe_names> variable store the "
274 + "executable name");
275 _mainPS.println("\t// - Load SPEs objects into SPE context "
277 _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
278 _mainPS.println("\t\tif ((data[num].spe_ctx = "
279 + "spe_context_create(0, NULL)) == NULL) {");
280 _mainPS.println("\t\t\tperror(\"Failed creating context\"); "
282 _mainPS.println("\t\t}");
283 _mainPS.println("\t\tif (!(program[num] = spe_image_open("
284 + "&spe_names[num][0]))) {");
285 _mainPS.println("\t\t\t perror(\"Fail opening image\"); "
287 _mainPS.println("\t\t}");
288 _mainPS.println("\t\tif (spe_program_load(data[num].spe_ctx, "
289 + "program[num])) {");
290 _mainPS.println("\t\t\tperror(\"Failed loading program\"); "
292 _mainPS.println("\t\t} ");
293 _mainPS.println("\t}");
296 _mainPS.println("\t// create PPE pthreads");
297 for (Process process : x.getProcessList()) {
298 if (!(process.getNumOfInports() > 0
299 && process.getNumOfOutports() > 0)) {
300 _mainPS.println("\tpthread_t thread_"
301 + process.getName() + ";");
302 _mainPS.println("\tpthread_create( &thread_"
303 + process.getName() + ", NULL, "
304 + process.getBasename() + "_wrapper, "
305 + process.getName() + "_Process_Wrapper);");
308 _mainPS.println("\t");
310 _mainPS.println("\t// create SPE pthreads");
311 _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
312 _mainPS.println("\t\tif(pthread_create(&data[num].pthread, "
313 + "NULL, &spu_pthread, &data[num])){");
314 _mainPS.println("\t\t\tperror(\"Failed creating thread\"); "
316 _mainPS.println("\t\t}");
317 _mainPS.println("\t}");
320 _mainPS.println("#ifdef MEASURE_SET_UP_SPE_THREAD");
321 _mainPS.println("\tgettimeofday(&t_ppe_setup_end, NULL);");
322 _mainPS.println("\tprintf(\"PPE_SETUP;%f\\n\", "
323 + "(t_ppe_setup_end.tv_sec "
324 + "- t_ppe_setup_start.tv_sec) + 0.000001 "
325 + "* (t_ppe_setup_end.tv_usec "
326 + "- t_ppe_setup_start.tv_usec));");
327 _mainPS.println("#endif");
330 _mainPS.println("\t//Start the main loop");
331 _mainPS.println("\tworkloop();");
334 _mainPS.println("\t// Loop on all SPEs and for each perform "
336 _mainPS.println("\t// - wait for all the SPE pthread to "
338 _mainPS.println("\t// - destroy the SPE contexts");
339 _mainPS.println("\tfor( num=0; num<NUM_SPES; num++){");
340 _mainPS.println("\t\tif(pthread_join(data[num].pthread, "
342 _mainPS.println("\t\t\tperror(\"Failed joining thread\"); "
344 _mainPS.println("\t\t}");
345 _mainPS.println("\t\t");
346 _mainPS.println("\t\tif (spe_context_destroy("
347 + "data[num].spe_ctx)) {");
348 _mainPS.println("\t\t\tperror(\"Failed "
349 + "spe_context_destroy\"); exit(1);");
350 _mainPS.println("\t\t}");
351 _mainPS.println("\t}");
352 _mainPS.println("\tprintf(\")PPE:) Complete running "
353 + "all SPEs\\n\");");
355 _mainPS.println("\tfor (j = 0; j < NUM_FIFO; j++)");
356 _mainPS.println("\t{");
357 _mainPS.println("\t\tfree(locBuf[j]);");
358 _mainPS.println("\t\tpthread_mutex_destroy (&(mutex[j]));");
359 _mainPS.println("\t}");
361 _mainPS.println("#ifdef MEASURE_APPLICATION");
362 _mainPS.println("\tgettimeofday(&t_ppe_end, NULL);");
363 _mainPS.println("\tprintf(\"PPE;%f\\n\",(t_ppe_end.tv_sec "
364 + "- t_ppe_start.tv_sec) + 0.000001 "
365 + "* (t_ppe_end.tv_usec - t_ppe_start.tv_usec));");
366 _mainPS.println("#endif");
368 _mainPS.println("\treturn (0);");
369 _mainPS.println("}");
371 catch (Exception e) {
372 System.out.println("CbeDBModuleVisitor: exception occured: "
380 * @param x process that needs to be processed
382 public void visitComponent(Process x) {
387 * @param x channel that needs to be processed
389 public void visitComponent(Channel x) {
393 * Round the parameter to the next DMA-number up.
394 * Example: 23 gives 32.
395 * @param number number to round up
396 * @return next DMA-number
398 protected int roundDMA(int number) {
400 return number + 16 - (number % 16);
401 } else if (number > 8) {
403 } else if (number > 4) {
405 } else if (number > 2) {
407 } else if (number > 1) {
414 protected CodePrintStream _mainPS = null;
415 protected String _dir = null;
416 protected HashMap<Port, Integer> _portMap;