3df8d8900312242ccce9ea419d12aa63b8ae7992
[IRC.git] / Robust / src / Analysis / Scheduling / SchedulingUtil.java
1 package Analysis.Scheduling;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.PrintWriter;
6 import java.util.Collection;
7 import java.util.Enumeration;
8 import java.util.HashSet;
9 import java.util.Hashtable;
10 import java.util.Iterator;
11 import java.util.Set;
12 import java.util.Vector;
13 import java.util.Map.Entry;
14
15 import Analysis.Scheduling.ScheduleSimulator.Action;
16 import Analysis.Scheduling.ScheduleSimulator.CheckPoint;
17 import Analysis.TaskStateAnalysis.Allocations;
18 import Analysis.TaskStateAnalysis.FEdge;
19 import Analysis.TaskStateAnalysis.FlagState;
20 import Analysis.TaskStateAnalysis.FEdge.NewObjInfo;
21 import IR.ClassDescriptor;
22 import IR.Operation;
23 import IR.State;
24 import IR.Tree.FlagExpressionNode;
25 import IR.Tree.FlagNode;
26 import IR.Tree.FlagOpNode;
27 import Util.Edge;
28 import Util.GraphNode;
29 import Util.Namer;
30
31 public class SchedulingUtil {
32     
33     public static Vector<ScheduleNode> generateScheduleGraph(State state, 
34                                                              Vector<ScheduleNode> scheduleNodes,
35                                                              Vector<ScheduleEdge> scheduleEdges,
36                                                              Vector<Vector<ScheduleNode>> rootnodes, 
37                                                              Vector<Vector<CombinationUtil.Combine>> combine, 
38                                                              int gid) {
39         Vector<ScheduleNode> result = new Vector<ScheduleNode>();
40
41         // clone the ScheduleNodes
42         Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>> sn2hash = 
43             new Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>>();
44         Hashtable<ScheduleNode, ScheduleNode> sn2sn = 
45             new Hashtable<ScheduleNode, ScheduleNode>();
46         cloneScheduleGraph(scheduleNodes,
47                            scheduleEdges,
48                            sn2hash,
49                            sn2sn,
50                            result,
51                            gid);
52
53         // combine those nodes in combine with corresponding rootnodes
54         for(int i = 0; i < combine.size(); i++) {
55             if(combine.elementAt(i) != null) {
56                 for(int j = 0; j < combine.elementAt(i).size(); j++) {
57                     CombinationUtil.Combine tmpcombine = combine.elementAt(i).elementAt(j);
58                     ScheduleNode tocombine = sn2sn.get(tmpcombine.node);
59                     ScheduleNode root = sn2sn.get(rootnodes.elementAt(tmpcombine.root).elementAt(tmpcombine.index));
60                     ScheduleEdge se = (ScheduleEdge)tocombine.inedges().next();
61                     try {
62                         if(root.equals(((ScheduleNode)se.getSource()))) {
63                             root.mergeSEdge(se);
64                             if(ScheduleEdge.NEWEDGE == se.getType()) {
65                                 // As se has been changed into an internal edge inside a ScheduleNode,
66                                 // change the source and target of se from original ScheduleNodes into ClassNodes.
67                                 se.setTarget(se.getTargetCNode());
68                                 //se.setSource(se.getSourceCNode());
69                                 //se.getTargetCNode().addEdge(se);
70                                 se.getSourceCNode().addEdge(se);
71                             }
72                         } else {
73                             root.mergeSNode(tocombine);
74                         }
75                     } catch(Exception e) {
76                         e.printStackTrace();
77                         System.exit(-1);
78                     }
79                     result.removeElement(tocombine);
80                 }
81             }
82         }
83         
84         assignCids(result);
85         
86         sn2hash.clear();
87         sn2hash = null;
88         sn2sn.clear();
89         sn2sn = null;
90
91         if(state.PRINTSCHEDULING) {
92             String path = state.outputdir + "scheduling_" + gid + ".dot";
93             SchedulingUtil.printScheduleGraph(path, result);
94         }
95
96         return result;
97     }
98     
99     public static void cloneScheduleGraph(Vector<ScheduleNode> scheduleNodes,
100                                           Vector<ScheduleEdge> scheduleEdges,
101                                           Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>> sn2hash,
102                                           Hashtable<ScheduleNode, ScheduleNode> sn2sn,
103                                           Vector<ScheduleNode> result,
104                                           int gid) {
105         for(int i = 0; i < scheduleNodes.size(); i++) {
106             Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>();
107             ScheduleNode tocopy = scheduleNodes.elementAt(i);
108             ScheduleNode temp = (ScheduleNode)tocopy.clone(cn2cn, gid);
109             result.add(i, temp);
110             sn2hash.put(temp, cn2cn);
111             sn2sn.put(tocopy, temp);
112             cn2cn = null;
113         }
114         // clone the ScheduleEdges
115         for(int i = 0; i < scheduleEdges.size(); i++) {
116             ScheduleEdge sse = scheduleEdges.elementAt(i);
117             ScheduleNode csource = sn2sn.get(sse.getSource());
118             ScheduleNode ctarget = sn2sn.get(sse.getTarget());
119             Hashtable<ClassNode, ClassNode> sourcecn2cn = sn2hash.get(csource);
120             Hashtable<ClassNode, ClassNode> targetcn2cn = sn2hash.get(ctarget);
121             ScheduleEdge se =  null;
122             switch(sse.getType()) {
123             case ScheduleEdge.NEWEDGE: {
124                 se = new ScheduleEdge(ctarget, "new", sse.getFstate(), sse.getType(), gid);       //new ScheduleEdge(ctarget, "new", sse.getClassDescriptor(), sse.getIsNew(), gid);
125                 se.setProbability(sse.getProbability());
126                 se.setNewRate(sse.getNewRate());
127                 break;
128             }
129
130             case ScheduleEdge.TRANSEDGE: {
131                 se = new ScheduleEdge(ctarget, "transmit", sse.getFstate(), sse.getType(), gid);       //new ScheduleEdge(ctarget, "transmit", sse.getClassDescriptor(), false, gid);
132                 break;
133             }
134             }
135             se.setSourceCNode(sourcecn2cn.get(sse.getSourceCNode()));
136             se.setTargetCNode(targetcn2cn.get(sse.getTargetCNode()));
137             se.setFEdge(sse.getFEdge());
138             se.setTargetFState(sse.getTargetFState());
139             se.setIsclone(true);
140             csource.addEdge(se);
141             sourcecn2cn = null;
142             targetcn2cn = null;
143         }
144     }
145     
146     public static void assignCids(Vector<ScheduleNode> result) {
147         Hashtable<Integer, Integer> hcid2cid = new Hashtable<Integer, Integer>();
148         int ncid = 0;
149         for(int i = 0; i < result.size(); i++) {
150             ScheduleNode tmpnode = result.elementAt(i);
151             tmpnode.computeHashcid();
152             int hcid = tmpnode.getHashcid();
153             if(hcid2cid.containsKey(hcid)) {
154                 // already have a cid for this node
155                 tmpnode.setCid(hcid2cid.get(hcid));
156             } else {
157                 // generate a new cid for such node
158                 tmpnode.setCid(ncid);
159                 hcid2cid.put(hcid, ncid);
160                 ncid++;
161             }
162         }
163         hcid2cid.clear();
164         hcid2cid = null;
165     }
166     
167     //  Organize the scheduleNodes in order of their cid
168     public static Vector<Vector<ScheduleNode>> 
169     rangeScheduleNodes(Vector<ScheduleNode> scheduleNodes) {
170       try{  
171         Vector<Vector<ScheduleNode>> sNodeVecs = new Vector<Vector<ScheduleNode>>();
172
173         for(int i = 0; i < scheduleNodes.size(); i++) {
174           ScheduleNode tmpn = scheduleNodes.elementAt(i);
175           int tmpcid = tmpn.getCid();
176           int index = 0;
177           for(index = 0; index < sNodeVecs.size(); index++) {
178             if(sNodeVecs.elementAt(index).elementAt(0).getCid() > tmpcid) {
179               // find the place to insert
180               sNodeVecs.add(sNodeVecs.lastElement());
181               for(int j = sNodeVecs.size() - 2; j > index; j--) {
182                 sNodeVecs.setElementAt(sNodeVecs.elementAt(j - 1), j);
183               }
184               sNodeVecs.setElementAt(new Vector<ScheduleNode>(), index);
185             } else if(sNodeVecs.elementAt(index).elementAt(0).getCid() == tmpcid) {
186               break;
187             }
188           }
189           if(index == sNodeVecs.size()) {
190             sNodeVecs.add(new Vector<ScheduleNode>());
191           }
192
193           /*int index = tmpcid;
194             while(sNodeVecs.size() <= index) {
195                 sNodeVecs.add(null);
196             }
197             if(sNodeVecs.elementAt(index) == null) {
198                 sNodeVecs.setElementAt(new Vector<ScheduleNode>(), index);
199             }*/
200           sNodeVecs.elementAt(index).add(tmpn);
201         }
202
203         return sNodeVecs;
204       } catch(Error e) {
205         System.err.println("Error in rangeScheduleNodes");
206         e.printStackTrace();
207         return null;
208       }
209     }
210
211   /*public static int maxDivisor(int l, int r) {
212       int a = l;
213       int b = r;
214       int c = 0;
215
216       while(true) {
217           if(a == 0) {
218               return b << c;
219           } else if(b == 0) {
220               return a << c;
221           }
222
223           if(((a&1)==0) && ((b&1)==0)) {
224               // a and b are both even
225               a >>= 1;
226               b >>= 1;
227    ++c;
228           } else if(((a&1)==0) && ((b&1)!=0)) {
229               // a is even, b is odd
230               a >>= 1;
231           } else if (((a&1)!=0) && ((b&1)==0)) {
232               // a is odd, b is even
233               b >>= 1;
234           } else if (((a&1)!=0) && ((b&1)!=0)) {
235               // a and b are both odd
236               int tmp = a>b? b:a;
237               a = a>b ? (a-b):(b-a);
238               b = tmp;
239           }
240       }
241      }*/
242
243   public static boolean isTaskTrigger_flag(FlagExpressionNode fen,
244                                            FlagState fs) {
245     if (fen==null)
246       return true;
247     else if (fen instanceof FlagNode)
248       return fs.get(((FlagNode)fen).getFlag());
249     else
250       switch (((FlagOpNode)fen).getOp().getOp()) {
251       case Operation.LOGIC_AND:
252         return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
253
254       case Operation.LOGIC_OR:
255         return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
256
257       case Operation.LOGIC_NOT:
258         return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs));
259
260       default:
261         return false;
262       }
263   }
264
265   public static void printScheduleGraph(String path, 
266                                         Vector<ScheduleNode> sNodes) {
267     try {
268       File file=new File(path);
269       FileOutputStream dotstream=new FileOutputStream(file,false);
270       PrintWriter output = new java.io.PrintWriter(dotstream, true);
271       output.println("digraph G {");
272       output.println("\tcompound=true;\n");
273       traverseSNodes(output, sNodes);
274       output.println("}\n");
275       output.close();
276     } catch (Exception e) {
277       e.printStackTrace();
278       System.exit(-1);
279     }
280   }
281
282   private static void traverseSNodes(PrintWriter output, 
283                                      Vector<ScheduleNode> sNodes) {
284     //Draw clusters representing ScheduleNodes
285     Iterator it = sNodes.iterator();
286     while (it.hasNext()) {
287       ScheduleNode gn = (ScheduleNode) it.next();
288       Iterator edges = gn.edges();
289       output.println("\tsubgraph " + gn.getLabel() + "{");
290       output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
291       Iterator it_cnodes = gn.getClassNodesIterator();
292       traverseCNodes(output, it_cnodes);
293       it_cnodes = null;
294       //Draw the internal 'new' edges
295       Iterator it_edges =gn.getScheduleEdgesIterator();
296       while(it_edges.hasNext()) {
297         ScheduleEdge se = (ScheduleEdge)it_edges.next();
298         output.print("\t");
299         if(se.getSourceCNode().isclone()) {
300           output.print(se.getSourceCNode().getLabel());
301         } else {
302           if(se.getSourceFState() == null) {
303             output.print(se.getSourceCNode().getClusterLabel());
304           } else {
305             output.print(se.getSourceFState().getLabel());
306           }
307         }
308
309         output.print(" -> ");
310         if(se.isclone()) {
311           if(se.getTargetCNode().isclone()) {
312             output.print(se.getTargetCNode().getLabel());
313           } else {
314             output.print(se.getTargetCNode().getClusterLabel());
315           }
316           output.println(" [label=\"" + se.getLabel() + "\", color=red];");
317         } else {
318           output.print(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, ltail=");
319           if(se.getSourceCNode().isclone()) {
320             output.println(se.getSourceCNode().getLabel() + "];");
321           } else {
322             output.println(se.getSourceCNode().getClusterLabel() + "];");
323           }
324         }
325       }
326       output.println("\t}\n");
327       it_edges = null;
328       //Draw 'new' edges of this ScheduleNode
329       while(edges.hasNext()) {
330         ScheduleEdge se = (ScheduleEdge)edges.next();
331         output.print("\t");
332         if(se.getSourceCNode().isclone()) {
333           output.print(se.getSourceCNode().getLabel());
334         } else {
335           if(se.getSourceFState() == null) {
336             output.print(se.getSourceCNode().getClusterLabel());
337           } else {
338             output.print(se.getSourceFState().getLabel());
339           }
340         }
341
342         output.print(" -> ");
343         if(se.isclone()) {
344           if(se.getTargetCNode().isclone()) {
345             output.print(se.getTargetCNode().getLabel());
346           } else {
347             output.print(se.getTargetCNode().getClusterLabel());
348           }
349           output.println(" [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
350         } else {
351           output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
352         }
353       }
354       edges = null;
355     }
356     it = null;
357   }
358
359   private static void traverseCNodes(PrintWriter output, 
360                                      Iterator it) {
361     //Draw clusters representing ClassNodes
362     while (it.hasNext()) {
363       ClassNode gn = (ClassNode) it.next();
364       if(gn.isclone()) {
365         output.println("\t\t" + gn.getLabel() + " [style=dashed, label=\"" + gn.getTextLabel() + "\", shape=box];");
366       } else {
367         output.println("\tsubgraph " + gn.getClusterLabel() + "{");
368         output.println("\t\tstyle=dashed;");
369         output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
370         traverseFlagStates(output, gn.getFlagStates());
371         output.println("\t}\n");
372       }
373     }
374   }
375
376   private static void traverseFlagStates(PrintWriter output, 
377                                          Collection nodes) {
378     Set cycleset=GraphNode.findcycles(nodes);
379     Vector namers=new Vector();
380     namers.add(new Namer());
381     namers.add(new Allocations());
382
383     Iterator it = nodes.iterator();
384     while (it.hasNext()) {
385       GraphNode gn = (GraphNode) it.next();
386       Iterator edges = gn.edges();
387       String label = "";
388       String dotnodeparams="";
389
390       for(int i=0; i<namers.size(); i++) {
391         Namer name=(Namer) namers.get(i);
392         String newlabel=name.nodeLabel(gn);
393         String newparams=name.nodeOption(gn);
394
395         if (!newlabel.equals("") && !label.equals("")) {
396           label+=", ";
397         }
398         if (!newparams.equals("")) {
399           dotnodeparams+=", " + name.nodeOption(gn);
400         }
401         label+=name.nodeLabel(gn);
402       }
403       label += ":[" + ((FlagState)gn).getExeTime() + "]";
404
405       if (!gn.merge)
406         output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];");
407
408       if (!gn.merge)
409         while (edges.hasNext()) {
410           Edge edge = (Edge) edges.next();
411           GraphNode node = edge.getTarget();
412           if (nodes.contains(node)) {
413               Iterator nodeit=nonmerge(node, nodes).iterator();
414             for(; nodeit.hasNext();) {
415               GraphNode node2=(GraphNode)nodeit.next();
416               String edgelabel = "";
417               String edgedotnodeparams="";
418
419               for(int i=0; i<namers.size(); i++) {
420                 Namer name=(Namer) namers.get(i);
421                 String newlabel=name.edgeLabel(edge);
422                 String newoption=name.edgeOption(edge);
423                 if (!newlabel.equals("")&& !edgelabel.equals(""))
424                   edgelabel+=", ";
425                 edgelabel+=newlabel;
426                 if (!newoption.equals(""))
427                   edgedotnodeparams+=", "+newoption;
428               }
429               edgelabel+=":[" + ((FEdge)edge).getExeTime() + "]";
430               edgelabel+=":(" + ((FEdge)edge).getProbability() + "%)";
431               Hashtable<ClassDescriptor, NewObjInfo> hashtable = ((FEdge)edge).getNewObjInfoHashtable();
432               if(hashtable != null) {
433                 Set<ClassDescriptor> keys = hashtable.keySet();
434                 Iterator it_keys = keys.iterator();
435                 while(it_keys.hasNext()) {
436                   ClassDescriptor cd = (ClassDescriptor)it_keys.next();
437                   NewObjInfo noi = hashtable.get(cd);
438                   edgelabel += ":{ class " + cd.getSymbol() + " | " + noi.getNewRate() + " | (" + noi.getProbability() + "%) }";
439                 }
440                 keys = null;
441                 it_keys = null;
442               }
443               output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];");
444             }
445             nodeit = null;
446           }
447         }
448       edges = null;
449     }
450     cycleset = null;
451     namers = null;
452     it = null;
453   }
454
455   private static Set nonmerge(GraphNode gn, 
456                               Collection nodes) {
457     HashSet newset=new HashSet();
458     HashSet toprocess=new HashSet();
459     toprocess.add(gn);
460     while(!toprocess.isEmpty()) {
461       GraphNode gn2=(GraphNode)toprocess.iterator().next();
462       toprocess.remove(gn2);
463       if (!gn2.merge)
464         newset.add(gn2);
465       else {
466         Iterator edges = gn2.edges();
467         while (edges.hasNext()) {
468           Edge edge = (Edge) edges.next();
469           GraphNode node = edge.getTarget();
470           if (!newset.contains(node)&&nodes.contains(node))
471             toprocess.add(node);
472         }
473         edges = null;
474       }
475     }
476     toprocess = null;
477     return newset;
478   }
479
480   public static void printSimulationResult(String path, 
481                                            long time, 
482                                            int coreNum, 
483                                            Vector<CheckPoint> checkpoints) {
484     try {
485       File file=new File(path);
486       FileOutputStream dotstream=new FileOutputStream(file,false);
487       PrintWriter output = new java.io.PrintWriter(dotstream, true);
488       output.println("digraph simulation{");
489       output.print("\t");
490       output.println("node [shape=plaintext];");
491       output.print("\t");
492       output.println("edge [dir=none];");
493       output.print("\t");
494       output.println("ranksep=.05;");
495       output.println();
496       output.print("\t");
497       int j = 0;
498
499       // the capital line
500       output.print("{rank=source; \"Time\"; ");
501       for(j = 0; j < coreNum; j++) {
502         output.print("\"core " + j + "\"; ");
503       }
504       output.println("}");
505       // time coordinate nodes
506       Vector<String> timeNodes = new Vector<String>();
507       String[] lastTaskNodes = new String[coreNum];
508       String[] lastTasks = new String[coreNum];
509       boolean[] isTaskFinish = new boolean[coreNum];
510       for(j = 0; j < coreNum; j++) {
511         lastTaskNodes[j] = "first";
512         isTaskFinish[j] = true;
513         lastTasks[j] = "";
514       }
515       timeNodes.add("0");
516       for(j = 0; j < checkpoints.size(); j++) {
517         CheckPoint tcp = checkpoints.elementAt(j);
518         Hashtable<Integer, String> tmplastTasks = new Hashtable<Integer, String>();
519         Vector<Integer> tmpisTaskFinish = new Vector<Integer>();
520         Vector<Integer> tmpisset = new Vector<Integer>();
521         String tnode = String.valueOf(tcp.getTimepoint());
522         if(!timeNodes.contains(tnode)) {
523           timeNodes.add(tnode);
524         }
525         Vector<Action> actions = tcp.getActions();
526         Hashtable<String, StringBuffer> tmpTaskNodes = new Hashtable<String, StringBuffer>();
527         for(int i = 0; i < actions.size(); i++) {
528           Action taction = actions.elementAt(i);
529           int cNum = taction.getCoreNum();
530           if(!tmplastTasks.containsKey(cNum)) {
531             tmplastTasks.put(cNum, lastTasks[cNum]);
532           }
533           if(!(tmpisset.contains(cNum)) 
534                   && (isTaskFinish[cNum]) 
535                   && !(tmpisTaskFinish.contains(cNum))) {
536             tmpisTaskFinish.add(cNum);  // records those with task finished the first time visit it
537           }
538           String tmpTaskNode = "\"" + tnode + "core" + cNum + "\"";
539           StringBuffer tmpLabel = null;
540           boolean isfirst = false;
541           if(!tmpTaskNodes.containsKey(tmpTaskNode)) {
542             tmpTaskNodes.put(tmpTaskNode, new StringBuffer(tnode + ":"));
543             isfirst = true;
544           }
545           tmpLabel = tmpTaskNodes.get(tmpTaskNode);
546           switch(taction.getType()) {
547           case Action.ADDOBJ: {
548             if(!isfirst) {
549               tmpLabel.append("\\n");
550             }
551             tmpLabel.append("(" + taction.getTransObj().getSymbol() + ")arrives;");
552             if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
553               output.print("\t");
554               if(lastTaskNodes[cNum].equals("first")) {
555                 output.print("\"core " + cNum + "\"->" + tmpTaskNode);
556               } else {
557                 output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
558               }
559               if(tmpisTaskFinish.contains(cNum)) {
560                 output.print(" [style=invis]");
561               }
562               output.println(";");
563               lastTaskNodes[cNum] = tmpTaskNode;
564             }
565             break;
566           }
567
568           case Action.TASKFINISH: {
569             if(!isfirst) {
570               tmpLabel.append("\\n");
571             }
572             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
573             /*Vector<Integer> taskparams = taction.getTaskParams();
574             for(int ii = 0; ii < taskparams.size(); ii++) {
575                 tmpLabel.append(taskparams.elementAt(ii));
576                 if(ii < taskparams.size() - 1) {
577                     tmpLabel.append(",");
578                 }
579             }*/
580             tmpLabel.append(")>finishes;");
581             if(!(lastTaskNodes[cNum].equals("first"))) {
582               if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
583                 output.print("\t");
584                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
585                 lastTaskNodes[cNum] = tmpTaskNode;
586               }
587               if(tmpisset.contains(cNum)) {
588                 isTaskFinish[cNum] &= true;
589               } else {
590                 isTaskFinish[cNum] = true;
591                 tmpisset.add(cNum);
592               }
593               lastTasks[cNum] = "";
594             } else {
595               throw new Exception("Error: unexpected task finish");
596             }
597             break;
598           }
599
600           case Action.TFWITHOBJ: {
601             if(!isfirst) {
602               tmpLabel.append("\\n");
603             }
604             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
605             /*Vector<Integer> taskparams = taction.getTaskParams();
606             for(int ii = 0; ii < taskparams.size(); ii++) {
607                 tmpLabel.append(taskparams.elementAt(ii));
608                 if(ii < taskparams.size() - 1) {
609                     tmpLabel.append(",");
610                 }
611             }*/
612             tmpLabel.append(")>finishes;");
613             Iterator<Entry<ClassDescriptor, Integer>> it_entry = (Iterator<Entry<ClassDescriptor, Integer>>)taction.getNObjs().entrySet().iterator();
614             while(it_entry.hasNext()) {
615               Entry<ClassDescriptor, Integer> entry = it_entry.next();
616               tmpLabel.append(entry.getValue() + "(" + entry.getKey().getSymbol() + ")");
617               if(it_entry.hasNext()) {
618                 tmpLabel.append(",");
619               } else {
620                 tmpLabel.append(";");
621               }
622               entry = null;
623             }
624             it_entry = null;
625             if(!(lastTaskNodes[cNum].equals("first"))) {
626               if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
627                 output.print("\t");
628                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
629                 lastTaskNodes[cNum] = tmpTaskNode;
630               }
631               if(tmpisset.contains(cNum)) {
632                 isTaskFinish[cNum] &= true;
633               } else {
634                 isTaskFinish[cNum] = true;
635                 tmpisset.add(cNum);
636               }
637               lastTasks[cNum] = "";
638             } else {
639               throw new Exception("Error: unexpected task finish");
640             }
641             break;
642           }
643
644           case Action.TASKSTART: {
645             if(!isfirst) {
646               tmpLabel.append("\\n");
647             }
648             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
649             /*Vector<Integer> taskparams = taction.getTaskParams();
650             for(int ii = 0; ii < taskparams.size(); ii++) {
651                 tmpLabel.append(taskparams.elementAt(ii));
652                 if(ii < taskparams.size() - 1) {
653                     tmpLabel.append(",");
654                 }
655             }*/
656             tmpLabel.append(")>starts;");
657             lastTasks[cNum] = taction.getTd().getSymbol();
658
659             if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
660               output.print("\t");
661               if(lastTaskNodes[cNum].equals("first")) {
662                 output.print("\"core " + cNum + "\"->" + tmpTaskNode);
663               } else {
664                 output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
665               }
666               if(tmpisTaskFinish.contains(cNum)) {
667                 output.print(" [style=invis]");
668               }
669               output.println(";");
670               lastTaskNodes[cNum] = tmpTaskNode;
671             }
672             isTaskFinish[cNum] &= false;
673             break;
674           }
675
676           case Action.TASKABORT: {
677             if(!isfirst) {
678               tmpLabel.append("\\n");
679             }
680             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
681             /*Vector<Integer> taskparams = taction.getTaskParams();
682             for(int ii = 0; ii < taskparams.size(); ii++) {
683                 tmpLabel.append(taskparams.elementAt(ii));
684                 if(ii < taskparams.size() - 1) {
685                     tmpLabel.append(",");
686                 }
687             }*/
688             tmpLabel.append(")>aborts;");
689             if(!(lastTaskNodes[cNum].equals("first")) &&
690                (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
691               if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
692                 output.print("\t");
693                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
694                 lastTaskNodes[cNum] = tmpTaskNode;
695               }
696               if(tmpisset.contains(cNum)) {
697                 isTaskFinish[cNum] &= true;
698               } else {
699                 isTaskFinish[cNum] = true;
700                 tmpisset.add(cNum);
701               }
702               lastTasks[cNum] = "";
703             } else {
704               throw new Exception("Error: unexpected task aborts");
705             }
706             break;
707           }
708
709           case Action.TASKREMOVE: {
710             if(!isfirst) {
711               tmpLabel.append("\\n");
712             }
713             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
714             /*Vector<Integer> taskparams = taction.getTaskParams();
715             for(int ii = 0; ii < taskparams.size(); ii++) {
716                 tmpLabel.append(taskparams.elementAt(ii));
717                 if(ii < taskparams.size() - 1) {
718                     tmpLabel.append(",");
719                 }
720             }*/
721             tmpLabel.append(")>removes;");
722             if(!(lastTaskNodes[cNum].equals("first")) &&
723                (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
724               if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
725                 output.print("\t");
726                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
727                 lastTaskNodes[cNum] = tmpTaskNode;
728               }
729               if(tmpisset.contains(cNum)) {
730                 isTaskFinish[cNum] &= true;
731               } else {
732                 isTaskFinish[cNum] = true;
733                 tmpisset.add(cNum);
734               }
735               lastTasks[cNum] = "";
736             } else {
737               throw new Exception("Error: unexpected task remove");
738             }
739             break;
740           }
741           }
742         }
743         Enumeration<String> keys = tmpTaskNodes.keys();
744         while(keys.hasMoreElements()) {
745           String tmpTaskNode = keys.nextElement();
746           output.print("\t");
747           output.println(tmpTaskNode + "[label=\"" + tmpTaskNodes.get(tmpTaskNode).toString() + "\"]");
748         }
749         output.print("\t");
750         output.print("{rank=same; rankdir=LR; " + tnode + "; ");
751         keys = tmpTaskNodes.keys();
752         while(keys.hasMoreElements()) {
753           String tmpTaskNode = keys.nextElement();
754           output.print(tmpTaskNode);
755           output.print("; ");
756         }
757         keys = null;
758         output.println("}");
759         output.print("\t");
760         tmplastTasks = null;
761         tmpisTaskFinish = null;
762         tmpisset = null;
763         actions = null;
764         tmpTaskNodes = null;
765       }
766       output.print("\t");
767       output.print("\t");
768       long prev = Long.parseLong(timeNodes.elementAt(0));
769       long next = 0;
770       long max = 0;
771       long max2 = 0;
772       for(j = 1; j < timeNodes.size(); j++) {
773         next = Long.parseLong(timeNodes.elementAt(j));
774         long delta = next - prev;
775         if(max < delta) {
776           max2 = max;
777           max = delta;
778         } else if((max != delta) && (max2 < delta)) {
779           max2 = delta;
780         }
781         prev = next;
782       }
783       if(max2 == 0) {
784         max2 = 1;
785       } else if(max/max2 > 100) {
786         max2 = max/100;
787       }
788       output.println("\"Time\"->" + timeNodes.elementAt(0) + "[style=invis];");
789       prev = Long.parseLong(timeNodes.elementAt(0));
790       next = 0;
791       for(j = 1; j < timeNodes.size(); j++) {
792         next = Long.parseLong(timeNodes.elementAt(j));
793         if(next - prev > max2) {
794           do {
795             output.print(prev + "->");
796             prev += max2;
797           } while(next - prev > max2);
798           output.println(next + ";");
799         } else {
800           output.println("{rank=same; rankdir=LR; " + prev + "; " + next + "}");
801           output.println(prev + "->" + next + "[style=invis];");
802         }
803         prev = next;
804       }
805
806       /*for(j = 0; j < time; j++) {
807          output.print(j + "->");
808          }
809          output.println(timeNodes.lastElement() + ";");*/
810       output.println("}");
811       output.close();
812       timeNodes = null;
813       lastTaskNodes = null;
814       lastTasks = null;
815       isTaskFinish = null;
816     } catch (Exception e) {
817       e.printStackTrace();
818       System.exit(-1);
819     }
820   }
821   
822   public static void printCriticalPath(String path,
823                                        Vector<SimExecutionEdge> criticalPath) {
824       try {
825           File file=new File(path);
826           FileOutputStream dotstream=new FileOutputStream(file,false);
827           PrintWriter output = new java.io.PrintWriter(dotstream, true);
828           output.println("digraph simulation{");
829           output.print("\t");
830           output.println("node [shape=plaintext];");
831           output.print("\t");
832           output.println("edge [dir=none];");
833           output.print("\t");
834           output.println("ranksep=.05;");
835           output.println();
836           output.print("\t");
837           Vector<SimExecutionNode> nodes = new Vector<SimExecutionNode>();
838           String label = "";
839           String dotnodeparams="";
840
841           for(int i = 0; i < criticalPath.size(); i++) {
842               SimExecutionEdge seedge = criticalPath.elementAt(i);
843               SimExecutionNode startnode = (SimExecutionNode)seedge.getSource();
844               SimExecutionNode endnode = (SimExecutionNode)seedge.getTarget();
845               if(!nodes.contains(startnode)) {
846                   label = startnode.getCoreNum() + ":" + startnode.getTimepoint();
847                   output.println("\t" + startnode.getLabel() + " [label=\"" 
848                                  + label + "\" ];");
849           nodes.addElement(startnode);
850               }
851               if(!nodes.contains(endnode)) {
852                   label = endnode.getCoreNum() + ":" + endnode.getTimepoint();
853                   output.println("\t" + endnode.getLabel() + " [label=\"" 
854                                  + label + "\" ];");
855           nodes.addElement(endnode);
856               }
857               output.println("\t" + startnode.getLabel() + " -> " + endnode.getLabel() 
858                              + " [" + "label=\"" + seedge.getLabel() + "\"];");
859           }
860           output.println("}");
861           output.close();
862       nodes.clear();
863           nodes = null;
864       } catch (Exception e) {
865           e.printStackTrace();
866           System.exit(-1);
867       }
868   }
869 }