changes to handle fixed point analysis properly + bug fix.
[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>> rangeScheduleNodes(Vector<ScheduleNode> scheduleNodes) {
169         Vector<Vector<ScheduleNode>> sNodeVecs = new Vector<Vector<ScheduleNode>>();
170         
171         for(int i = 0; i < scheduleNodes.size(); i++) {
172             ScheduleNode tmpn = scheduleNodes.elementAt(i);
173             int tmpcid = tmpn.getCid();
174             int index = 0;
175             for(index = 0; index < sNodeVecs.size(); index++) {
176                 if(sNodeVecs.elementAt(index).elementAt(0).getCid() > tmpcid) {
177                     // find the place to insert
178                     sNodeVecs.add(sNodeVecs.lastElement());
179                     for(int j = sNodeVecs.size() - 2; j > index; j--) {
180                         sNodeVecs.setElementAt(sNodeVecs.elementAt(j - 1), j);
181                     }
182                     sNodeVecs.setElementAt(new Vector<ScheduleNode>(), index);
183                 } else if(sNodeVecs.elementAt(index).elementAt(0).getCid() == tmpcid) {
184                     break;
185                 }
186             }
187             if(index == sNodeVecs.size()) {
188                 sNodeVecs.add(new Vector<ScheduleNode>());
189             }
190             
191             /*int index = tmpcid;
192             while(sNodeVecs.size() <= index) {
193                 sNodeVecs.add(null);
194             }
195             if(sNodeVecs.elementAt(index) == null) {
196                 sNodeVecs.setElementAt(new Vector<ScheduleNode>(), index);
197             }*/
198             sNodeVecs.elementAt(index).add(tmpn);
199         }
200         
201         return sNodeVecs;
202     }
203
204   /*public static int maxDivisor(int l, int r) {
205       int a = l;
206       int b = r;
207       int c = 0;
208
209       while(true) {
210           if(a == 0) {
211               return b << c;
212           } else if(b == 0) {
213               return a << c;
214           }
215
216           if(((a&1)==0) && ((b&1)==0)) {
217               // a and b are both even
218               a >>= 1;
219               b >>= 1;
220    ++c;
221           } else if(((a&1)==0) && ((b&1)!=0)) {
222               // a is even, b is odd
223               a >>= 1;
224           } else if (((a&1)!=0) && ((b&1)==0)) {
225               // a is odd, b is even
226               b >>= 1;
227           } else if (((a&1)!=0) && ((b&1)!=0)) {
228               // a and b are both odd
229               int tmp = a>b? b:a;
230               a = a>b ? (a-b):(b-a);
231               b = tmp;
232           }
233       }
234      }*/
235
236   public static boolean isTaskTrigger_flag(FlagExpressionNode fen,
237                                            FlagState fs) {
238     if (fen==null)
239       return true;
240     else if (fen instanceof FlagNode)
241       return fs.get(((FlagNode)fen).getFlag());
242     else
243       switch (((FlagOpNode)fen).getOp().getOp()) {
244       case Operation.LOGIC_AND:
245         return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
246
247       case Operation.LOGIC_OR:
248         return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
249
250       case Operation.LOGIC_NOT:
251         return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs));
252
253       default:
254         return false;
255       }
256   }
257
258   public static void printScheduleGraph(String path, 
259                                         Vector<ScheduleNode> sNodes) {
260     try {
261       File file=new File(path);
262       FileOutputStream dotstream=new FileOutputStream(file,false);
263       PrintWriter output = new java.io.PrintWriter(dotstream, true);
264       output.println("digraph G {");
265       output.println("\tcompound=true;\n");
266       traverseSNodes(output, sNodes);
267       output.println("}\n");
268       output.close();
269     } catch (Exception e) {
270       e.printStackTrace();
271       System.exit(-1);
272     }
273   }
274
275   private static void traverseSNodes(PrintWriter output, 
276                                      Vector<ScheduleNode> sNodes) {
277     //Draw clusters representing ScheduleNodes
278     Iterator it = sNodes.iterator();
279     while (it.hasNext()) {
280       ScheduleNode gn = (ScheduleNode) it.next();
281       Iterator edges = gn.edges();
282       output.println("\tsubgraph " + gn.getLabel() + "{");
283       output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
284       Iterator it_cnodes = gn.getClassNodesIterator();
285       traverseCNodes(output, it_cnodes);
286       it_cnodes = null;
287       //Draw the internal 'new' edges
288       Iterator it_edges =gn.getScheduleEdgesIterator();
289       while(it_edges.hasNext()) {
290         ScheduleEdge se = (ScheduleEdge)it_edges.next();
291         output.print("\t");
292         if(se.getSourceCNode().isclone()) {
293           output.print(se.getSourceCNode().getLabel());
294         } else {
295           if(se.getSourceFState() == null) {
296             output.print(se.getSourceCNode().getClusterLabel());
297           } else {
298             output.print(se.getSourceFState().getLabel());
299           }
300         }
301
302         output.print(" -> ");
303         if(se.isclone()) {
304           if(se.getTargetCNode().isclone()) {
305             output.print(se.getTargetCNode().getLabel());
306           } else {
307             output.print(se.getTargetCNode().getClusterLabel());
308           }
309           output.println(" [label=\"" + se.getLabel() + "\", color=red];");
310         } else {
311           output.print(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, ltail=");
312           if(se.getSourceCNode().isclone()) {
313             output.println(se.getSourceCNode().getLabel() + "];");
314           } else {
315             output.println(se.getSourceCNode().getClusterLabel() + "];");
316           }
317         }
318       }
319       output.println("\t}\n");
320       it_edges = null;
321       //Draw 'new' edges of this ScheduleNode
322       while(edges.hasNext()) {
323         ScheduleEdge se = (ScheduleEdge)edges.next();
324         output.print("\t");
325         if(se.getSourceCNode().isclone()) {
326           output.print(se.getSourceCNode().getLabel());
327         } else {
328           if(se.getSourceFState() == null) {
329             output.print(se.getSourceCNode().getClusterLabel());
330           } else {
331             output.print(se.getSourceFState().getLabel());
332           }
333         }
334
335         output.print(" -> ");
336         if(se.isclone()) {
337           if(se.getTargetCNode().isclone()) {
338             output.print(se.getTargetCNode().getLabel());
339           } else {
340             output.print(se.getTargetCNode().getClusterLabel());
341           }
342           output.println(" [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
343         } else {
344           output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
345         }
346       }
347       edges = null;
348     }
349     it = null;
350   }
351
352   private static void traverseCNodes(PrintWriter output, 
353                                      Iterator it) {
354     //Draw clusters representing ClassNodes
355     while (it.hasNext()) {
356       ClassNode gn = (ClassNode) it.next();
357       if(gn.isclone()) {
358         output.println("\t\t" + gn.getLabel() + " [style=dashed, label=\"" + gn.getTextLabel() + "\", shape=box];");
359       } else {
360         output.println("\tsubgraph " + gn.getClusterLabel() + "{");
361         output.println("\t\tstyle=dashed;");
362         output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
363         traverseFlagStates(output, gn.getFlagStates());
364         output.println("\t}\n");
365       }
366     }
367   }
368
369   private static void traverseFlagStates(PrintWriter output, 
370                                          Collection nodes) {
371     Set cycleset=GraphNode.findcycles(nodes);
372     Vector namers=new Vector();
373     namers.add(new Namer());
374     namers.add(new Allocations());
375
376     Iterator it = nodes.iterator();
377     while (it.hasNext()) {
378       GraphNode gn = (GraphNode) it.next();
379       Iterator edges = gn.edges();
380       String label = "";
381       String dotnodeparams="";
382
383       for(int i=0; i<namers.size(); i++) {
384         Namer name=(Namer) namers.get(i);
385         String newlabel=name.nodeLabel(gn);
386         String newparams=name.nodeOption(gn);
387
388         if (!newlabel.equals("") && !label.equals("")) {
389           label+=", ";
390         }
391         if (!newparams.equals("")) {
392           dotnodeparams+=", " + name.nodeOption(gn);
393         }
394         label+=name.nodeLabel(gn);
395       }
396       label += ":[" + ((FlagState)gn).getExeTime() + "]";
397
398       if (!gn.merge)
399         output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];");
400
401       if (!gn.merge)
402         while (edges.hasNext()) {
403           Edge edge = (Edge) edges.next();
404           GraphNode node = edge.getTarget();
405           if (nodes.contains(node)) {
406               Iterator nodeit=nonmerge(node, nodes).iterator();
407             for(; nodeit.hasNext();) {
408               GraphNode node2=(GraphNode)nodeit.next();
409               String edgelabel = "";
410               String edgedotnodeparams="";
411
412               for(int i=0; i<namers.size(); i++) {
413                 Namer name=(Namer) namers.get(i);
414                 String newlabel=name.edgeLabel(edge);
415                 String newoption=name.edgeOption(edge);
416                 if (!newlabel.equals("")&& !edgelabel.equals(""))
417                   edgelabel+=", ";
418                 edgelabel+=newlabel;
419                 if (!newoption.equals(""))
420                   edgedotnodeparams+=", "+newoption;
421               }
422               edgelabel+=":[" + ((FEdge)edge).getExeTime() + "]";
423               edgelabel+=":(" + ((FEdge)edge).getProbability() + "%)";
424               Hashtable<ClassDescriptor, NewObjInfo> hashtable = ((FEdge)edge).getNewObjInfoHashtable();
425               if(hashtable != null) {
426                 Set<ClassDescriptor> keys = hashtable.keySet();
427                 Iterator it_keys = keys.iterator();
428                 while(it_keys.hasNext()) {
429                   ClassDescriptor cd = (ClassDescriptor)it_keys.next();
430                   NewObjInfo noi = hashtable.get(cd);
431                   edgelabel += ":{ class " + cd.getSymbol() + " | " + noi.getNewRate() + " | (" + noi.getProbability() + "%) }";
432                 }
433                 keys = null;
434                 it_keys = null;
435               }
436               output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];");
437             }
438             nodeit = null;
439           }
440         }
441       edges = null;
442     }
443     cycleset = null;
444     namers = null;
445     it = null;
446   }
447
448   private static Set nonmerge(GraphNode gn, 
449                               Collection nodes) {
450     HashSet newset=new HashSet();
451     HashSet toprocess=new HashSet();
452     toprocess.add(gn);
453     while(!toprocess.isEmpty()) {
454       GraphNode gn2=(GraphNode)toprocess.iterator().next();
455       toprocess.remove(gn2);
456       if (!gn2.merge)
457         newset.add(gn2);
458       else {
459         Iterator edges = gn2.edges();
460         while (edges.hasNext()) {
461           Edge edge = (Edge) edges.next();
462           GraphNode node = edge.getTarget();
463           if (!newset.contains(node)&&nodes.contains(node))
464             toprocess.add(node);
465         }
466         edges = null;
467       }
468     }
469     toprocess = null;
470     return newset;
471   }
472
473   public static void printSimulationResult(String path, 
474                                            long time, 
475                                            int coreNum, 
476                                            Vector<CheckPoint> checkpoints) {
477     try {
478       File file=new File(path);
479       FileOutputStream dotstream=new FileOutputStream(file,false);
480       PrintWriter output = new java.io.PrintWriter(dotstream, true);
481       output.println("digraph simulation{");
482       output.print("\t");
483       output.println("node [shape=plaintext];");
484       output.print("\t");
485       output.println("edge [dir=none];");
486       output.print("\t");
487       output.println("ranksep=.05;");
488       output.println();
489       output.print("\t");
490       int j = 0;
491
492       // the capital line
493       output.print("{rank=source; \"Time\"; ");
494       for(j = 0; j < coreNum; j++) {
495         output.print("\"core " + j + "\"; ");
496       }
497       output.println("}");
498       // time coordinate nodes
499       Vector<String> timeNodes = new Vector<String>();
500       String[] lastTaskNodes = new String[coreNum];
501       String[] lastTasks = new String[coreNum];
502       boolean[] isTaskFinish = new boolean[coreNum];
503       for(j = 0; j < coreNum; j++) {
504         lastTaskNodes[j] = "first";
505         isTaskFinish[j] = true;
506         lastTasks[j] = "";
507       }
508       timeNodes.add("0");
509       for(j = 0; j < checkpoints.size(); j++) {
510         CheckPoint tcp = checkpoints.elementAt(j);
511         Hashtable<Integer, String> tmplastTasks = new Hashtable<Integer, String>();
512         Vector<Integer> tmpisTaskFinish = new Vector<Integer>();
513         Vector<Integer> tmpisset = new Vector<Integer>();
514         String tnode = String.valueOf(tcp.getTimepoint());
515         if(!timeNodes.contains(tnode)) {
516           timeNodes.add(tnode);
517         }
518         Vector<Action> actions = tcp.getActions();
519         Hashtable<String, StringBuffer> tmpTaskNodes = new Hashtable<String, StringBuffer>();
520         for(int i = 0; i < actions.size(); i++) {
521           Action taction = actions.elementAt(i);
522           int cNum = taction.getCoreNum();
523           if(!tmplastTasks.containsKey(cNum)) {
524             tmplastTasks.put(cNum, lastTasks[cNum]);
525           }
526           if(!(tmpisset.contains(cNum)) 
527                   && (isTaskFinish[cNum]) 
528                   && !(tmpisTaskFinish.contains(cNum))) {
529             tmpisTaskFinish.add(cNum);  // records those with task finished the first time visit it
530           }
531           String tmpTaskNode = "\"" + tnode + "core" + cNum + "\"";
532           StringBuffer tmpLabel = null;
533           boolean isfirst = false;
534           if(!tmpTaskNodes.containsKey(tmpTaskNode)) {
535             tmpTaskNodes.put(tmpTaskNode, new StringBuffer(tnode + ":"));
536             isfirst = true;
537           }
538           tmpLabel = tmpTaskNodes.get(tmpTaskNode);
539           switch(taction.getType()) {
540           case Action.ADDOBJ: {
541             if(!isfirst) {
542               tmpLabel.append("\\n");
543             }
544             tmpLabel.append("(" + taction.getTransObj().getSymbol() + ")arrives;");
545             if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
546               output.print("\t");
547               if(lastTaskNodes[cNum].equals("first")) {
548                 output.print("\"core " + cNum + "\"->" + tmpTaskNode);
549               } else {
550                 output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
551               }
552               if(tmpisTaskFinish.contains(cNum)) {
553                 output.print(" [style=invis]");
554               }
555               output.println(";");
556               lastTaskNodes[cNum] = tmpTaskNode;
557             }
558             break;
559           }
560
561           case Action.TASKFINISH: {
562             if(!isfirst) {
563               tmpLabel.append("\\n");
564             }
565             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
566             /*Vector<Integer> taskparams = taction.getTaskParams();
567             for(int ii = 0; ii < taskparams.size(); ii++) {
568                 tmpLabel.append(taskparams.elementAt(ii));
569                 if(ii < taskparams.size() - 1) {
570                     tmpLabel.append(",");
571                 }
572             }*/
573             tmpLabel.append(")>finishes;");
574             if(!(lastTaskNodes[cNum].equals("first"))) {
575               if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
576                 output.print("\t");
577                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
578                 lastTaskNodes[cNum] = tmpTaskNode;
579               }
580               if(tmpisset.contains(cNum)) {
581                 isTaskFinish[cNum] &= true;
582               } else {
583                 isTaskFinish[cNum] = true;
584                 tmpisset.add(cNum);
585               }
586               lastTasks[cNum] = "";
587             } else {
588               throw new Exception("Error: unexpected task finish");
589             }
590             break;
591           }
592
593           case Action.TFWITHOBJ: {
594             if(!isfirst) {
595               tmpLabel.append("\\n");
596             }
597             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
598             /*Vector<Integer> taskparams = taction.getTaskParams();
599             for(int ii = 0; ii < taskparams.size(); ii++) {
600                 tmpLabel.append(taskparams.elementAt(ii));
601                 if(ii < taskparams.size() - 1) {
602                     tmpLabel.append(",");
603                 }
604             }*/
605             tmpLabel.append(")>finishes;");
606             Iterator<Entry<ClassDescriptor, Integer>> it_entry = (Iterator<Entry<ClassDescriptor, Integer>>)taction.getNObjs().entrySet().iterator();
607             while(it_entry.hasNext()) {
608               Entry<ClassDescriptor, Integer> entry = it_entry.next();
609               tmpLabel.append(entry.getValue() + "(" + entry.getKey().getSymbol() + ")");
610               if(it_entry.hasNext()) {
611                 tmpLabel.append(",");
612               } else {
613                 tmpLabel.append(";");
614               }
615               entry = null;
616             }
617             it_entry = null;
618             if(!(lastTaskNodes[cNum].equals("first"))) {
619               if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
620                 output.print("\t");
621                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
622                 lastTaskNodes[cNum] = tmpTaskNode;
623               }
624               if(tmpisset.contains(cNum)) {
625                 isTaskFinish[cNum] &= true;
626               } else {
627                 isTaskFinish[cNum] = true;
628                 tmpisset.add(cNum);
629               }
630               lastTasks[cNum] = "";
631             } else {
632               throw new Exception("Error: unexpected task finish");
633             }
634             break;
635           }
636
637           case Action.TASKSTART: {
638             if(!isfirst) {
639               tmpLabel.append("\\n");
640             }
641             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
642             /*Vector<Integer> taskparams = taction.getTaskParams();
643             for(int ii = 0; ii < taskparams.size(); ii++) {
644                 tmpLabel.append(taskparams.elementAt(ii));
645                 if(ii < taskparams.size() - 1) {
646                     tmpLabel.append(",");
647                 }
648             }*/
649             tmpLabel.append(")>starts;");
650             lastTasks[cNum] = taction.getTd().getSymbol();
651
652             if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
653               output.print("\t");
654               if(lastTaskNodes[cNum].equals("first")) {
655                 output.print("\"core " + cNum + "\"->" + tmpTaskNode);
656               } else {
657                 output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
658               }
659               if(tmpisTaskFinish.contains(cNum)) {
660                 output.print(" [style=invis]");
661               }
662               output.println(";");
663               lastTaskNodes[cNum] = tmpTaskNode;
664             }
665             isTaskFinish[cNum] &= false;
666             break;
667           }
668
669           case Action.TASKABORT: {
670             if(!isfirst) {
671               tmpLabel.append("\\n");
672             }
673             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
674             /*Vector<Integer> taskparams = taction.getTaskParams();
675             for(int ii = 0; ii < taskparams.size(); ii++) {
676                 tmpLabel.append(taskparams.elementAt(ii));
677                 if(ii < taskparams.size() - 1) {
678                     tmpLabel.append(",");
679                 }
680             }*/
681             tmpLabel.append(")>aborts;");
682             if(!(lastTaskNodes[cNum].equals("first")) &&
683                (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
684               if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
685                 output.print("\t");
686                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
687                 lastTaskNodes[cNum] = tmpTaskNode;
688               }
689               if(tmpisset.contains(cNum)) {
690                 isTaskFinish[cNum] &= true;
691               } else {
692                 isTaskFinish[cNum] = true;
693                 tmpisset.add(cNum);
694               }
695               lastTasks[cNum] = "";
696             } else {
697               throw new Exception("Error: unexpected task aborts");
698             }
699             break;
700           }
701
702           case Action.TASKREMOVE: {
703             if(!isfirst) {
704               tmpLabel.append("\\n");
705             }
706             tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
707             /*Vector<Integer> taskparams = taction.getTaskParams();
708             for(int ii = 0; ii < taskparams.size(); ii++) {
709                 tmpLabel.append(taskparams.elementAt(ii));
710                 if(ii < taskparams.size() - 1) {
711                     tmpLabel.append(",");
712                 }
713             }*/
714             tmpLabel.append(")>removes;");
715             if(!(lastTaskNodes[cNum].equals("first")) &&
716                (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
717               if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
718                 output.print("\t");
719                 output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
720                 lastTaskNodes[cNum] = tmpTaskNode;
721               }
722               if(tmpisset.contains(cNum)) {
723                 isTaskFinish[cNum] &= true;
724               } else {
725                 isTaskFinish[cNum] = true;
726                 tmpisset.add(cNum);
727               }
728               lastTasks[cNum] = "";
729             } else {
730               throw new Exception("Error: unexpected task remove");
731             }
732             break;
733           }
734           }
735         }
736         Enumeration<String> keys = tmpTaskNodes.keys();
737         while(keys.hasMoreElements()) {
738           String tmpTaskNode = keys.nextElement();
739           output.print("\t");
740           output.println(tmpTaskNode + "[label=\"" + tmpTaskNodes.get(tmpTaskNode).toString() + "\"]");
741         }
742         output.print("\t");
743         output.print("{rank=same; rankdir=LR; " + tnode + "; ");
744         keys = tmpTaskNodes.keys();
745         while(keys.hasMoreElements()) {
746           String tmpTaskNode = keys.nextElement();
747           output.print(tmpTaskNode);
748           output.print("; ");
749         }
750         keys = null;
751         output.println("}");
752         output.print("\t");
753         tmplastTasks = null;
754         tmpisTaskFinish = null;
755         tmpisset = null;
756         actions = null;
757         tmpTaskNodes = null;
758       }
759       output.print("\t");
760       output.print("\t");
761       long prev = Long.parseLong(timeNodes.elementAt(0));
762       long next = 0;
763       long max = 0;
764       long max2 = 0;
765       for(j = 1; j < timeNodes.size(); j++) {
766         next = Long.parseLong(timeNodes.elementAt(j));
767         long delta = next - prev;
768         if(max < delta) {
769           max2 = max;
770           max = delta;
771         } else if((max != delta) && (max2 < delta)) {
772           max2 = delta;
773         }
774         prev = next;
775       }
776       if(max2 == 0) {
777         max2 = 1;
778       } else if(max/max2 > 100) {
779         max2 = max/100;
780       }
781       output.println("\"Time\"->" + timeNodes.elementAt(0) + "[style=invis];");
782       prev = Long.parseLong(timeNodes.elementAt(0));
783       next = 0;
784       for(j = 1; j < timeNodes.size(); j++) {
785         next = Long.parseLong(timeNodes.elementAt(j));
786         if(next - prev > max2) {
787           do {
788             output.print(prev + "->");
789             prev += max2;
790           } while(next - prev > max2);
791           output.println(next + ";");
792         } else {
793           output.println("{rank=same; rankdir=LR; " + prev + "; " + next + "}");
794           output.println(prev + "->" + next + "[style=invis];");
795         }
796         prev = next;
797       }
798
799       /*for(j = 0; j < time; j++) {
800          output.print(j + "->");
801          }
802          output.println(timeNodes.lastElement() + ";");*/
803       output.println("}");
804       output.close();
805       timeNodes = null;
806       lastTaskNodes = null;
807       lastTasks = null;
808       isTaskFinish = null;
809     } catch (Exception e) {
810       e.printStackTrace();
811       System.exit(-1);
812     }
813   }
814   
815   public static void printCriticalPath(String path,
816                                        Vector<SimExecutionEdge> criticalPath) {
817       try {
818           File file=new File(path);
819           FileOutputStream dotstream=new FileOutputStream(file,false);
820           PrintWriter output = new java.io.PrintWriter(dotstream, true);
821           output.println("digraph simulation{");
822           output.print("\t");
823           output.println("node [shape=plaintext];");
824           output.print("\t");
825           output.println("edge [dir=none];");
826           output.print("\t");
827           output.println("ranksep=.05;");
828           output.println();
829           output.print("\t");
830           Vector<SimExecutionNode> nodes = new Vector<SimExecutionNode>();
831           String label = "";
832           String dotnodeparams="";
833
834           for(int i = 0; i < criticalPath.size(); i++) {
835               SimExecutionEdge seedge = criticalPath.elementAt(i);
836               SimExecutionNode startnode = (SimExecutionNode)seedge.getSource();
837               SimExecutionNode endnode = (SimExecutionNode)seedge.getTarget();
838               if(!nodes.contains(startnode)) {
839                   label = startnode.getCoreNum() + ":" + startnode.getTimepoint();
840                   output.println("\t" + startnode.getLabel() + " [label=\"" 
841                                  + label + "\" ];");
842               }
843               if(!nodes.contains(endnode)) {
844                   label = endnode.getCoreNum() + ":" + endnode.getTimepoint();
845                   output.println("\t" + endnode.getLabel() + " [label=\"" 
846                                  + label + "\" ];");
847               }
848               output.println("\t" + startnode.getLabel() + " -> " + endnode.getLabel() 
849                              + " [" + "label=\"" + seedge.getLabel() + "\"];");
850           }
851           output.println("}");
852           output.close();
853           nodes = null;
854       } catch (Exception e) {
855           e.printStackTrace();
856           System.exit(-1);
857       }
858   }
859 }