add codes for randomly generating core group mappings on cores
authorjzhou <jzhou>
Tue, 19 Jan 2010 22:43:09 +0000 (22:43 +0000)
committerjzhou <jzhou>
Tue, 19 Jan 2010 22:43:09 +0000 (22:43 +0000)
Robust/src/Analysis/Scheduling/CombinationUtil.java
Robust/src/Analysis/Scheduling/MCImplSynthesis.java
Robust/src/Analysis/Scheduling/ScheduleAnalysis.java
Robust/src/Analysis/Scheduling/SchedulingUtil.java

index be8f5667918371706879af38354f826ff0288c1d..d1a5d300769c95d77007d810996534f1be506bf9 100644 (file)
@@ -1,5 +1,6 @@
 package Analysis.Scheduling;
 
+import java.util.Random;
 import java.util.Vector;
 
 public class CombinationUtil {
@@ -24,6 +25,11 @@ public class CombinationUtil {
                                                          Vector<Vector<ScheduleNode>> node2combine) {
     return CombinationUtil.allocateCombinationUtil().new CombineGenerator(rootnodes, node2combine);
   }
+  
+  public static RandomGenerator allocateRandomGenerator(Vector<Vector<ScheduleNode>> snodevecs, 
+                                                         int rootNum) {
+      return CombinationUtil.allocateCombinationUtil().new RandomGenerator(snodevecs, rootNum);
+  }
 
   public class RootsGenerator {
     Vector<Vector<ScheduleNode>> sNodeVecs;
@@ -195,12 +201,16 @@ public class CombinationUtil {
     Vector<Vector<Combine>> combine;
     int[] lastchoices;
     boolean first4choice;
+    Random rand;
+    int limit;
+    int[][] rootLoads;
 
     public CombineGenerator(Vector<Vector<ScheduleNode>> rootnodes, 
                            Vector<Vector<ScheduleNode>> node2combine) {
       this.rootNodes = rootnodes;
       this.node2Combine = node2combine;
       this.rootNStates = new Vector<Vector<int[]>>();
+      int rootnum = 0;
       for(int i = 0; i < this.rootNodes.size(); i++) {
        this.rootNStates.add(new Vector<int[]>());
        for(int j = 0; j < this.rootNodes.elementAt(i).size(); j++) {
@@ -208,9 +218,11 @@ public class CombinationUtil {
          for(int k = 0; k < this.node2Combine.size(); k++) {
            this.rootNStates.elementAt(i).elementAt(j)[k] = 0;
          }
+         rootnum++;
        }
       }
       this.combine = new Vector<Vector<Combine>>();
+      int tomapnum = 0;
       for(int i = 0; i < this.node2Combine.size(); i++) {
        if(this.node2Combine.elementAt(i) == null) {
          this.combine.add(null);
@@ -218,11 +230,16 @@ public class CombinationUtil {
          this.combine.add(new Vector<Combine>());
          for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
            this.combine.elementAt(i).add(new Combine(this.node2Combine.elementAt(i).elementAt(j)));
+           tomapnum++;
          }
        }
       }
       this.lastchoices = null;
       this.first4choice = false;
+      this.rand = new Random();
+      
+      this.limit = (tomapnum-1)/rootnum+1;
+      this.rootLoads = null;
     }
     
     public void clear() {
@@ -239,6 +256,43 @@ public class CombinationUtil {
     public Vector<Vector<Combine>> getCombine() {
       return combine;
     }
+    
+    // generate next mapping randomly evenly
+    public boolean randomGenE() {
+       this.rootLoads = new int[this.rootNodes.size()][];
+       for(int i = 0; i < this.rootNodes.size(); i++) {
+           this.rootLoads[i] = new int[this.rootNodes.elementAt(i).size()];
+       }
+       int rootx = this.rootNodes.size();
+       for(int i = 0; i < this.node2Combine.size(); i++) {
+           for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
+               Combine tmp = this.combine.elementAt(i).elementAt(j);
+               do {
+                   int x = Math.abs(rand.nextInt()) % rootx;
+                   int y = Math.abs(rand.nextInt()) % this.rootNodes.elementAt(x).size();
+                   if(this.rootLoads[x][y] < this.limit) {
+                       tmp.root  = x;
+                       tmp.index = y;
+                       this.rootLoads[tmp.root][tmp.index]++;
+                       break;
+                   }
+               }while(true);
+           }
+       }
+       return true;
+    }
+    
+    public boolean randomGen() {
+       int rootx = this.rootNodes.size();
+       for(int i = 0; i < this.node2Combine.size(); i++) {
+           for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
+               Combine tmp = this.combine.elementAt(i).elementAt(j);
+               tmp.root = Math.abs(rand.nextInt()) % rootx;
+               tmp.index = Math.abs(rand.nextInt()) % this.rootNodes.elementAt(tmp.root).size();
+           }
+       }
+       return true;
+    }
 
     public boolean nextGen() {
       boolean trial = false;
@@ -579,4 +633,55 @@ public class CombinationUtil {
       }
     }
   }
+  
+  public class RandomGenerator {
+      Vector<Vector<ScheduleNode>> sNodeVecs;
+      Vector<Vector<ScheduleNode>> mapping;
+      int rootNum;
+      Random rand;
+
+      public RandomGenerator(Vector<Vector<ScheduleNode>> snodevecs, 
+                            int rootNum) {
+        this.sNodeVecs = snodevecs;
+        this.rootNum = rootNum;
+        
+        this.mapping = new Vector<Vector<ScheduleNode>>();
+        for(int i = 0; i < this.rootNum; i++) {
+            this.mapping.add(null);
+        }
+        this.rand = new Random();
+      }
+      
+      public void clear() {
+       this.sNodeVecs = null;
+       this.rootNum = 0;
+       this.mapping = null;
+      }
+
+      public boolean nextGen() {
+         this.mapping = null;
+         this.mapping = new Vector<Vector<ScheduleNode>>();
+         for(int i = 0; i < this.rootNum; i++) {
+             this.mapping.add(null);
+         }
+         
+         // randomly choose a core for each node in sNodeVecs
+         for(int i = 0; i < this.sNodeVecs.size(); i++) {
+             Vector<ScheduleNode> sNodes = this.sNodeVecs.elementAt(i);
+             for(int j = 0; j < sNodes.size(); j++) {
+                 ScheduleNode snode = sNodes.elementAt(j);
+                 int core = Math.abs(rand.nextInt()) % this.rootNum;
+                 if(this.mapping.elementAt(core) == null) {
+                     this.mapping.setElementAt(new Vector<ScheduleNode>(), core);
+                 }
+                 this.mapping.elementAt(core).add(snode);
+             }
+         }
+         return true;
+      }
+      
+      public Vector<Vector<ScheduleNode>> getMapping() {
+         return this.mapping;
+      }
+  }
 }
\ No newline at end of file
index 30f1c35467405e00d28e4d931c3cf4c0ab759acd..fbac0574aadb52aa3a46ea579ac91031d6134c25 100644 (file)
@@ -53,7 +53,7 @@ public class MCImplSynthesis {
     this.scheduleThreshold = 1000;
     this.probThreshold = 0;
     this.generateThreshold = 30;
-    this.skipThreshold = 100; // never skip
+    this.skipThreshold = 100; // never skip // 30;
   }
 
   public int getCoreNum() {
@@ -1047,7 +1047,7 @@ public class MCImplSynthesis {
       cloneScheduleGraph(scheduleGraph, lgid);
     
     if(newscheduleGraph.size() == 0) {
-      System.err.println("empty schedule graph!");
+      //System.err.println("empty schedule graph!");
       return optimizeschedulegraphs;
     }
 
@@ -1124,6 +1124,7 @@ public class MCImplSynthesis {
       CombinationUtil.allocateCombineGenerator(rootNodes, nodes2combine);
     Random rand = new Random();
     while ((left > 0) && (cGen.nextGen())) {
+    //while ((left > 0) && (cGen.randomGen())) {
       if(Math.abs(rand.nextInt()) % 100 > this.generateThreshold) {
         Vector<Vector<CombinationUtil.Combine>> combine = cGen.getCombine();
         Vector<ScheduleNode> sNodes = 
index 3ed1ab38f7405c388c41c3cc2b04eb38ea140115..4334cb2d2bd8ab04303657f7607e905ccdaa0028 100644 (file)
@@ -1229,13 +1229,77 @@ public class ScheduleAnalysis {
       Vector<Vector<ScheduleNode>> sNodeVecs = 
         SchedulingUtil.rangeScheduleNodes(this.scheduleNodes);
 
-      CombinationUtil.RootsGenerator rGen = 
-        CombinationUtil.allocateRootsGenerator(sNodeVecs, 
-            this.coreNum);
-
       int gid = 1;
-      Random rand = new Random();
       boolean isBig = Math.pow(this.coreNum, reduceNum) > 1000;
+      Random rand = new Random();
+      if(false) {
+         CombinationUtil.RootsGenerator rGen = 
+               CombinationUtil.allocateRootsGenerator(sNodeVecs, 
+                                                      this.coreNum);
+         while((!isBig || (gid <= this.scheduleThreshold)) && (rGen.nextGen())) {
+             // first get the chosen rootNodes
+             Vector<Vector<ScheduleNode>> rootNodes = rGen.getRootNodes();
+             Vector<Vector<ScheduleNode>> nodes2combine = rGen.getNode2Combine();
+
+             CombinationUtil.CombineGenerator cGen = 
+                 CombinationUtil.allocateCombineGenerator(rootNodes, 
+                         nodes2combine);
+             while((!isBig || (gid <= this.scheduleThreshold)) && (cGen.randomGenE())) {  
+                 boolean implement = true;
+                 /*if(isBig) {
+                     implement = Math.abs(rand.nextInt()) % 100 > generateThreshold;
+                 }*/
+                 if(implement) {
+                     Vector<Vector<CombinationUtil.Combine>> combine = cGen.getCombine();
+                     Vector<ScheduleNode> sNodes = 
+                         SchedulingUtil.generateScheduleGraph(this.state,
+                                 this.scheduleNodes,
+                                 this.scheduleEdges,
+                                 rootNodes, 
+                                 combine, 
+                                 gid++);
+                     this.scheduleGraphs.add(sNodes);
+                     sNodes = null;
+                     combine = null;
+                 } else if(Math.abs(rand.nextInt()) % 100 > skipThreshold){
+                     break;
+                 }
+             }
+             cGen.clear();
+             rootNodes = null;
+             nodes2combine = null;
+         }
+         rGen.clear();
+         sNodeVecs = null;
+      } else if (false) {
+         CombinationUtil.RandomGenerator rGen = 
+               CombinationUtil.allocateRandomGenerator(sNodeVecs, 
+                                                       this.coreNum);
+         // random genenration
+         while((!isBig || (gid <= this.scheduleThreshold)) && (rGen.nextGen())) {
+             Vector<Vector<ScheduleNode>> mapping = rGen.getMapping();
+             boolean implement = true;
+             if(isBig) {
+                 implement = Math.abs(rand.nextInt()) % 100 > generateThreshold;
+             }
+             if(implement) {
+                 Vector<ScheduleNode> sNodes = 
+                     SchedulingUtil.generateScheduleGraph(this.state,
+                         this.scheduleNodes,
+                         this.scheduleEdges,
+                         mapping, 
+                         gid++);
+                 this.scheduleGraphs.add(sNodes);
+                 sNodes = null;
+             }
+             mapping = null;
+         }
+         rGen.clear();
+         sNodeVecs = null;
+      } else {
+         CombinationUtil.RootsGenerator rGen = 
+               CombinationUtil.allocateRootsGenerator(sNodeVecs, 
+                   this.coreNum);
       while((!isBig || (gid <= this.scheduleThreshold)) && (rGen.nextGen())) {
         // first get the chosen rootNodes
         Vector<Vector<ScheduleNode>> rootNodes = rGen.getRootNodes();
@@ -1243,7 +1307,7 @@ public class ScheduleAnalysis {
 
         CombinationUtil.CombineGenerator cGen = 
           CombinationUtil.allocateCombineGenerator(rootNodes, 
-              nodes2combine);
+                                                   nodes2combine);
         while((!isBig || (gid <= this.scheduleThreshold)) && (cGen.nextGen())) {  
           boolean implement = true;
           if(isBig) {
@@ -1271,6 +1335,7 @@ public class ScheduleAnalysis {
       }
       rGen.clear();
       sNodeVecs = null;
+      }
       return isBig;
     }
   }
index 10e8c7ff2a9f8073240d4748952aa9cd980939ff..470c3a0c9b50e4f7392ec056532cad9a331e2a68 100644 (file)
@@ -31,11 +31,10 @@ import Util.Namer;
 public class SchedulingUtil {
     
     public static Vector<ScheduleNode> generateScheduleGraph(State state, 
-                                                            Vector<ScheduleNode> scheduleNodes,
-                                                            Vector<ScheduleEdge> scheduleEdges,
-                                                            Vector<Vector<ScheduleNode>> rootnodes, 
-                                                            Vector<Vector<CombinationUtil.Combine>> combine, 
-                                                            int gid) {
+           Vector<ScheduleNode> scheduleNodes,
+           Vector<ScheduleEdge> scheduleEdges,
+           Vector<Vector<ScheduleNode>> mapping, 
+           int gid) {
        Vector<ScheduleNode> result = new Vector<ScheduleNode>();
 
        // clone the ScheduleNodes
@@ -44,11 +43,78 @@ public class SchedulingUtil {
        Hashtable<ScheduleNode, ScheduleNode> sn2sn = 
            new Hashtable<ScheduleNode, ScheduleNode>();
        cloneScheduleGraph(scheduleNodes,
-                          scheduleEdges,
-                          sn2hash,
-                          sn2sn,
-                          result,
-                          gid);
+               scheduleEdges,
+               sn2hash,
+               sn2sn,
+               result,
+               gid);
+
+       // combine those nodes in combine with corresponding rootnodes
+       for(int i = 0; i < mapping.size(); i++) {
+           Vector<ScheduleNode> sNodes = mapping.elementAt(i);
+           if(sNodes != null) {
+               ScheduleNode rootnode = sNodes.elementAt(0);
+               for(int j = 1; j < sNodes.size(); j++) {
+                   ScheduleNode tocombine = sn2sn.get(sNodes.elementAt(j));
+                   ScheduleNode root = sn2sn.get(rootnode);
+                   ScheduleEdge se = (ScheduleEdge)tocombine.inedges().next();
+                   try {
+                       if(root.equals(((ScheduleNode)se.getSource()))) {
+                           root.mergeSEdge(se);
+                           if(ScheduleEdge.NEWEDGE == se.getType()) {
+                               // As se has been changed into an internal edge inside a ScheduleNode,
+                               // change the source and target of se from original ScheduleNodes into ClassNodes.
+                               se.setTarget(se.getTargetCNode());
+                               //se.setSource(se.getSourceCNode());
+                               //se.getTargetCNode().addEdge(se);
+                               se.getSourceCNode().addEdge(se);
+                           }
+                       } else {
+                           root.mergeSNode(tocombine);
+                       }
+                   } catch(Exception e) {
+                       e.printStackTrace();
+                       System.exit(-1);
+                   }
+                   result.removeElement(tocombine);
+               }
+           }
+       }
+
+       assignCids(result);
+
+       sn2hash.clear();
+       sn2hash = null;
+       sn2sn.clear();
+       sn2sn = null;
+
+       if(state.PRINTSCHEDULING) {
+           String path = state.outputdir + "scheduling_" + gid + ".dot";
+           SchedulingUtil.printScheduleGraph(path, result);
+       }
+
+       return result;
+    }
+
+    public static Vector<ScheduleNode> generateScheduleGraph(State state, 
+           Vector<ScheduleNode> scheduleNodes,
+           Vector<ScheduleEdge> scheduleEdges,
+           Vector<Vector<ScheduleNode>> rootnodes, 
+           Vector<Vector<CombinationUtil.Combine>> combine, 
+           int gid) {
+       Vector<ScheduleNode> result = new Vector<ScheduleNode>();
+
+       // clone the ScheduleNodes
+       Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>> sn2hash = 
+           new Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>>();
+       Hashtable<ScheduleNode, ScheduleNode> sn2sn = 
+           new Hashtable<ScheduleNode, ScheduleNode>();
+       cloneScheduleGraph(scheduleNodes,
+               scheduleEdges,
+               sn2hash,
+               sn2sn,
+               result,
+               gid);
 
        // combine those nodes in combine with corresponding rootnodes
        for(int i = 0; i < combine.size(); i++) {
@@ -80,9 +146,9 @@ public class SchedulingUtil {
                }
            }
        }
-       
+
        assignCids(result);
-       
+
        sn2hash.clear();
        sn2hash = null;
        sn2sn.clear();
@@ -95,13 +161,13 @@ public class SchedulingUtil {
 
        return result;
     }
-    
+
     public static void cloneScheduleGraph(Vector<ScheduleNode> scheduleNodes,
-                                          Vector<ScheduleEdge> scheduleEdges,
-                                          Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>> sn2hash,
-                                          Hashtable<ScheduleNode, ScheduleNode> sn2sn,
-                                          Vector<ScheduleNode> result,
-                                          int gid) {
+           Vector<ScheduleEdge> scheduleEdges,
+           Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>> sn2hash,
+           Hashtable<ScheduleNode, ScheduleNode> sn2sn,
+           Vector<ScheduleNode> result,
+           int gid) {
        for(int i = 0; i < scheduleNodes.size(); i++) {
            Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>();
            ScheduleNode tocopy = scheduleNodes.elementAt(i);
@@ -142,7 +208,7 @@ public class SchedulingUtil {
            targetcn2cn = null;
        }
     }
-    
+
     public static void assignCids(Vector<ScheduleNode> result) {
        Hashtable<Integer, Integer> hcid2cid = new Hashtable<Integer, Integer>();
        int ncid = 0;
@@ -163,57 +229,57 @@ public class SchedulingUtil {
        hcid2cid.clear();
        hcid2cid = null;
     }
-    
+
     //  Organize the scheduleNodes in order of their cid
     public static Vector<Vector<ScheduleNode>> 
     rangeScheduleNodes(Vector<ScheduleNode> scheduleNodes) {
-      try{  
-        Vector<Vector<ScheduleNode>> sNodeVecs = new Vector<Vector<ScheduleNode>>();
-
-        for(int i = 0; i < scheduleNodes.size(); i++) {
-          ScheduleNode tmpn = scheduleNodes.elementAt(i);
-          int tmpcid = tmpn.getCid();
-          int index = 0;
-          for(index = 0; index < sNodeVecs.size(); index++) {
-            if(sNodeVecs.elementAt(index).elementAt(0).getCid() > tmpcid) {
-              // find the place to insert
-              sNodeVecs.insertElementAt(new Vector<ScheduleNode>(), index);
-              /*sNodeVecs.add(sNodeVecs.lastElement());
+       try{  
+           Vector<Vector<ScheduleNode>> sNodeVecs = new Vector<Vector<ScheduleNode>>();
+
+           for(int i = 0; i < scheduleNodes.size(); i++) {
+               ScheduleNode tmpn = scheduleNodes.elementAt(i);
+               int tmpcid = tmpn.getCid();
+               int index = 0;
+               for(index = 0; index < sNodeVecs.size(); index++) {
+                   if(sNodeVecs.elementAt(index).elementAt(0).getCid() > tmpcid) {
+                       // find the place to insert
+                       sNodeVecs.insertElementAt(new Vector<ScheduleNode>(), index);
+                       /*sNodeVecs.add(sNodeVecs.lastElement());
               for(int j = sNodeVecs.size() - 2; j > index; j--) {
                 sNodeVecs.setElementAt(sNodeVecs.elementAt(j - 1), j);
               }
               sNodeVecs.setElementAt(new Vector<ScheduleNode>(), index);*/
-              break;
-            } else if(sNodeVecs.elementAt(index).elementAt(0).getCid() == tmpcid) {
-              break;
-            }
-          }
-          if(index == sNodeVecs.size()) {
-            sNodeVecs.add(new Vector<ScheduleNode>());
-          }
+                       break;
+                   } else if(sNodeVecs.elementAt(index).elementAt(0).getCid() == tmpcid) {
+                       break;
+                   }
+               }
+               if(index == sNodeVecs.size()) {
+                   sNodeVecs.add(new Vector<ScheduleNode>());
+               }
 
-          /*int index = tmpcid;
+               /*int index = tmpcid;
            while(sNodeVecs.size() <= index) {
                sNodeVecs.add(null);
            }
            if(sNodeVecs.elementAt(index) == null) {
                sNodeVecs.setElementAt(new Vector<ScheduleNode>(), index);
            }*/
-          if(!sNodeVecs.elementAt(index).contains(tmpn)) {
-            sNodeVecs.elementAt(index).addElement(tmpn);
-          }
-        }
-
-        return sNodeVecs;
-      } catch(Error e) {
-        System.err.println("Error in rangeScheduleNodes: " + scheduleNodes.size());
-        e.printStackTrace();
-        //System.exit(-1);
-        return null;
-      }
+               if(!sNodeVecs.elementAt(index).contains(tmpn)) {
+                   sNodeVecs.elementAt(index).addElement(tmpn);
+               }
+           }
+
+           return sNodeVecs;
+       } catch(Error e) {
+           System.err.println("Error in rangeScheduleNodes: " + scheduleNodes.size());
+           e.printStackTrace();
+           //System.exit(-1);
+           return null;
+       }
     }
 
-  /*public static int maxDivisor(int l, int r) {
+    /*public static int maxDivisor(int l, int r) {
       int a = l;
       int b = r;
       int c = 0;
@@ -245,630 +311,630 @@ public class SchedulingUtil {
       }
      }*/
 
-  public static boolean isTaskTrigger_flag(FlagExpressionNode fen,
-                                          FlagState fs) {
-    if (fen==null)
-      return true;
-    else if (fen instanceof FlagNode)
-      return fs.get(((FlagNode)fen).getFlag());
-    else
-      switch (((FlagOpNode)fen).getOp().getOp()) {
-      case Operation.LOGIC_AND:
-       return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
-
-      case Operation.LOGIC_OR:
-       return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
-
-      case Operation.LOGIC_NOT:
-       return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs));
-
-      default:
-       return false;
-      }
-  }
-
-  public static void printScheduleGraph(String path, 
-                                       Vector<ScheduleNode> sNodes) {
-    try {
-      File file=new File(path);
-      FileOutputStream dotstream=new FileOutputStream(file,false);
-      PrintWriter output = new java.io.PrintWriter(dotstream, true);
-      output.println("digraph G {");
-      output.println("\tcompound=true;\n");
-      traverseSNodes(output, sNodes);
-      output.println("}\n");
-      output.close();
-    } catch (Exception e) {
-      e.printStackTrace();
-      System.exit(-1);
+    public static boolean isTaskTrigger_flag(FlagExpressionNode fen,
+           FlagState fs) {
+       if (fen==null)
+           return true;
+       else if (fen instanceof FlagNode)
+           return fs.get(((FlagNode)fen).getFlag());
+       else
+           switch (((FlagOpNode)fen).getOp().getOp()) {
+           case Operation.LOGIC_AND:
+               return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
+
+           case Operation.LOGIC_OR:
+               return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
+
+           case Operation.LOGIC_NOT:
+               return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs));
+
+           default:
+               return false;
+           }
     }
-  }
-
-  private static void traverseSNodes(PrintWriter output, 
-                                    Vector<ScheduleNode> sNodes) {
-    //Draw clusters representing ScheduleNodes
-    Iterator it = sNodes.iterator();
-    while (it.hasNext()) {
-      ScheduleNode gn = (ScheduleNode) it.next();
-      Iterator edges = gn.edges();
-      output.println("\tsubgraph " + gn.getLabel() + "{");
-      output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
-      Iterator it_cnodes = gn.getClassNodesIterator();
-      traverseCNodes(output, it_cnodes);
-      it_cnodes = null;
-      //Draw the internal 'new' edges
-      Iterator it_edges =gn.getScheduleEdgesIterator();
-      while(it_edges.hasNext()) {
-       ScheduleEdge se = (ScheduleEdge)it_edges.next();
-       output.print("\t");
-       if(se.getSourceCNode().isclone()) {
-         output.print(se.getSourceCNode().getLabel());
-       } else {
-         if(se.getSourceFState() == null) {
-           output.print(se.getSourceCNode().getClusterLabel());
-         } else {
-           output.print(se.getSourceFState().getLabel());
-         }
-       }
 
-       output.print(" -> ");
-       if(se.isclone()) {
-         if(se.getTargetCNode().isclone()) {
-           output.print(se.getTargetCNode().getLabel());
-         } else {
-           output.print(se.getTargetCNode().getClusterLabel());
-         }
-         output.println(" [label=\"" + se.getLabel() + "\", color=red];");
-       } else {
-         output.print(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, ltail=");
-         if(se.getSourceCNode().isclone()) {
-           output.println(se.getSourceCNode().getLabel() + "];");
-         } else {
-           output.println(se.getSourceCNode().getClusterLabel() + "];");
-         }
-       }
-      }
-      output.println("\t}\n");
-      it_edges = null;
-      //Draw 'new' edges of this ScheduleNode
-      while(edges.hasNext()) {
-       ScheduleEdge se = (ScheduleEdge)edges.next();
-       output.print("\t");
-       if(se.getSourceCNode().isclone()) {
-         output.print(se.getSourceCNode().getLabel());
-       } else {
-         if(se.getSourceFState() == null) {
-           output.print(se.getSourceCNode().getClusterLabel());
-         } else {
-           output.print(se.getSourceFState().getLabel());
-         }
+    public static void printScheduleGraph(String path, 
+           Vector<ScheduleNode> sNodes) {
+       try {
+           File file=new File(path);
+           FileOutputStream dotstream=new FileOutputStream(file,false);
+           PrintWriter output = new java.io.PrintWriter(dotstream, true);
+           output.println("digraph G {");
+           output.println("\tcompound=true;\n");
+           traverseSNodes(output, sNodes);
+           output.println("}\n");
+           output.close();
+       } catch (Exception e) {
+           e.printStackTrace();
+           System.exit(-1);
        }
+    }
+
+    private static void traverseSNodes(PrintWriter output, 
+           Vector<ScheduleNode> sNodes) {
+       //Draw clusters representing ScheduleNodes
+       Iterator it = sNodes.iterator();
+       while (it.hasNext()) {
+           ScheduleNode gn = (ScheduleNode) it.next();
+           Iterator edges = gn.edges();
+           output.println("\tsubgraph " + gn.getLabel() + "{");
+           output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
+           Iterator it_cnodes = gn.getClassNodesIterator();
+           traverseCNodes(output, it_cnodes);
+           it_cnodes = null;
+           //Draw the internal 'new' edges
+           Iterator it_edges =gn.getScheduleEdgesIterator();
+           while(it_edges.hasNext()) {
+               ScheduleEdge se = (ScheduleEdge)it_edges.next();
+               output.print("\t");
+               if(se.getSourceCNode().isclone()) {
+                   output.print(se.getSourceCNode().getLabel());
+               } else {
+                   if(se.getSourceFState() == null) {
+                       output.print(se.getSourceCNode().getClusterLabel());
+                   } else {
+                       output.print(se.getSourceFState().getLabel());
+                   }
+               }
 
-       output.print(" -> ");
-       if(se.isclone()) {
-         if(se.getTargetCNode().isclone()) {
-           output.print(se.getTargetCNode().getLabel());
-         } else {
-           output.print(se.getTargetCNode().getClusterLabel());
-         }
-         output.println(" [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
-       } else {
-         output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
+               output.print(" -> ");
+               if(se.isclone()) {
+                   if(se.getTargetCNode().isclone()) {
+                       output.print(se.getTargetCNode().getLabel());
+                   } else {
+                       output.print(se.getTargetCNode().getClusterLabel());
+                   }
+                   output.println(" [label=\"" + se.getLabel() + "\", color=red];");
+               } else {
+                   output.print(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, ltail=");
+                   if(se.getSourceCNode().isclone()) {
+                       output.println(se.getSourceCNode().getLabel() + "];");
+                   } else {
+                       output.println(se.getSourceCNode().getClusterLabel() + "];");
+                   }
+               }
+           }
+           output.println("\t}\n");
+           it_edges = null;
+           //Draw 'new' edges of this ScheduleNode
+           while(edges.hasNext()) {
+               ScheduleEdge se = (ScheduleEdge)edges.next();
+               output.print("\t");
+               if(se.getSourceCNode().isclone()) {
+                   output.print(se.getSourceCNode().getLabel());
+               } else {
+                   if(se.getSourceFState() == null) {
+                       output.print(se.getSourceCNode().getClusterLabel());
+                   } else {
+                       output.print(se.getSourceFState().getLabel());
+                   }
+               }
+
+               output.print(" -> ");
+               if(se.isclone()) {
+                   if(se.getTargetCNode().isclone()) {
+                       output.print(se.getTargetCNode().getLabel());
+                   } else {
+                       output.print(se.getTargetCNode().getClusterLabel());
+                   }
+                   output.println(" [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
+               } else {
+                   output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed];");
+               }
+           }
+           edges = null;
        }
-      }
-      edges = null;
-    }
-    it = null;
-  }
-
-  private static void traverseCNodes(PrintWriter output, 
-                                    Iterator it) {
-    //Draw clusters representing ClassNodes
-    while (it.hasNext()) {
-      ClassNode gn = (ClassNode) it.next();
-      if(gn.isclone()) {
-       output.println("\t\t" + gn.getLabel() + " [style=dashed, label=\"" + gn.getTextLabel() + "\", shape=box];");
-      } else {
-       output.println("\tsubgraph " + gn.getClusterLabel() + "{");
-       output.println("\t\tstyle=dashed;");
-       output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
-       traverseFlagStates(output, gn.getFlagStates());
-       output.println("\t}\n");
-      }
+       it = null;
     }
-  }
-
-  private static void traverseFlagStates(PrintWriter output, 
-                                        Collection nodes) {
-    Set cycleset=GraphNode.findcycles(nodes);
-    Vector namers=new Vector();
-    namers.add(new Namer());
-    namers.add(new Allocations());
-
-    Iterator it = nodes.iterator();
-    while (it.hasNext()) {
-      GraphNode gn = (GraphNode) it.next();
-      Iterator edges = gn.edges();
-      String label = "";
-      String dotnodeparams="";
-
-      for(int i=0; i<namers.size(); i++) {
-       Namer name=(Namer) namers.get(i);
-       String newlabel=name.nodeLabel(gn);
-       String newparams=name.nodeOption(gn);
-
-       if (!newlabel.equals("") && !label.equals("")) {
-         label+=", ";
-       }
-       if (!newparams.equals("")) {
-         dotnodeparams+=", " + name.nodeOption(gn);
+
+    private static void traverseCNodes(PrintWriter output, 
+           Iterator it) {
+       //Draw clusters representing ClassNodes
+       while (it.hasNext()) {
+           ClassNode gn = (ClassNode) it.next();
+           if(gn.isclone()) {
+               output.println("\t\t" + gn.getLabel() + " [style=dashed, label=\"" + gn.getTextLabel() + "\", shape=box];");
+           } else {
+               output.println("\tsubgraph " + gn.getClusterLabel() + "{");
+               output.println("\t\tstyle=dashed;");
+               output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";");
+               traverseFlagStates(output, gn.getFlagStates());
+               output.println("\t}\n");
+           }
        }
-       label+=name.nodeLabel(gn);
-      }
-      label += ":[" + ((FlagState)gn).getExeTime() + "]";
-
-      if (!gn.merge)
-       output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];");
-
-      if (!gn.merge)
-       while (edges.hasNext()) {
-         Edge edge = (Edge) edges.next();
-         GraphNode node = edge.getTarget();
-         if (nodes.contains(node)) {
-             Iterator nodeit=nonmerge(node, nodes).iterator();
-           for(; nodeit.hasNext();) {
-             GraphNode node2=(GraphNode)nodeit.next();
-             String edgelabel = "";
-             String edgedotnodeparams="";
-
-             for(int i=0; i<namers.size(); i++) {
+    }
+
+    private static void traverseFlagStates(PrintWriter output, 
+           Collection nodes) {
+       Set cycleset=GraphNode.findcycles(nodes);
+       Vector namers=new Vector();
+       namers.add(new Namer());
+       namers.add(new Allocations());
+
+       Iterator it = nodes.iterator();
+       while (it.hasNext()) {
+           GraphNode gn = (GraphNode) it.next();
+           Iterator edges = gn.edges();
+           String label = "";
+           String dotnodeparams="";
+
+           for(int i=0; i<namers.size(); i++) {
                Namer name=(Namer) namers.get(i);
-               String newlabel=name.edgeLabel(edge);
-               String newoption=name.edgeOption(edge);
-               if (!newlabel.equals("")&& !edgelabel.equals(""))
-                 edgelabel+=", ";
-               edgelabel+=newlabel;
-               if (!newoption.equals(""))
-                 edgedotnodeparams+=", "+newoption;
-             }
-             edgelabel+=":[" + ((FEdge)edge).getExeTime() + "]";
-             edgelabel+=":(" + ((FEdge)edge).getProbability() + "%)";
-             Hashtable<ClassDescriptor, NewObjInfo> hashtable = ((FEdge)edge).getNewObjInfoHashtable();
-             if(hashtable != null) {
-               Set<ClassDescriptor> keys = hashtable.keySet();
-               Iterator it_keys = keys.iterator();
-               while(it_keys.hasNext()) {
-                 ClassDescriptor cd = (ClassDescriptor)it_keys.next();
-                 NewObjInfo noi = hashtable.get(cd);
-                 edgelabel += ":{ class " + cd.getSymbol() + " | " + noi.getNewRate() + " | (" + noi.getProbability() + "%) }";
+               String newlabel=name.nodeLabel(gn);
+               String newparams=name.nodeOption(gn);
+
+               if (!newlabel.equals("") && !label.equals("")) {
+                   label+=", ";
                }
-               keys = null;
-               it_keys = null;
-             }
-             output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];");
+               if (!newparams.equals("")) {
+                   dotnodeparams+=", " + name.nodeOption(gn);
+               }
+               label+=name.nodeLabel(gn);
            }
-           nodeit = null;
-         }
+           label += ":[" + ((FlagState)gn).getExeTime() + "]";
+
+           if (!gn.merge)
+               output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];");
+
+           if (!gn.merge)
+               while (edges.hasNext()) {
+                   Edge edge = (Edge) edges.next();
+                   GraphNode node = edge.getTarget();
+                   if (nodes.contains(node)) {
+                       Iterator nodeit=nonmerge(node, nodes).iterator();
+                       for(; nodeit.hasNext();) {
+                           GraphNode node2=(GraphNode)nodeit.next();
+                           String edgelabel = "";
+                           String edgedotnodeparams="";
+
+                           for(int i=0; i<namers.size(); i++) {
+                               Namer name=(Namer) namers.get(i);
+                               String newlabel=name.edgeLabel(edge);
+                               String newoption=name.edgeOption(edge);
+                               if (!newlabel.equals("")&& !edgelabel.equals(""))
+                                   edgelabel+=", ";
+                               edgelabel+=newlabel;
+                               if (!newoption.equals(""))
+                                   edgedotnodeparams+=", "+newoption;
+                           }
+                           edgelabel+=":[" + ((FEdge)edge).getExeTime() + "]";
+                           edgelabel+=":(" + ((FEdge)edge).getProbability() + "%)";
+                           Hashtable<ClassDescriptor, NewObjInfo> hashtable = ((FEdge)edge).getNewObjInfoHashtable();
+                           if(hashtable != null) {
+                               Set<ClassDescriptor> keys = hashtable.keySet();
+                               Iterator it_keys = keys.iterator();
+                               while(it_keys.hasNext()) {
+                                   ClassDescriptor cd = (ClassDescriptor)it_keys.next();
+                                   NewObjInfo noi = hashtable.get(cd);
+                                   edgelabel += ":{ class " + cd.getSymbol() + " | " + noi.getNewRate() + " | (" + noi.getProbability() + "%) }";
+                               }
+                               keys = null;
+                               it_keys = null;
+                           }
+                           output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];");
+                       }
+                       nodeit = null;
+                   }
+               }
+           edges = null;
        }
-      edges = null;
+       cycleset = null;
+       namers = null;
+       it = null;
     }
-    cycleset = null;
-    namers = null;
-    it = null;
-  }
-
-  private static Set nonmerge(GraphNode gn, 
-                             Collection nodes) {
-    HashSet newset=new HashSet();
-    HashSet toprocess=new HashSet();
-    toprocess.add(gn);
-    while(!toprocess.isEmpty()) {
-      GraphNode gn2=(GraphNode)toprocess.iterator().next();
-      toprocess.remove(gn2);
-      if (!gn2.merge)
-       newset.add(gn2);
-      else {
-       Iterator edges = gn2.edges();
-       while (edges.hasNext()) {
-         Edge edge = (Edge) edges.next();
-         GraphNode node = edge.getTarget();
-         if (!newset.contains(node)&&nodes.contains(node))
-           toprocess.add(node);
+
+    private static Set nonmerge(GraphNode gn, 
+           Collection nodes) {
+       HashSet newset=new HashSet();
+       HashSet toprocess=new HashSet();
+       toprocess.add(gn);
+       while(!toprocess.isEmpty()) {
+           GraphNode gn2=(GraphNode)toprocess.iterator().next();
+           toprocess.remove(gn2);
+           if (!gn2.merge)
+               newset.add(gn2);
+           else {
+               Iterator edges = gn2.edges();
+               while (edges.hasNext()) {
+                   Edge edge = (Edge) edges.next();
+                   GraphNode node = edge.getTarget();
+                   if (!newset.contains(node)&&nodes.contains(node))
+                       toprocess.add(node);
+               }
+               edges = null;
+           }
        }
-       edges = null;
-      }
+       toprocess = null;
+       return newset;
     }
-    toprocess = null;
-    return newset;
-  }
-
-  public static void printSimulationResult(String path, 
-                                          long time, 
-                                          int coreNum, 
-                                          Vector<CheckPoint> checkpoints) {
-    try {
-      File file=new File(path);
-      FileOutputStream dotstream=new FileOutputStream(file,false);
-      PrintWriter output = new java.io.PrintWriter(dotstream, true);
-      output.println("digraph simulation{");
-      output.print("\t");
-      output.println("node [shape=plaintext];");
-      output.print("\t");
-      output.println("edge [dir=none];");
-      output.print("\t");
-      output.println("ranksep=.05;");
-      output.println();
-      output.print("\t");
-      int j = 0;
-
-      // the capital line
-      output.print("{rank=source; \"Time\"; ");
-      for(j = 0; j < coreNum; j++) {
-       output.print("\"core " + j + "\"; ");
-      }
-      output.println("}");
-      // time coordinate nodes
-      Vector<String> timeNodes = new Vector<String>();
-      String[] lastTaskNodes = new String[coreNum];
-      String[] lastTasks = new String[coreNum];
-      boolean[] isTaskFinish = new boolean[coreNum];
-      for(j = 0; j < coreNum; j++) {
-       lastTaskNodes[j] = "first";
-       isTaskFinish[j] = true;
-       lastTasks[j] = "";
-      }
-      timeNodes.add("0");
-      for(j = 0; j < checkpoints.size(); j++) {
-       CheckPoint tcp = checkpoints.elementAt(j);
-       Hashtable<Integer, String> tmplastTasks = new Hashtable<Integer, String>();
-       Vector<Integer> tmpisTaskFinish = new Vector<Integer>();
-       Vector<Integer> tmpisset = new Vector<Integer>();
-       String tnode = String.valueOf(tcp.getTimepoint());
-       if(!timeNodes.contains(tnode)) {
-         timeNodes.add(tnode);
-       }
-       Vector<Action> actions = tcp.getActions();
-       Hashtable<String, StringBuffer> tmpTaskNodes = new Hashtable<String, StringBuffer>();
-       for(int i = 0; i < actions.size(); i++) {
-         Action taction = actions.elementAt(i);
-         int cNum = taction.getCoreNum();
-         if(!tmplastTasks.containsKey(cNum)) {
-           tmplastTasks.put(cNum, lastTasks[cNum]);
-         }
-         if(!(tmpisset.contains(cNum)) 
-                 && (isTaskFinish[cNum]) 
-                 && !(tmpisTaskFinish.contains(cNum))) {
-           tmpisTaskFinish.add(cNum);  // records those with task finished the first time visit it
-         }
-         String tmpTaskNode = "\"" + tnode + "core" + cNum + "\"";
-         StringBuffer tmpLabel = null;
-         boolean isfirst = false;
-         if(!tmpTaskNodes.containsKey(tmpTaskNode)) {
-           tmpTaskNodes.put(tmpTaskNode, new StringBuffer(tnode + ":"));
-           isfirst = true;
-         }
-         tmpLabel = tmpTaskNodes.get(tmpTaskNode);
-         switch(taction.getType()) {
-         case Action.ADDOBJ: {
-           if(!isfirst) {
-             tmpLabel.append("\\n");
+
+    public static void printSimulationResult(String path, 
+           long time, 
+           int coreNum, 
+           Vector<CheckPoint> checkpoints) {
+       try {
+           File file=new File(path);
+           FileOutputStream dotstream=new FileOutputStream(file,false);
+           PrintWriter output = new java.io.PrintWriter(dotstream, true);
+           output.println("digraph simulation{");
+           output.print("\t");
+           output.println("node [shape=plaintext];");
+           output.print("\t");
+           output.println("edge [dir=none];");
+           output.print("\t");
+           output.println("ranksep=.05;");
+           output.println();
+           output.print("\t");
+           int j = 0;
+
+           // the capital line
+           output.print("{rank=source; \"Time\"; ");
+           for(j = 0; j < coreNum; j++) {
+               output.print("\"core " + j + "\"; ");
            }
-           tmpLabel.append("(" + taction.getTransObj().getSymbol() + ")arrives;");
-           if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
-             output.print("\t");
-             if(lastTaskNodes[cNum].equals("first")) {
-               output.print("\"core " + cNum + "\"->" + tmpTaskNode);
-             } else {
-               output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
-             }
-             if(tmpisTaskFinish.contains(cNum)) {
-               output.print(" [style=invis]");
-             }
-             output.println(";");
-             lastTaskNodes[cNum] = tmpTaskNode;
+           output.println("}");
+           // time coordinate nodes
+           Vector<String> timeNodes = new Vector<String>();
+           String[] lastTaskNodes = new String[coreNum];
+           String[] lastTasks = new String[coreNum];
+           boolean[] isTaskFinish = new boolean[coreNum];
+           for(j = 0; j < coreNum; j++) {
+               lastTaskNodes[j] = "first";
+               isTaskFinish[j] = true;
+               lastTasks[j] = "";
            }
-           break;
-         }
+           timeNodes.add("0");
+           for(j = 0; j < checkpoints.size(); j++) {
+               CheckPoint tcp = checkpoints.elementAt(j);
+               Hashtable<Integer, String> tmplastTasks = new Hashtable<Integer, String>();
+               Vector<Integer> tmpisTaskFinish = new Vector<Integer>();
+               Vector<Integer> tmpisset = new Vector<Integer>();
+               String tnode = String.valueOf(tcp.getTimepoint());
+               if(!timeNodes.contains(tnode)) {
+                   timeNodes.add(tnode);
+               }
+               Vector<Action> actions = tcp.getActions();
+               Hashtable<String, StringBuffer> tmpTaskNodes = new Hashtable<String, StringBuffer>();
+               for(int i = 0; i < actions.size(); i++) {
+                   Action taction = actions.elementAt(i);
+                   int cNum = taction.getCoreNum();
+                   if(!tmplastTasks.containsKey(cNum)) {
+                       tmplastTasks.put(cNum, lastTasks[cNum]);
+                   }
+                   if(!(tmpisset.contains(cNum)) 
+                           && (isTaskFinish[cNum]) 
+                           && !(tmpisTaskFinish.contains(cNum))) {
+                       tmpisTaskFinish.add(cNum);  // records those with task finished the first time visit it
+                   }
+                   String tmpTaskNode = "\"" + tnode + "core" + cNum + "\"";
+                   StringBuffer tmpLabel = null;
+                   boolean isfirst = false;
+                   if(!tmpTaskNodes.containsKey(tmpTaskNode)) {
+                       tmpTaskNodes.put(tmpTaskNode, new StringBuffer(tnode + ":"));
+                       isfirst = true;
+                   }
+                   tmpLabel = tmpTaskNodes.get(tmpTaskNode);
+                   switch(taction.getType()) {
+                   case Action.ADDOBJ: {
+                       if(!isfirst) {
+                           tmpLabel.append("\\n");
+                       }
+                       tmpLabel.append("(" + taction.getTransObj().getSymbol() + ")arrives;");
+                       if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
+                           output.print("\t");
+                           if(lastTaskNodes[cNum].equals("first")) {
+                               output.print("\"core " + cNum + "\"->" + tmpTaskNode);
+                           } else {
+                               output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
+                           }
+                           if(tmpisTaskFinish.contains(cNum)) {
+                               output.print(" [style=invis]");
+                           }
+                           output.println(";");
+                           lastTaskNodes[cNum] = tmpTaskNode;
+                       }
+                       break;
+                   }
 
-         case Action.TASKFINISH: {
-           if(!isfirst) {
-             tmpLabel.append("\\n");
-           }
-           tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
-           /*Vector<Integer> taskparams = taction.getTaskParams();
+                   case Action.TASKFINISH: {
+                       if(!isfirst) {
+                           tmpLabel.append("\\n");
+                       }
+                       tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
+                       /*Vector<Integer> taskparams = taction.getTaskParams();
            for(int ii = 0; ii < taskparams.size(); ii++) {
                tmpLabel.append(taskparams.elementAt(ii));
                if(ii < taskparams.size() - 1) {
                    tmpLabel.append(",");
                }
            }*/
-           tmpLabel.append(")>finishes;");
-           if(!(lastTaskNodes[cNum].equals("first"))) {
-             if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
-               output.print("\t");
-               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
-               lastTaskNodes[cNum] = tmpTaskNode;
-             }
-             if(tmpisset.contains(cNum)) {
-               isTaskFinish[cNum] &= true;
-             } else {
-               isTaskFinish[cNum] = true;
-               tmpisset.add(cNum);
-             }
-             lastTasks[cNum] = "";
-           } else {
-             throw new Exception("Error: unexpected task finish");
-           }
-           break;
-         }
+                       tmpLabel.append(")>finishes;");
+                       if(!(lastTaskNodes[cNum].equals("first"))) {
+                           if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
+                               output.print("\t");
+                               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
+                               lastTaskNodes[cNum] = tmpTaskNode;
+                           }
+                           if(tmpisset.contains(cNum)) {
+                               isTaskFinish[cNum] &= true;
+                           } else {
+                               isTaskFinish[cNum] = true;
+                               tmpisset.add(cNum);
+                           }
+                           lastTasks[cNum] = "";
+                       } else {
+                           throw new Exception("Error: unexpected task finish");
+                       }
+                       break;
+                   }
 
-         case Action.TFWITHOBJ: {
-           if(!isfirst) {
-             tmpLabel.append("\\n");
-           }
-           tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
-           /*Vector<Integer> taskparams = taction.getTaskParams();
+                   case Action.TFWITHOBJ: {
+                       if(!isfirst) {
+                           tmpLabel.append("\\n");
+                       }
+                       tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
+                       /*Vector<Integer> taskparams = taction.getTaskParams();
            for(int ii = 0; ii < taskparams.size(); ii++) {
                tmpLabel.append(taskparams.elementAt(ii));
                if(ii < taskparams.size() - 1) {
                    tmpLabel.append(",");
                }
            }*/
-           tmpLabel.append(")>finishes;");
-           Iterator<Entry<ClassDescriptor, Integer>> it_entry = (Iterator<Entry<ClassDescriptor, Integer>>)taction.getNObjs().entrySet().iterator();
-           while(it_entry.hasNext()) {
-             Entry<ClassDescriptor, Integer> entry = it_entry.next();
-             tmpLabel.append(entry.getValue() + "(" + entry.getKey().getSymbol() + ")");
-             if(it_entry.hasNext()) {
-               tmpLabel.append(",");
-             } else {
-               tmpLabel.append(";");
-             }
-             entry = null;
-           }
-           it_entry = null;
-           if(!(lastTaskNodes[cNum].equals("first"))) {
-             if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
-               output.print("\t");
-               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
-               lastTaskNodes[cNum] = tmpTaskNode;
-             }
-             if(tmpisset.contains(cNum)) {
-               isTaskFinish[cNum] &= true;
-             } else {
-               isTaskFinish[cNum] = true;
-               tmpisset.add(cNum);
-             }
-             lastTasks[cNum] = "";
-           } else {
-             throw new Exception("Error: unexpected task finish");
-           }
-           break;
-         }
+                       tmpLabel.append(")>finishes;");
+                       Iterator<Entry<ClassDescriptor, Integer>> it_entry = (Iterator<Entry<ClassDescriptor, Integer>>)taction.getNObjs().entrySet().iterator();
+                       while(it_entry.hasNext()) {
+                           Entry<ClassDescriptor, Integer> entry = it_entry.next();
+                           tmpLabel.append(entry.getValue() + "(" + entry.getKey().getSymbol() + ")");
+                           if(it_entry.hasNext()) {
+                               tmpLabel.append(",");
+                           } else {
+                               tmpLabel.append(";");
+                           }
+                           entry = null;
+                       }
+                       it_entry = null;
+                       if(!(lastTaskNodes[cNum].equals("first"))) {
+                           if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
+                               output.print("\t");
+                               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
+                               lastTaskNodes[cNum] = tmpTaskNode;
+                           }
+                           if(tmpisset.contains(cNum)) {
+                               isTaskFinish[cNum] &= true;
+                           } else {
+                               isTaskFinish[cNum] = true;
+                               tmpisset.add(cNum);
+                           }
+                           lastTasks[cNum] = "";
+                       } else {
+                           throw new Exception("Error: unexpected task finish");
+                       }
+                       break;
+                   }
 
-         case Action.TASKSTART: {
-           if(!isfirst) {
-             tmpLabel.append("\\n");
-           }
-           tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
-           /*Vector<Integer> taskparams = taction.getTaskParams();
+                   case Action.TASKSTART: {
+                       if(!isfirst) {
+                           tmpLabel.append("\\n");
+                       }
+                       tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
+                       /*Vector<Integer> taskparams = taction.getTaskParams();
            for(int ii = 0; ii < taskparams.size(); ii++) {
                tmpLabel.append(taskparams.elementAt(ii));
                if(ii < taskparams.size() - 1) {
                    tmpLabel.append(",");
                }
            }*/
-           tmpLabel.append(")>starts;");
-           lastTasks[cNum] = taction.getTd().getSymbol();
-
-           if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
-             output.print("\t");
-             if(lastTaskNodes[cNum].equals("first")) {
-               output.print("\"core " + cNum + "\"->" + tmpTaskNode);
-             } else {
-               output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
-             }
-             if(tmpisTaskFinish.contains(cNum)) {
-               output.print(" [style=invis]");
-             }
-             output.println(";");
-             lastTaskNodes[cNum] = tmpTaskNode;
-           }
-           isTaskFinish[cNum] &= false;
-           break;
-         }
+                       tmpLabel.append(")>starts;");
+                       lastTasks[cNum] = taction.getTd().getSymbol();
+
+                       if (!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
+                           output.print("\t");
+                           if(lastTaskNodes[cNum].equals("first")) {
+                               output.print("\"core " + cNum + "\"->" + tmpTaskNode);
+                           } else {
+                               output.print(lastTaskNodes[cNum] + "->" + tmpTaskNode);
+                           }
+                           if(tmpisTaskFinish.contains(cNum)) {
+                               output.print(" [style=invis]");
+                           }
+                           output.println(";");
+                           lastTaskNodes[cNum] = tmpTaskNode;
+                       }
+                       isTaskFinish[cNum] &= false;
+                       break;
+                   }
 
-         case Action.TASKABORT: {
-           if(!isfirst) {
-             tmpLabel.append("\\n");
-           }
-           tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
-           /*Vector<Integer> taskparams = taction.getTaskParams();
+                   case Action.TASKABORT: {
+                       if(!isfirst) {
+                           tmpLabel.append("\\n");
+                       }
+                       tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
+                       /*Vector<Integer> taskparams = taction.getTaskParams();
            for(int ii = 0; ii < taskparams.size(); ii++) {
                tmpLabel.append(taskparams.elementAt(ii));
                if(ii < taskparams.size() - 1) {
                    tmpLabel.append(",");
                }
            }*/
-           tmpLabel.append(")>aborts;");
-           if(!(lastTaskNodes[cNum].equals("first")) &&
-              (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
-             if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
-               output.print("\t");
-               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
-               lastTaskNodes[cNum] = tmpTaskNode;
-             }
-             if(tmpisset.contains(cNum)) {
-               isTaskFinish[cNum] &= true;
-             } else {
-               isTaskFinish[cNum] = true;
-               tmpisset.add(cNum);
-             }
-             lastTasks[cNum] = "";
-           } else {
-             throw new Exception("Error: unexpected task aborts");
-           }
-           break;
-         }
+                       tmpLabel.append(")>aborts;");
+                       if(!(lastTaskNodes[cNum].equals("first")) &&
+                               (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
+                           if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
+                               output.print("\t");
+                               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
+                               lastTaskNodes[cNum] = tmpTaskNode;
+                           }
+                           if(tmpisset.contains(cNum)) {
+                               isTaskFinish[cNum] &= true;
+                           } else {
+                               isTaskFinish[cNum] = true;
+                               tmpisset.add(cNum);
+                           }
+                           lastTasks[cNum] = "";
+                       } else {
+                           throw new Exception("Error: unexpected task aborts");
+                       }
+                       break;
+                   }
 
-         case Action.TASKREMOVE: {
-           if(!isfirst) {
-             tmpLabel.append("\\n");
-           }
-           tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
-           /*Vector<Integer> taskparams = taction.getTaskParams();
+                   case Action.TASKREMOVE: {
+                       if(!isfirst) {
+                           tmpLabel.append("\\n");
+                       }
+                       tmpLabel.append("<" + taction.getTd().getSymbol() + "(");
+                       /*Vector<Integer> taskparams = taction.getTaskParams();
            for(int ii = 0; ii < taskparams.size(); ii++) {
                tmpLabel.append(taskparams.elementAt(ii));
                if(ii < taskparams.size() - 1) {
                    tmpLabel.append(",");
                }
            }*/
-           tmpLabel.append(")>removes;");
-           if(!(lastTaskNodes[cNum].equals("first")) &&
-              (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
-             if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
+                       tmpLabel.append(")>removes;");
+                       if(!(lastTaskNodes[cNum].equals("first")) &&
+                               (tmplastTasks.get(cNum).equals(taction.getTd().getSymbol()))) {
+                           if(!(lastTaskNodes[cNum].equals(tmpTaskNode))) {
+                               output.print("\t");
+                               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
+                               lastTaskNodes[cNum] = tmpTaskNode;
+                           }
+                           if(tmpisset.contains(cNum)) {
+                               isTaskFinish[cNum] &= true;
+                           } else {
+                               isTaskFinish[cNum] = true;
+                               tmpisset.add(cNum);
+                           }
+                           lastTasks[cNum] = "";
+                       } else {
+                           throw new Exception("Error: unexpected task remove");
+                       }
+                       break;
+                   }
+                   }
+               }
+               Enumeration<String> keys = tmpTaskNodes.keys();
+               while(keys.hasMoreElements()) {
+                   String tmpTaskNode = keys.nextElement();
+                   output.print("\t");
+                   output.println(tmpTaskNode + "[label=\"" + tmpTaskNodes.get(tmpTaskNode).toString() + "\"]");
+               }
                output.print("\t");
-               output.println(lastTaskNodes[cNum] + "->" + tmpTaskNode + ";");
-               lastTaskNodes[cNum] = tmpTaskNode;
-             }
-             if(tmpisset.contains(cNum)) {
-               isTaskFinish[cNum] &= true;
-             } else {
-               isTaskFinish[cNum] = true;
-               tmpisset.add(cNum);
-             }
-             lastTasks[cNum] = "";
-           } else {
-             throw new Exception("Error: unexpected task remove");
+               output.print("{rank=same; rankdir=LR; " + tnode + "; ");
+               keys = tmpTaskNodes.keys();
+               while(keys.hasMoreElements()) {
+                   String tmpTaskNode = keys.nextElement();
+                   output.print(tmpTaskNode);
+                   output.print("; ");
+               }
+               keys = null;
+               output.println("}");
+               output.print("\t");
+               tmplastTasks = null;
+               tmpisTaskFinish = null;
+               tmpisset = null;
+               actions = null;
+               tmpTaskNodes = null;
+           }
+           output.print("\t");
+           output.print("\t");
+           long prev = Long.parseLong(timeNodes.elementAt(0));
+           long next = 0;
+           long max = 0;
+           long max2 = 0;
+           for(j = 1; j < timeNodes.size(); j++) {
+               next = Long.parseLong(timeNodes.elementAt(j));
+               long delta = next - prev;
+               if(max < delta) {
+                   max2 = max;
+                   max = delta;
+               } else if((max != delta) && (max2 < delta)) {
+                   max2 = delta;
+               }
+               prev = next;
+           }
+           if(max2 == 0) {
+               max2 = 1;
+           } else if(max/max2 > 100) {
+               max2 = max/100;
+           }
+           output.println("\"Time\"->" + timeNodes.elementAt(0) + "[style=invis];");
+           prev = Long.parseLong(timeNodes.elementAt(0));
+           next = 0;
+           for(j = 1; j < timeNodes.size(); j++) {
+               next = Long.parseLong(timeNodes.elementAt(j));
+               if(next - prev > max2) {
+                   do {
+                       output.print(prev + "->");
+                       prev += max2;
+                   } while(next - prev > max2);
+                   output.println(next + ";");
+               } else {
+                   output.println("{rank=same; rankdir=LR; " + prev + "; " + next + "}");
+                   output.println(prev + "->" + next + "[style=invis];");
+               }
+               prev = next;
            }
-           break;
-         }
-         }
-       }
-       Enumeration<String> keys = tmpTaskNodes.keys();
-       while(keys.hasMoreElements()) {
-         String tmpTaskNode = keys.nextElement();
-         output.print("\t");
-         output.println(tmpTaskNode + "[label=\"" + tmpTaskNodes.get(tmpTaskNode).toString() + "\"]");
-       }
-       output.print("\t");
-       output.print("{rank=same; rankdir=LR; " + tnode + "; ");
-       keys = tmpTaskNodes.keys();
-       while(keys.hasMoreElements()) {
-         String tmpTaskNode = keys.nextElement();
-         output.print(tmpTaskNode);
-         output.print("; ");
-       }
-       keys = null;
-       output.println("}");
-       output.print("\t");
-       tmplastTasks = null;
-       tmpisTaskFinish = null;
-       tmpisset = null;
-       actions = null;
-       tmpTaskNodes = null;
-      }
-      output.print("\t");
-      output.print("\t");
-      long prev = Long.parseLong(timeNodes.elementAt(0));
-      long next = 0;
-      long max = 0;
-      long max2 = 0;
-      for(j = 1; j < timeNodes.size(); j++) {
-       next = Long.parseLong(timeNodes.elementAt(j));
-       long delta = next - prev;
-       if(max < delta) {
-         max2 = max;
-         max = delta;
-       } else if((max != delta) && (max2 < delta)) {
-         max2 = delta;
-       }
-       prev = next;
-      }
-      if(max2 == 0) {
-       max2 = 1;
-      } else if(max/max2 > 100) {
-       max2 = max/100;
-      }
-      output.println("\"Time\"->" + timeNodes.elementAt(0) + "[style=invis];");
-      prev = Long.parseLong(timeNodes.elementAt(0));
-      next = 0;
-      for(j = 1; j < timeNodes.size(); j++) {
-       next = Long.parseLong(timeNodes.elementAt(j));
-       if(next - prev > max2) {
-         do {
-           output.print(prev + "->");
-           prev += max2;
-         } while(next - prev > max2);
-         output.println(next + ";");
-       } else {
-         output.println("{rank=same; rankdir=LR; " + prev + "; " + next + "}");
-         output.println(prev + "->" + next + "[style=invis];");
-       }
-       prev = next;
-      }
 
-      /*for(j = 0; j < time; j++) {
+           /*for(j = 0; j < time; j++) {
          output.print(j + "->");
          }
          output.println(timeNodes.lastElement() + ";");*/
-      output.println("}");
-      output.close();
-      timeNodes = null;
-      lastTaskNodes = null;
-      lastTasks = null;
-      isTaskFinish = null;
-    } catch (Exception e) {
-      e.printStackTrace();
-      System.exit(-1);
+           output.println("}");
+           output.close();
+           timeNodes = null;
+           lastTaskNodes = null;
+           lastTasks = null;
+           isTaskFinish = null;
+       } catch (Exception e) {
+           e.printStackTrace();
+           System.exit(-1);
+       }
+    }
+
+    public static void printCriticalPath(String path,
+           Vector<SimExecutionEdge> criticalPath) {
+       try {
+           File file=new File(path);
+           FileOutputStream dotstream=new FileOutputStream(file,false);
+           PrintWriter output = new java.io.PrintWriter(dotstream, true);
+           output.println("digraph simulation{");
+           output.print("\t");
+           output.println("node [shape=plaintext];");
+           output.print("\t");
+           output.println("edge [dir=none];");
+           output.print("\t");
+           output.println("ranksep=.05;");
+           output.println();
+           output.print("\t");
+           Vector<SimExecutionNode> nodes = new Vector<SimExecutionNode>();
+           String label = "";
+           String dotnodeparams="";
+
+           for(int i = 0; i < criticalPath.size(); i++) {
+               SimExecutionEdge seedge = criticalPath.elementAt(i);
+               SimExecutionNode startnode = (SimExecutionNode)seedge.getSource();
+               SimExecutionNode endnode = (SimExecutionNode)seedge.getTarget();
+               if(!nodes.contains(startnode)) {
+                   label = startnode.getCoreNum() + ":" + startnode.getTimepoint();
+                   output.println("\t" + startnode.getLabel() + " [label=\"" 
+                           + label + "\" ];");
+                   nodes.addElement(startnode);
+               }
+               if(!nodes.contains(endnode)) {
+                   label = endnode.getCoreNum() + ":" + endnode.getTimepoint();
+                   output.println("\t" + endnode.getLabel() + " [label=\"" 
+                           + label + "\" ];");
+                   nodes.addElement(endnode);
+               }
+               output.println("\t" + startnode.getLabel() + " -> " + endnode.getLabel() 
+                       + " [" + "label=\"" + seedge.getLabel() + "\"];");
+           }
+           output.println("}");
+           output.close();
+           nodes.clear();
+           nodes = null;
+       } catch (Exception e) {
+           e.printStackTrace();
+           System.exit(-1);
+       }
     }
-  }
-  
-  public static void printCriticalPath(String path,
-                                      Vector<SimExecutionEdge> criticalPath) {
-      try {
-         File file=new File(path);
-         FileOutputStream dotstream=new FileOutputStream(file,false);
-         PrintWriter output = new java.io.PrintWriter(dotstream, true);
-         output.println("digraph simulation{");
-         output.print("\t");
-         output.println("node [shape=plaintext];");
-         output.print("\t");
-         output.println("edge [dir=none];");
-         output.print("\t");
-         output.println("ranksep=.05;");
-         output.println();
-         output.print("\t");
-         Vector<SimExecutionNode> nodes = new Vector<SimExecutionNode>();
-         String label = "";
-         String dotnodeparams="";
-
-         for(int i = 0; i < criticalPath.size(); i++) {
-             SimExecutionEdge seedge = criticalPath.elementAt(i);
-             SimExecutionNode startnode = (SimExecutionNode)seedge.getSource();
-             SimExecutionNode endnode = (SimExecutionNode)seedge.getTarget();
-             if(!nodes.contains(startnode)) {
-                 label = startnode.getCoreNum() + ":" + startnode.getTimepoint();
-                 output.println("\t" + startnode.getLabel() + " [label=\"" 
-                                + label + "\" ];");
-          nodes.addElement(startnode);
-             }
-             if(!nodes.contains(endnode)) {
-                 label = endnode.getCoreNum() + ":" + endnode.getTimepoint();
-                 output.println("\t" + endnode.getLabel() + " [label=\"" 
-                                + label + "\" ];");
-          nodes.addElement(endnode);
-             }
-             output.println("\t" + startnode.getLabel() + " -> " + endnode.getLabel() 
-                            + " [" + "label=\"" + seedge.getLabel() + "\"];");
-         }
-         output.println("}");
-         output.close();
-      nodes.clear();
-         nodes = null;
-      } catch (Exception e) {
-         e.printStackTrace();
-         System.exit(-1);
-      }
-  }
 }
\ No newline at end of file