From: jzhou Date: Wed, 16 Jan 2008 23:46:19 +0000 (+0000) Subject: Add new feature of splitting nodes into Scheduling algorithm and fix some bugs in... X-Git-Tag: preEdgeChange~304 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=889090703643a3ad93015a6b42d65bdaa847672f;p=IRC.git Add new feature of splitting nodes into Scheduling algorithm and fix some bugs in handling probabilities of /new/ edge. --- diff --git a/Robust/src/Analysis/Scheduling/ClassNode.java b/Robust/src/Analysis/Scheduling/ClassNode.java index 027d8dd6..9964ecf8 100644 --- a/Robust/src/Analysis/Scheduling/ClassNode.java +++ b/Robust/src/Analysis/Scheduling/ClassNode.java @@ -17,6 +17,9 @@ public class ClassNode extends GraphNode implements Cloneable{ private ScheduleNode sn; private Vector flagStates; private boolean sorted = false; + private boolean clone = false; + + private int transTime; /** Class constructor * @param cd ClassDescriptor @@ -27,6 +30,15 @@ public class ClassNode extends GraphNode implements Cloneable{ this.flagStates = fStates; this.sn = null; this.uid=ClassNode.nodeID++; + this.transTime = 0; + } + + public int getTransTime() { + return this.transTime; + } + + public void setTransTime(int transTime) { + this.transTime = transTime; } public int getuid() { @@ -53,6 +65,10 @@ public class ClassNode extends GraphNode implements Cloneable{ return flagStates; } + public boolean isclone() { + return clone; + } + public String toString() { return cd.toString()+getTextLabel(); } @@ -84,7 +100,9 @@ public class ClassNode extends GraphNode implements Cloneable{ ClassNode fs=(ClassNode)o; if ((fs.getClassDescriptor()!= cd) || (fs.getScheduleNode() != sn) || - (fs.isSorted() != sorted)) { + (fs.isSorted() != sorted) || + (fs.clone != this.clone) || + (fs.transTime != this.transTime)) { return false; } return (fs.getFlagStates().equals(flagStates)); @@ -121,6 +139,13 @@ public class ClassNode extends GraphNode implements Cloneable{ e.printStackTrace(); } o.uid = ClassNode.nodeID++; + o.clone = true; return o; } + + public void calExeTime() { + for(int i = 0; i < this.flagStates.size(); i++) { + this.flagStates.elementAt(i).getExeTime(); + } + } } diff --git a/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java b/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java index e3423ebe..b31b5987 100644 --- a/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java +++ b/Robust/src/Analysis/Scheduling/ScheduleAnalysis.java @@ -1,7 +1,9 @@ package Analysis.Scheduling; import Analysis.TaskStateAnalysis.*; +import Analysis.TaskStateAnalysis.FEdge.NewObjInfo; import IR.*; + import java.util.*; import java.io.*; @@ -17,11 +19,11 @@ public class ScheduleAnalysis { State state; Vector scheduleNodes; Vector classNodes; + Hashtable cd2ClassNode; boolean sorted = false; Vector scheduleEdges; - Hashtable>> taskToSEdges; - - int probabilityThreshold; + + int transThreshold; public ScheduleAnalysis(State state, TaskAnalysis taskanalysis) { this.state = state; @@ -29,16 +31,13 @@ public class ScheduleAnalysis { this.scheduleNodes = new Vector(); this.classNodes = new Vector(); this.scheduleEdges = new Vector(); - this.taskToSEdges = new Hashtable>>(); - this.probabilityThreshold = 45; + this.cd2ClassNode = new Hashtable(); + + this.transThreshold = 45; } - public void setProbabilityThreshold(int pt) { - this.probabilityThreshold = pt; - } - - public Vector getSEdges(TaskDescriptor td, ClassDescriptor cd) { - return taskToSEdges.get(td).get(cd); + public void setTransThreshold(int tt) { + this.transThreshold = tt; } public Vector getSEdges4Test() { @@ -61,8 +60,15 @@ public class ScheduleAnalysis { ClassNode cNode = new ClassNode(cd, sFStates); cNode.setSorted(true); classNodes.add(cNode); + cd2ClassNode.put(cd, cNode); cdToCNodes.put(cd, cNode); - } + cNode.calExeTime(); + + // for test + if(cd.getSymbol().equals("C")) { + cNode.setTransTime(45); + } + } } // For each ClassNode create a ScheduleNode containing it @@ -71,6 +77,11 @@ public class ScheduleAnalysis { ScheduleNode sn = new ScheduleNode(classNodes.elementAt(i)); classNodes.elementAt(i).setScheduleNode(sn); scheduleNodes.add(sn); + try { + sn.calExeTime(); + } catch (Exception e) { + e.printStackTrace(); + } } // Create 'new' edges between the ScheduleNodes. @@ -91,24 +102,24 @@ public class ScheduleAnalysis { ScheduleNode sNode = cNode.getScheduleNode(); for(int j = 0; j < numEdges; j++) { FEdge pfe = fev.elementAt(j); + FEdge.NewObjInfo noi = pfe.getNewObjInfo(cd); + if ((noi == null) || (noi.getNewRate() == 0) || (noi.getProbability() == 0)) { + // fake creating edge, do not need to create corresponding 'new' edge + continue; + } FlagState pfs = (FlagState)pfe.getTarget(); ClassDescriptor pcd = pfs.getClassDescriptor(); ClassNode pcNode = cdToCNodes.get(pcd); - - ScheduleEdge sEdge = new ScheduleEdge(sNode, "new", td, cd); + + ScheduleEdge sEdge = new ScheduleEdge(sNode, "new",/* td,*/ cd); sEdge.setFEdge(pfe); sEdge.setSourceCNode(pcNode); sEdge.setTargetCNode(cNode); sEdge.setTargetFState(root); + sEdge.setNewRate(noi.getNewRate()); + sEdge.setProbability(noi.getProbability()); pcNode.getScheduleNode().addEdge(sEdge); scheduleEdges.add(sEdge); - if(taskToSEdges.get(td) == null) { - taskToSEdges.put(td, new Hashtable>()); - } - if(taskToSEdges.get(td).get(cd) == null) { - taskToSEdges.get(td).put(cd, new Vector()); - } - taskToSEdges.get(td).get(cd).add(sEdge); if((j !=0 ) || (k != 0) || (h != 0)) { toBreakDown.add(sEdge); } @@ -137,71 +148,253 @@ public class ScheduleAnalysis { for(i = 0; i < toBreakDown.size(); i++ ) { cloneSNodeList(toBreakDown.elementAt(i), false); } + + // Remove fake 'new' edges + for(i = 0; i < scheduleEdges.size(); i++) { + ScheduleEdge se = scheduleEdges.elementAt(i); + if((0 == se.getNewRate()) || (0 == se.getProbability())) { + scheduleEdges.removeElement(se); + scheduleNodes.removeElement(se.getTarget()); + } + } } + /*private void removeSNodeList(ScheduleEdge se) { + ScheduleNode sNode = (ScheduleNode)se.getTarget(); + scheduleNodes.removeElement(sNode); + Vector cNodes = sNode.getClassNodes(); + for(int i = 0; i < cNodes.size(); i++) { + classNodes.removeElement(cNodes.elementAt(i)); + cd2ClassNode.remove(cNodes.elementAt(i).getClassDescriptor()); + } + Vector edges = sNode.getEdgeVector(); + for(int j = 0; j < edges.size(); j++) { + removeSNodeList(edges.elementAt(j)); + } + }*/ + public void scheduleAnalysis() { // First iteration - int i = 0; - Vector rsev = new Vector(); + int i = 0; + //Access the ScheduleEdges in reverse topology order + Hashtable> fe2ses = new Hashtable>(); + Hashtable> sn2fes = new Hashtable>(); + ScheduleNode preSNode = null; for(i = scheduleEdges.size(); i > 0; i--) { ScheduleEdge se = scheduleEdges.elementAt(i-1); - if(!(se.getProbability() > this.probabilityThreshold)){ - // Merge the target ScheduleNode into the source ScheduleNode - ((ScheduleNode)se.getSource()).merge(se); - scheduleNodes.remove(se.getTarget()); - se.setTarget((ScheduleNode)se.getSource()); - rsev.add(se); + if(preSNode == null) { + preSNode = (ScheduleNode)se.getSource(); + } + if(se.getIsNew()) { + boolean split = false; + FEdge fe = se.getFEdge(); + if(fe.getSource() == fe.getTarget()) { + // back edge + int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100); + int rate = 0; + if(repeat > 1){ + for(int j = 1; j< repeat; j++ ) { + cloneSNodeList(se, true); + } + se.setNewRate(1); + se.setProbability(100); + } + try { + rate = (int)Math.ceil(se.getListExeTime()/ calInExeTime(se.getSourceFState())); + } catch (Exception e) { + e.printStackTrace(); + } + for(int j = rate - 1; j > 0; j--) { + for(int k = repeat; k > 0; k--) { + cloneSNodeList(se, true); + } + } + } else { + // if preSNode is not the same as se's source ScheduleNode + // handle any ScheduleEdges previously put into fe2ses whose source ScheduleNode is preSNode + boolean same = (preSNode == se.getSource()); + if(!same) { + if(preSNode.getFinishingTime() < se.getSource().getFinishingTime()) { + if(sn2fes.containsKey(preSNode)) { + Vector fes = sn2fes.remove(preSNode); + for(int j = 0; j < fes.size(); j++) { + FEdge tempfe = fes.elementAt(j); + Vector ses = fe2ses.get(tempfe); + ScheduleEdge tempse = ses.elementAt(0); + int temptime = tempse.getListExeTime(); + // find out the ScheduleEdge with least exeTime + for(int k = 1; k < ses.size(); k++) { + int ttemp = ses.elementAt(k).getListExeTime(); + if(ttemp < temptime) { + tempse = ses.elementAt(k); + temptime = ttemp; + } + } + // handle the tempse + handleScheduleEdge(tempse, true); + ses.removeElement(tempse); + // handle other ScheduleEdges + for(int k = 0; k < ses.size(); k++) { + handleScheduleEdge(ses.elementAt(k), false); + } + ses = null; + fe2ses.remove(tempfe); + } + fes = null; + } + } + preSNode = (ScheduleNode)se.getSource(); + } + + // if fe is the last task inside this ClassNode, delay the expanding and merging until we find all such 'nmew' edges + // associated with a last task inside this ClassNode + if(!fe.getTarget().edges().hasNext()) { + if(fe2ses.get(fe) == null) { + fe2ses.put(fe, new Vector()); + } + if(sn2fes.get((ScheduleNode)se.getSource()) == null) { + sn2fes.put((ScheduleNode)se.getSource(), new Vector()); + } + fe2ses.get(fe).add(se); + sn2fes.get((ScheduleNode)se.getSource()).add(fe); + } else { + // As this is not a last task, first handle available ScheduleEdges previously put into fe2ses + if((same) && (sn2fes.containsKey(preSNode))) { + Vector fes = sn2fes.remove(preSNode); + for(int j = 0; j < fes.size(); j++) { + FEdge tempfe = fes.elementAt(j); + Vector ses = fe2ses.get(tempfe); + ScheduleEdge tempse = ses.elementAt(0); + int temptime = tempse.getListExeTime(); + // find out the ScheduleEdge with least exeTime + for(int k = 1; k < ses.size(); k++) { + int ttemp = ses.elementAt(k).getListExeTime(); + if(ttemp < temptime) { + tempse = ses.elementAt(k); + temptime = ttemp; + } + } + // handle the tempse + handleScheduleEdge(tempse, true); + ses.removeElement(tempse); + // handle other ScheduleEdges + for(int k = 0; k < ses.size(); k++) { + handleScheduleEdge(ses.elementAt(k), false); + } + ses = null; + fe2ses.remove(tempfe); + } + fes = null; + } + + if((!(se.getTransTime() < this.transThreshold)) && (se.getSourceCNode().getTransTime() < se.getTransTime())) { + split = true; + splitSNode(se, true); + } else { + // handle this ScheduleEdge + handleScheduleEdge(se, true); + } + } + } } } - scheduleEdges.removeAll(rsev); - rsev = null; - - //Second iteration - //Access the ScheduleEdges in reverse topology order - for(i = scheduleEdges.size(); i > 0; i--) { - ScheduleEdge se = scheduleEdges.elementAt(i-1); - FEdge fe = se.getFEdge(); - if(fe.getSource() == fe.getTarget()) { - // back edge - if(se.getNewRate() > 1){ - for(int j = 1; j< se.getNewRate(); j++ ) { - cloneSNodeList(se, true); - } - se.setNewRate(1); + if(!fe2ses.isEmpty()) { + Set keys = fe2ses.keySet(); + Iterator it_keys = keys.iterator(); + while(it_keys.hasNext()) { + FEdge tempfe = (FEdge)it_keys.next(); + Vector ses = fe2ses.get(tempfe); + ScheduleEdge tempse = ses.elementAt(0); + int temptime = tempse.getListExeTime(); + // find out the ScheduleEdge with least exeTime + for(int k = 1; k < ses.size(); k++) { + int ttemp = ses.elementAt(k).getListExeTime(); + if(ttemp < temptime) { + tempse = ses.elementAt(k); + temptime = ttemp; + } } + // handle the tempse + handleScheduleEdge(tempse, true); + ses.removeElement(tempse); + // handle other ScheduleEdges + for(int k = 0; k < ses.size(); k++) { + handleScheduleEdge(ses.elementAt(k), false); + } + ses = null; + } + keys = null; + fe2ses.clear(); + sn2fes.clear(); + } + } + + private void handleScheduleEdge(ScheduleEdge se, boolean merge) { + int rate = 0; + int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100); + if(merge) { + try { + rate = (int)Math.ceil((se.getTransTime() - calInExeTime(se.getSourceFState()))/ se.getListExeTime()); + if(rate < 0 ) { + rate = 0; + } + } catch (Exception e) { + e.printStackTrace(); + } + if(0 == rate) { + // clone the whole ScheduleNode lists starting with se's target + for(int j = 1; j < repeat; j++ ) { + cloneSNodeList(se, true); + } + se.setNewRate(1); + se.setProbability(100); } else { - if(se.getNewRate() > 1){ + repeat -= rate; + if(repeat > 0){ // clone the whole ScheduleNode lists starting with se's target - for(int j = 1; j < se.getNewRate(); j++ ) { + for(int j = 0; j < repeat; j++ ) { cloneSNodeList(se, true); } - se.setNewRate(1); - } else if (se.getNewRate() == 1) { - //merge the target ScheduleNode to the source ScheduleNode - ((ScheduleNode)se.getSource()).merge(se); - scheduleNodes.remove(se.getTarget()); - scheduleEdges.removeElement(se); - se.setTarget((ScheduleNode)se.getSource()); - } + se.setNewRate(rate); + se.setProbability(100); + } } - } + // merge the original ScheduleNode to the source ScheduleNode + ((ScheduleNode)se.getSource()).mergeSEdge(se); + scheduleNodes.remove(se.getTarget()); + scheduleEdges.removeElement(se); + // 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()); + } else { + // clone the whole ScheduleNode lists starting with se's target + for(int j = 1; j < repeat; j++ ) { + cloneSNodeList(se, true); + } + se.setNewRate(1); + se.setProbability(100); + } } private void cloneSNodeList(ScheduleEdge sEdge, boolean copyIE) { Hashtable cn2cn = new Hashtable(); ScheduleNode csNode = (ScheduleNode)((ScheduleNode)sEdge.getTarget()).clone(cn2cn); scheduleNodes.add(csNode); - + // Clone all the external in ScheduleEdges int i; if(copyIE) { Vector inedges = sEdge.getTarget().getInedgeVector(); for(i = 0; i < inedges.size(); i++) { ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i); - ScheduleEdge se = new ScheduleEdge(csNode, "new", tse.getTask(), tse.getClassDescriptor()); - se.setProbability(tse.getProbability()); - se.setNewRate(1); - se.setFEdge(tse.getFEdge()); + ScheduleEdge se = new ScheduleEdge(csNode, "new", tse.getClassDescriptor(), tse.getIsNew()); + if(tse.getIsNew()) { + //se.setProbability(tse.getProbability()); + se.setProbability(100); + se.setNewRate(1); + se.setFEdge(tse.getFEdge()); + } se.setSourceCNode(tse.getSourceCNode()); se.setTargetCNode(cn2cn.get(tse.getTargetCNode())); tse.getSource().addEdge(se); @@ -212,6 +405,7 @@ public class ScheduleAnalysis { sEdge.setTarget(csNode); csNode.getInedgeVector().add(sEdge); sEdge.setTargetCNode(cn2cn.get(sEdge.getTargetCNode())); + sEdge.setTargetFState(null); } Queue toClone = new LinkedList(); @@ -234,9 +428,14 @@ public class ScheduleAnalysis { clone.add(tSNode); toClone.add((ScheduleNode)tse.getTarget()); qcn2cn.add(tocn2cn); - ScheduleEdge se = new ScheduleEdge(tSNode, "new", tse.getTask(), tse.getClassDescriptor()); - se.setProbability(tse.getProbability()); - se.setNewRate(tse.getNewRate()); + ScheduleEdge se = null; + if(tse.getIsNew()) { + se = new ScheduleEdge(tSNode, "new", tse.getClassDescriptor(), tse.getIsNew()); + se.setProbability(tse.getProbability()); + se.setNewRate(tse.getNewRate()); + } else { + se = new ScheduleEdge(tSNode, "transmit", tse.getClassDescriptor(), false); + } se.setSourceCNode(cn2cn.get(tse.getSourceCNode())); se.setTargetCNode(tocn2cn.get(tse.getTargetCNode())); csNode.addEdge(se); @@ -245,6 +444,131 @@ public class ScheduleAnalysis { } } + private int calInExeTime(FlagState fs) throws Exception { + int exeTime = 0; + ClassDescriptor cd = fs.getClassDescriptor(); + ClassNode cNode = cd2ClassNode.get(cd); + exeTime = cNode.getFlagStates().elementAt(0).getExeTime() - fs.getExeTime(); + while(true) { + Vector inedges = cNode.getInedgeVector(); + if(inedges.size() > 1) { + throw new Exception("Error: ClassNode's inedges more than one!"); + } + if(inedges.size() > 0) { + ScheduleEdge sEdge = (ScheduleEdge)inedges.elementAt(0); + cNode = (ClassNode)sEdge.getSource(); + exeTime += cNode.getFlagStates().elementAt(0).getExeTime(); + }else { + break; + } + } + exeTime = cNode.getScheduleNode().getExeTime() - exeTime; + return exeTime; + } + + private ScheduleNode splitSNode(ScheduleEdge se, boolean copy) { + FEdge fe = se.getFEdge(); + FlagState fs = (FlagState)fe.getTarget(); + FlagState nfs = (FlagState)fs.clone(); + fs.getEdgeVector().removeAllElements(); + nfs.getInedgeVector().removeAllElements(); + ClassNode sCNode = se.getSourceCNode(); + + // split the subtree whose root is nfs from the whole flag transition tree + Vector sfss = sCNode.getFlagStates(); + Vector fStates = new Vector(); + Queue toiterate = new LinkedList(); + toiterate.add(nfs); + fStates.add(nfs); + while(!toiterate.isEmpty()){ + FlagState tfs = toiterate.poll(); + Iterator it_edges = tfs.edges(); + while(it_edges.hasNext()) { + FlagState temp = (FlagState)((FEdge)it_edges.next()).getTarget(); + if(!fStates.contains(temp)) { + fStates.add(temp); + toiterate.add(temp); + sfss.removeElement(temp); + } + } + } + Vector sFStates = FlagState.DFS.topology(fStates, null); + // create a ClassNode and ScheduleNode for this subtree + ClassNode cNode = new ClassNode(sCNode.getClassDescriptor(), sFStates); + ScheduleNode sNode = new ScheduleNode(cNode); + cNode.setScheduleNode(sNode); + cNode.setSorted(true); + cNode.setTransTime(sCNode.getTransTime()); + classNodes.add(cNode); + scheduleNodes.add(sNode); + try { + sNode.calExeTime(); + } catch (Exception e) { + e.printStackTrace(); + } + // flush the exeTime of fs and its ancestors + fs.setExeTime(0); + toiterate.add(fs); + while(!toiterate.isEmpty()) { + FlagState tfs = toiterate.poll(); + int ttime = tfs.getExeTime(); + Iterator it_inedges = tfs.inedges(); + while(it_inedges.hasNext()) { + FEdge fEdge = (FEdge)it_inedges.next(); + FlagState temp = (FlagState)fEdge.getSource(); + int time = fEdge.getExeTime() + ttime; + if(temp.getExeTime() > time) { + temp.setExeTime(time); + toiterate.add(temp); + } + } + } + + + // create a 'trans' ScheudleEdge between this new ScheduleNode and se's source ScheduleNode + ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false); + sEdge.setTargetFState(fs); + sEdge.setFEdge(fe); + sEdge.setSourceCNode(sCNode); + sEdge.setTargetCNode(cNode); + sEdge.setTargetFState(nfs); + // todo + // Add calculation codes for calculating transmit time of an object + sEdge.setTransTime(cNode.getTransTime()); + se.getSource().addEdge(sEdge); + scheduleEdges.add(sEdge); + // redirect ScheudleEdges out of this subtree to the new ScheduleNode + Iterator it_sEdges = se.getSource().edges(); + Vector toremove = new Vector(); + while(it_sEdges.hasNext()) { + ScheduleEdge tse = (ScheduleEdge)it_sEdges.next(); + if((tse != se) && (tse != sEdge) && (tse.getSourceCNode() == sCNode)) { + if((tse.getSourceFState() != fs) && (sFStates.contains(tse.getSourceFState()))) { + tse.setSource(sNode); + tse.setSourceCNode(cNode); + sNode.getEdgeVector().addElement(tse); + toremove.add(tse); + } + } + } + se.getSource().getEdgeVector().removeAll(toremove); + + if(!copy) { + //merge se into its source ScheduleNode + ((ScheduleNode)se.getSource()).mergeSEdge(se); + scheduleNodes.remove(se.getTarget()); + scheduleEdges.removeElement(se); + // 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()); + } else { + handleScheduleEdge(se, true); + } + + return sNode; + } + public void schedule() { // Assign a core to each ScheduleNode int i = 0; @@ -287,14 +611,7 @@ public class ScheduleAnalysis { output.println("\tsubgraph " + gn.getLabel() + "{"); output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";"); Iterator it_cnodes = gn.getClassNodesIterator(); - if(gn.isclone()) { - while (it_cnodes.hasNext()) { - ClassNode cn = (ClassNode) it_cnodes.next(); - output.println("\t\t" + cn.getLabel() + " [style=dashed, label=\"" + cn.getTextLabel() + "\", shape=box];"); - } - } else { - traverseCNodes(output, it_cnodes); - } + traverseCNodes(output, it_cnodes); //Draw the internal 'new' edges Iterator it_edges =gn.getScheduleEdgesIterator(); while(it_edges.hasNext()) { @@ -322,16 +639,16 @@ public class ScheduleAnalysis { while(edges.hasNext()) { ScheduleEdge se = (ScheduleEdge)edges.next(); output.print("\t"); - if(((ScheduleNode)se.getSource()).isclone()) { + if(se.getSourceFState() == null) { output.print(se.getSourceCNode().getLabel()); } else { output.print(se.getSourceFState().getLabel()); } output.print(" -> "); - if(((ScheduleNode)se.getTarget()).isclone()) { - output.println(se.getTargetCNode().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed];"); + if(se.getTargetFState() == null) { + output.println(se.getTargetCNode().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed]"); } else { - output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed, ltail=" + gn.getLabel() + "];"); + output.println(se.getTargetFState().getLabel() + " [label=\"" + se.getLabel() + "\", color=red, style=dashed]"); } } } @@ -341,11 +658,15 @@ public class ScheduleAnalysis { //Draw clusters representing ClassNodes while (it.hasNext()) { ClassNode gn = (ClassNode) it.next(); - output.println("\tsubgraph " + gn.getClusterLabel() + "{"); - output.println("\t\tstyle=dashed;"); - output.println("\t\tlabel=\"" + gn.getTextLabel() + "\";"); - traverseFlagStates(output, gn.getFlagStates()); - output.println("\t}\n"); + 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"); + } } } @@ -367,7 +688,7 @@ public class ScheduleAnalysis { Namer name=(Namer) namers.get(i); String newlabel=name.nodeLabel(gn); String newparams=name.nodeOption(gn); - + if (!newlabel.equals("") && !label.equals("")) { label+=", "; } @@ -376,6 +697,7 @@ public class ScheduleAnalysis { } label+=name.nodeLabel(gn); } + label += ":[" + ((FlagState)gn).getExeTime() + "]"; if (!gn.merge) output.println("\t" + gn.getLabel() + " [label=\"" + label + "\"" + dotnodeparams + "];"); @@ -400,7 +722,17 @@ public class ScheduleAnalysis { if (!newoption.equals("")) edgedotnodeparams+=", "+newoption; } - + edgelabel+=":[" + ((FEdge)edge).getExeTime() + "]"; + Hashtable hashtable = ((FEdge)edge).getNewObjInfoHashtable(); + if(hashtable != null) { + Set 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() + "%) }"; + } + } output.println("\t" + gn.getLabel() + " -> " + node2.getLabel() + " [" + "label=\"" + edgelabel + "\"" + edgedotnodeparams + "];"); } } diff --git a/Robust/src/Analysis/Scheduling/ScheduleEdge.java b/Robust/src/Analysis/Scheduling/ScheduleEdge.java index 9d0a21e0..82479aa8 100644 --- a/Robust/src/Analysis/Scheduling/ScheduleEdge.java +++ b/Robust/src/Analysis/Scheduling/ScheduleEdge.java @@ -1,61 +1,87 @@ package Analysis.Scheduling; +import java.util.Iterator; + import IR.*; import Analysis.TaskStateAnalysis.*; import Util.Edge; +import Util.GraphNode; /* Edge *****************/ public class ScheduleEdge extends Edge { private String label; - private final TaskDescriptor td; private final ClassDescriptor cd; - private FEdge fedge; + private boolean isNew = true; + private FlagState targetFState; private ClassNode sourceCNode; private ClassNode targetCNode; - private int newRate; + private int probability; - //private int parameterindex; + private int transTime; + private int listExeTime; + + private FEdge fedge; + private int newRate; /** Class Constructor * */ - public ScheduleEdge(ScheduleNode target, String label, TaskDescriptor td, ClassDescriptor cd/*, int parameterindex*/) { + public ScheduleEdge(ScheduleNode target, String label, ClassDescriptor cd) { + super(target); + this.fedge = null; + this.targetFState = null; + this.sourceCNode = null; + this.targetCNode = null; + this.label = label; + this.cd = cd; + this.newRate = -1; + this.probability = 100; + this.transTime = -1; + this.listExeTime = -1; + } + + public ScheduleEdge(ScheduleNode target, String label, ClassDescriptor cd, boolean isNew) { super(target); this.fedge = null; this.targetFState = null; this.sourceCNode = null; this.targetCNode = null; this.label = label; - this.td = td; this.cd = cd; - this.newRate = 1; + this.newRate = -1; this.probability = 100; - //this.parameterindex = parameterindex; + this.transTime = -1; + this.listExeTime = -1; + this.isNew = isNew; } - public void setTarget(ScheduleNode sn) { + public void setTarget(GraphNode sn) { this.target = sn; } public String getLabel() { - String completeLabel = label + ":" + Integer.toString(this.newRate) + ":(" + Integer.toString(this.probability) + ")"; + String completeLabel = label; + if(isNew) { + completeLabel += ":" + Integer.toString(this.newRate); + } + completeLabel += ":(" + Integer.toString(this.probability) + "%)" + ":[" + Integer.toString(this.transTime) + "]"; return completeLabel; } public int hashCode(){ return target.hashCode()^label.hashCode(); } - - public TaskDescriptor getTask() { - return td; - } public ClassDescriptor getClassDescriptor() { return cd; } + public boolean getIsNew() { + return this.isNew; + } + public FEdge getFEdge() { return this.fedge; } @@ -101,27 +127,31 @@ public class ScheduleEdge extends Edge { public void setTargetCNode(ClassNode targetCNode) { this.targetCNode = targetCNode; + this.transTime = targetCNode.getTransTime(); } - - /* public int getIndex() { - return parameterindex; - }*/ public boolean equals(Object o) { if (o instanceof ScheduleEdge) { ScheduleEdge e=(ScheduleEdge)o; if ((e.label.equals(label))&& (e.target.equals(target))&& - (e.td.equals(td)) && + (e.source.equals(source)) && (e.cd.equals(cd)) && - (e.fedge.equals(fedge)) && - (e.targetFState.equals(targetFState)) && + (e.fedge.equals(fedge)) && (e.sourceCNode.equals(sourceCNode)) && (e.targetCNode.equals(targetCNode)) && (e.newRate == newRate) && - (e.probability == probability)/*&& - e.getIndex()==parameterindex*/) - return true; + (e.probability == probability) && + (e.isNew == isNew) && + (e.transTime == transTime) && + (e.listExeTime == listExeTime)) + if(e.targetFState != null) { + return e.targetFState.equals(targetFState); + } else if(this.targetFState == null) { + return true; + } else { + return false; + } } return false; } @@ -133,4 +163,36 @@ public class ScheduleEdge extends Edge { public void setNewRate(int nr) { this.newRate = nr; } + + public int getTransTime() { + return this.transTime; + } + + public void setTransTime(int transTime) { + this.transTime = transTime; + } + + public int getListExeTime() { + if(listExeTime == -1) { + // calculate the lisExeTime + listExeTime = ((ScheduleNode)this.getTarget()).getExeTime() + this.getTransTime() * this.getNewRate(); + Iterator it_edges = this.getTarget().edges(); + int temp = 0; + if(it_edges.hasNext()) { + temp = ((ScheduleEdge)it_edges.next()).getListExeTime(); + } + while(it_edges.hasNext()) { + int tetime = ((ScheduleEdge)it_edges.next()).getListExeTime(); + if(temp < tetime) { + temp = tetime; + } + } + listExeTime += temp; + } + return this.listExeTime; + } + + public void resetListExeTime() { + this.listExeTime = -1; + } } diff --git a/Robust/src/Analysis/Scheduling/ScheduleNode.java b/Robust/src/Analysis/Scheduling/ScheduleNode.java index 5ea3b61d..44b345b6 100644 --- a/Robust/src/Analysis/Scheduling/ScheduleNode.java +++ b/Robust/src/Analysis/Scheduling/ScheduleNode.java @@ -13,15 +13,15 @@ public class ScheduleNode extends GraphNode implements Cloneable{ private int uid; private static int nodeID=0; + private Vector classNodes; + Vector scheduleEdges; + + private int executionTime; + private int coreNum; private Vector tasks; private Hashtable> targetSNodes; private boolean sorted = false; - - private boolean clone = false; - - private Vector classNodes; - Vector scheduleEdges; /** Class constructor * @param cd ClassDescriptor @@ -30,6 +30,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{ public ScheduleNode() { this.uid=ScheduleNode.nodeID++; this.coreNum = -1; + this.executionTime = -1; } public ScheduleNode(ClassNode cn) { @@ -39,6 +40,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{ this.scheduleEdges = new Vector(); this.classNodes.add(cn); this.addEdge(cn.getEdgeVector()); + this.executionTime = -1; } public int getuid() { @@ -101,10 +103,6 @@ public class ScheduleNode extends GraphNode implements Cloneable{ this.sorted = sorted; } - public boolean isclone() { - return clone; - } - public String toString() { String temp = new String(""); for(int i = 0; i < classNodes.size(); i++) { @@ -113,7 +111,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{ temp += getTextLabel(); return temp; } - + public Vector getClassNodes() { if(classNodes == null) { classNodes = new Vector(); @@ -144,6 +142,28 @@ public class ScheduleNode extends GraphNode implements Cloneable{ scheduleEdges = null; } + public int getExeTime() { + if(this.executionTime == -1) { + try { + calExeTime(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return this.executionTime; + } + + public void calExeTime() throws Exception { + if(this.classNodes.size() != 1) { + throw new Exception("Error: there are multiple ClassNodes inside the ScheduleNode when calculating executionTime"); + } + ClassNode cn = this.classNodes.elementAt(0); + if(!cn.isSorted()) { + throw new Error("Error: Non-sorted ClassNode!"); + } + this.executionTime = cn.getFlagStates().elementAt(0).getExeTime(); + } + /** Tests for equality of two flagstate objects. */ @@ -152,7 +172,7 @@ public class ScheduleNode extends GraphNode implements Cloneable{ ScheduleNode fs=(ScheduleNode)o; if ((fs.getCoreNum() != this.coreNum) || (fs.sorted != this.sorted) || - (fs.clone != this.clone)){ + (fs.executionTime != this.executionTime)){ return false; } if(fs.tasks != null) { @@ -221,9 +241,17 @@ public class ScheduleNode extends GraphNode implements Cloneable{ } for(i = 0; i < this.scheduleEdges.size(); i++) { ScheduleEdge temp = this.scheduleEdges.elementAt(i); - ScheduleEdge se = new ScheduleEdge(o, "new", temp.getTask(), temp.getClassDescriptor()); + ScheduleEdge se = null; + if(!temp.getIsNew()) { + se = new ScheduleEdge(o, "transmit",temp.getClassDescriptor(), false); + } else { + se = new ScheduleEdge(o, "new",temp.getClassDescriptor()); + } se.setSourceCNode(cn2cn.get(temp.getSourceCNode())); se.setTargetCNode(cn2cn.get(temp.getTargetCNode())); + se.setProbability(temp.getProbability()); + se.setNewRate(temp.getNewRate()); + se.setTransTime(temp.getTransTime()); tses.add(se); } o.classNodes = tcns; @@ -232,12 +260,13 @@ public class ScheduleNode extends GraphNode implements Cloneable{ tses = null; o.inedges = new Vector(); o.edges = new Vector(); - - o.clone = true; + return o; } - public void merge(ScheduleEdge se) { + public void mergeSEdge(ScheduleEdge se) { + assert(se.getIsNew()); + Vector targetCNodes = (Vector)((ScheduleNode)se.getTarget()).getClassNodes(); Vector targetSEdges = (Vector)((ScheduleNode)se.getTarget()).getScheduleEdges(); @@ -260,14 +289,60 @@ public class ScheduleNode extends GraphNode implements Cloneable{ targetSEdges = null; scheduleEdges.add(se); + se.resetListExeTime(); se.getTarget().removeInedge(se); this.removeEdge(se); - //this.addEdge(se.getTarget().getEdgeVector()); Iterator it_edges = se.getTarget().edges(); while(it_edges.hasNext()) { ScheduleEdge tse = (ScheduleEdge)it_edges.next(); tse.setSource(this); this.edges.addElement(tse); + } + + // As all tasks inside one ScheduleNode are executed sequentially, + // simply add the execution time of all the ClassNodes inside one ScheduleNode. + if(this.executionTime == -1) { + this.executionTime = 0; + } + this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime(); + } + + public void mergeSNode(ScheduleNode sn) throws Exception { + Vector targetCNodes = (Vector)sn.getClassNodes(); + Vector targetSEdges = (Vector)sn.getScheduleEdges(); + + for(int i = 0; i < targetCNodes.size(); i++) { + targetCNodes.elementAt(i).setScheduleNode(this); + } + + if(classNodes == null) { + classNodes = targetCNodes; + scheduleEdges = targetSEdges; + } else { + if(targetCNodes.size() != 0) { + classNodes.addAll(targetCNodes); + } + if(targetSEdges.size() != 0) { + scheduleEdges.addAll(targetSEdges); + } + } + targetCNodes = null; + targetSEdges = null; + + Iterator it_edges = sn.edges(); + while(it_edges.hasNext()) { + ScheduleEdge tse = (ScheduleEdge)it_edges.next(); + tse.setSource(this); + this.edges.addElement(tse); + } + + // As all tasks inside one ScheduleNode are executed sequentially, + // simply add the execution time of all the ClassNodes inside one ScheduleNode. + if(this.executionTime == -1) { + throw new Exception("Error: ScheduleNode without initiate execution time when analysising."); + } + if(this.executionTime < sn.getExeTime()) { + this.executionTime = sn.getExeTime(); } } } diff --git a/Robust/src/Analysis/TaskStateAnalysis/FEdge.java b/Robust/src/Analysis/TaskStateAnalysis/FEdge.java index 19b4e5df..494748d1 100644 --- a/Robust/src/Analysis/TaskStateAnalysis/FEdge.java +++ b/Robust/src/Analysis/TaskStateAnalysis/FEdge.java @@ -13,6 +13,53 @@ public class FEdge extends Edge { private String label; private TaskDescriptor td; private int parameterindex; + + // jzhou + private int executeTime; + private Hashtable newObjInfos; + + public class NewObjInfo { + int newRate; + int probability; + + public NewObjInfo() { + newRate = 0; + probability = 0; + } + + public NewObjInfo(int newRate, int probability) { + this.newRate = newRate; + this.probability = probability; + } + + public int getNewRate() { + return this.newRate; + } + + public void setNewRate(int newRate) { + this.newRate = newRate; + } + + public int getProbability() { + return this.probability; + } + + public void setProbability(int probability) { + this.probability = probability; + } + + public boolean equals(Object o) { + if (o instanceof NewObjInfo) { + NewObjInfo e=(NewObjInfo)o; + if (e.newRate == this.newRate && + e.probability == this.probability) { + return true; + } + } + return false; + } + } + /** Class Constructor * */ @@ -21,6 +68,8 @@ public class FEdge extends Edge { this.label = label; this.td=td; this.parameterindex=parameterindex; + this.executeTime = -1; + this.newObjInfos = null; } public String getLabel() { @@ -44,10 +93,45 @@ public class FEdge extends Edge { FEdge e=(FEdge)o; if (e.label.equals(label)&& e.target.equals(target)&& + e.source.equals(source) && e.td==td&& - e.parameterindex==parameterindex) - return true; + e.parameterindex==parameterindex && + e.executeTime == executeTime) { + if(this.newObjInfos != null) { + if(e.newObjInfos == null) { + return false; + } else if(e.newObjInfos.equals(this.newObjInfos)) { + return true; + } + } + } } return false; } + + public int getExeTime() { + return this.executeTime; + } + + public void setExeTime(int eTime) { + this.executeTime = eTime; + } + + public Hashtable getNewObjInfoHashtable() { + return this.newObjInfos; + } + + public NewObjInfo getNewObjInfo(ClassDescriptor cd) { + if(this.newObjInfos == null) { + return null; + } + return this.newObjInfos.get(cd); + } + + public void addNewObjInfo(ClassDescriptor cd, int newRate, int probability) { + if(this.newObjInfos == null) { + this.newObjInfos = new Hashtable(); + } + this.newObjInfos.put(cd, new NewObjInfo(newRate, probability)); + } } diff --git a/Robust/src/Analysis/TaskStateAnalysis/FlagState.java b/Robust/src/Analysis/TaskStateAnalysis/FlagState.java index b70ce015..730bb740 100644 --- a/Robust/src/Analysis/TaskStateAnalysis/FlagState.java +++ b/Robust/src/Analysis/TaskStateAnalysis/FlagState.java @@ -1,4 +1,5 @@ package Analysis.TaskStateAnalysis; +import Analysis.Scheduling.ClassNode; import Analysis.TaskStateAnalysis.*; import IR.*; import IR.Tree.*; @@ -10,7 +11,7 @@ import Util.GraphNode; /** This class is used to hold the flag states that a class in the Bristlecone * program can exist in, during runtime. */ -public class FlagState extends GraphNode { +public class FlagState extends GraphNode implements Cloneable { public static final int ONETAG=1; public static final int NOTAGS=0; public static final int MULTITAGS=-1; @@ -24,6 +25,9 @@ public class FlagState extends GraphNode { private boolean issourcenode; private Vector tasks; public static final int KLIMIT=2; + + // jzhou + private int executeTime; /** Class constructor * Creates a new flagstate with all flags set to false. @@ -35,6 +39,7 @@ public class FlagState extends GraphNode { this.tags=new Hashtable(); this.uid=FlagState.nodeid++; this.issourcenode=false; + this.executeTime = -1; } /** Class constructor @@ -49,7 +54,7 @@ public class FlagState extends GraphNode { this.tags=tags; this.uid=FlagState.nodeid++; this.issourcenode=false; - + this.executeTime = -1; } public int getuid() { @@ -69,9 +74,9 @@ public class FlagState extends GraphNode { */ public boolean isSourceNode(){ - return issourcenode; - } - + return issourcenode; + } + /** Sets the flagstate as a source node. */ public void setAsSourceNode(){ @@ -175,7 +180,7 @@ public class FlagState extends GraphNode { //2 case HashSet newset1=(HashSet)flagstate.clone(); Hashtable newtags1=(Hashtable)tags.clone(); - + //1 case HashSet newset2=(HashSet)flagstate.clone(); Hashtable newtags2=(Hashtable)tags.clone(); @@ -195,20 +200,20 @@ public class FlagState extends GraphNode { * @param flags an array of flagdescriptors. * @return string representation of the flagstate. */ - public String toString(FlagDescriptor[] flags) - { - StringBuffer sb = new StringBuffer(flagstate.size()); - for(int i=0;i < flags.length; i++) - { - if (get(flags[i])) - sb.append(1); - else - sb.append(0); - } - - return new String(sb); - } - + public String toString(FlagDescriptor[] flags) + { + StringBuffer sb = new StringBuffer(flagstate.size()); + for(int i=0;i < flags.length; i++) + { + if (get(flags[i])) + sb.append(1); + else + sb.append(0); + } + + return new String(sb); + } + /** Accessor method * @return returns the classdescriptor of the flagstate. */ @@ -266,23 +271,23 @@ public class FlagState extends GraphNode { label+=", "+fd.toString(); } for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){ - TagDescriptor td=(TagDescriptor)en_tags.nextElement(); - switch (tags.get(td).intValue()){ - case ONETAG: - if (label==null) - label=td.toString()+"(1)"; - else - label+=", "+td.toString()+"(1)"; - break; - case MULTITAGS: - if (label==null) - label=td.toString()+"(n)"; - else - label+=", "+td.toString()+"(n)"; - break; - default: - break; - } + TagDescriptor td=(TagDescriptor)en_tags.nextElement(); + switch (tags.get(td).intValue()){ + case ONETAG: + if (label==null) + label=td.toString()+"(1)"; + else + label+=", "+td.toString()+"(1)"; + break; + case MULTITAGS: + if (label==null) + label=td.toString()+"(n)"; + else + label+=", "+td.toString()+"(n)"; + break; + default: + break; + } } if (label==null) return " "; @@ -290,6 +295,61 @@ public class FlagState extends GraphNode { } public Enumeration getTags(){ - return tags.keys(); + return tags.keys(); + } + + public int getExeTime() { + try { + if(this.executeTime == -1) { + calExeTime(); + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(0); + } + return this.executeTime; + } + + public void setExeTime(int exeTime) { + this.executeTime = exeTime; + } + + public void calExeTime() throws Exception { + Iterator it = this.edges(); + if(it.hasNext()) { + FEdge fe = (FEdge)it.next(); + if(fe.getExeTime() == -1) { + throw new Exception("Error: Uninitiate FEdge!"); + } + this.executeTime = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime(); + } else { + this.executeTime = 0; + } + while(it.hasNext()) { + FEdge fe = (FEdge)it.next(); + int temp = fe.getExeTime() + ((FlagState)fe.getTarget()).getExeTime(); + if(temp < this.executeTime) { + this.executeTime = temp; + } + } + } + + public Object clone() { + FlagState o = null; + try { + o = (FlagState)super.clone(); + } catch(CloneNotSupportedException e){ + e.printStackTrace(); + } + o.uid = FlagState.nodeid++; + o.edges = new Vector(); + for(int i = 0; i < this.edges.size(); i++) { + o.edges.addElement(this.edges.elementAt(i)); + } + o.inedges = new Vector(); + for(int i = 0; i < this.inedges.size(); i++) { + o.inedges.addElement(this.inedges.elementAt(i)); + } + return o; } }