--- /dev/null
+package Analysis.Scheduling;
+
+import java.util.Vector;
+
+public class CombinationUtil {
+ static CombinationUtil cu;
+
+ public CombinationUtil() {
+ }
+
+ public static CombinationUtil allocateCombinationUtil() {
+ if(cu == null) {
+ cu = new CombinationUtil();
+ }
+ return cu;
+ }
+
+ public static RootsGenerator allocateRootsGenerator(Vector<Vector<ScheduleNode>> snodevecs, int rootNum) {
+ return CombinationUtil.allocateCombinationUtil().new RootsGenerator(snodevecs, rootNum);
+ }
+
+ public static CombineGenerator allocateCombineGenerator(Vector<Vector<ScheduleNode>> rootnodes, Vector<Vector<ScheduleNode>> node2combine) {
+ return CombinationUtil.allocateCombinationUtil().new CombineGenerator(rootnodes, node2combine);
+ }
+
+ public class RootsGenerator {
+ Vector<Vector<ScheduleNode>> sNodeVecs;
+ Vector<Vector<ScheduleNode>> node2Combine;
+ Vector<Vector<ScheduleNode>> rootNodes;
+ int rootNum;
+
+ public RootsGenerator(Vector<Vector<ScheduleNode>> snodevecs, int rootNum) {
+ this.sNodeVecs = snodevecs;
+ this.rootNum = rootNum;
+ this.node2Combine = null;
+ this.rootNodes = null;
+ }
+
+ public boolean nextGen() {
+ boolean trial = false;
+ if(this.rootNodes == null) {
+ int num2choose = this.rootNum;
+ this.rootNodes = new Vector<Vector<ScheduleNode>>();
+ this.rootNodes.add(new Vector<ScheduleNode>());
+ Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(0);
+ for(int i = 0; i < toadd.size(); i++) {
+ // should be only one element: startup object
+ this.rootNodes.elementAt(0).add(toadd.elementAt(i));
+ num2choose--;
+ }
+ int next = 1;
+ trial = trial(num2choose, next);
+ } else {
+ int next = this.rootNodes.lastElement().elementAt(0).getCid() + 1;
+ int num2choose = 0;
+ if(next == this.sNodeVecs.size()) {
+ // backtrack
+ num2choose = this.rootNodes.lastElement().size();
+ this.rootNodes.removeElementAt(this.rootNodes.size() - 1);
+ if(this.rootNodes.size() == 1) {
+ // only startup object left, no more choices
+ return false;
+ }
+ next = this.rootNodes.lastElement().elementAt(0).getCid() + 1;
+
+ }
+ num2choose++;
+ // reduce one from the last one
+ this.rootNodes.lastElement().removeElementAt(this.rootNodes.lastElement().size() - 1);
+ if(this.rootNodes.lastElement().size() == 0) {
+ this.rootNodes.removeElementAt(this.rootNodes.size() - 1);
+ }
+
+ trial = trial(num2choose, next);
+ }
+ if(trial) {
+ // left nodes are all to be combined
+ this.node2Combine = new Vector<Vector<ScheduleNode>>();
+ int next = 1;
+ int index = 0;
+ for(int i = 1; i < this.rootNodes.size(); i++) {
+ int tmp = this.rootNodes.elementAt(i).elementAt(0).getCid();
+ while(next < tmp) {
+ this.node2Combine.add(new Vector<ScheduleNode>());
+ Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(next);
+ for(index = 0; index < toadd.size(); index++) {
+ this.node2Combine.lastElement().add(toadd.elementAt(index));
+ }
+ next++;
+ }
+ Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(tmp);
+ if(toadd.size() > this.rootNodes.elementAt(i).size()) {
+ this.node2Combine.add(new Vector<ScheduleNode>());
+ for(index = this.rootNodes.elementAt(i).size(); index < toadd.size(); index++) {
+ this.node2Combine.lastElement().add(toadd.elementAt(index));
+ }
+ }
+ next++;
+ }
+ while(next < this.sNodeVecs.size()) {
+ this.node2Combine.add(new Vector<ScheduleNode>());
+ Vector<ScheduleNode> toadd = this.sNodeVecs.elementAt(next);
+ for(index = 0; index < toadd.size(); index++) {
+ this.node2Combine.lastElement().add(toadd.elementAt(index));
+ }
+ next++;
+ }
+ }
+ return trial;
+ }
+
+ private boolean trial(int num2choose, int next) {
+ int index = 0;
+ boolean first = true;
+ while(num2choose > 0) {
+ if(first) {
+ if(next == this.sNodeVecs.size()) {
+ // no more nodes available to add
+ return false;
+ }
+ this.rootNodes.add(new Vector<ScheduleNode>());
+ first = false;
+ }
+ this.rootNodes.lastElement().add(this.sNodeVecs.elementAt(next).elementAt(index));
+ num2choose--;
+ index++;
+ if(index == this.sNodeVecs.elementAt(next).size()) {
+ index = 0;
+ next++;
+ first = true;
+ }
+ }
+ return true;
+ }
+
+ public Vector<Vector<ScheduleNode>> getNode2Combine() {
+ return node2Combine;
+ }
+
+ public Vector<Vector<ScheduleNode>> getRootNodes() {
+ return rootNodes;
+ }
+ }
+
+ public class Combine {
+ public ScheduleNode node;
+ public int root;
+ public int index;
+
+ public Combine(ScheduleNode n) {
+ this.node = n;
+ this.root = -1;
+ this.index = -1;
+ }
+ }
+
+ public class CombineGenerator {
+ Vector<Vector<ScheduleNode>> rootNodes;
+ Vector<Vector<int[]>> rootNStates;
+ Vector<Vector<ScheduleNode>> node2Combine;
+ Vector<Vector<Combine>> combine;
+ int[] lastchoices;
+ boolean first4choice;
+
+ public CombineGenerator(Vector<Vector<ScheduleNode>> rootnodes, Vector<Vector<ScheduleNode>> node2combine) {
+ this.rootNodes = rootnodes;
+ this.node2Combine = node2combine;
+ this.rootNStates = new Vector<Vector<int[]>>();
+ 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++) {
+ this.rootNStates.elementAt(i).add(new int[this.node2Combine.size()]);
+ for(int k = 0; k < this.node2Combine.size(); k++) {
+ this.rootNStates.elementAt(i).elementAt(j)[k] = 0;
+ }
+ }
+ }
+ this.combine = new Vector<Vector<Combine>>();
+ for(int i = 0; i < this.node2Combine.size(); i++) {
+ 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)));
+ }
+ }
+ this.lastchoices = null;
+ this.first4choice = false;
+ }
+
+ public Vector<Vector<Combine>> getCombine() {
+ return combine;
+ }
+
+ public boolean nextGen() {
+ boolean trial = false;
+ if(this.lastchoices == null) {
+ // first time
+ this.lastchoices = new int[this.node2Combine.size()];
+ for(int i = 0; i < this.lastchoices.length; i++) {
+ this.lastchoices[i] = 0;
+ }
+ this.first4choice = true;
+ trial = trial();
+ } else {
+ trial = trial();
+ while(!trial) {
+ // no more available combination under this choice
+ // choose another choice
+ int next = this.node2Combine.size() - 1;
+ boolean iter = false;;
+ do{
+ this.lastchoices[next]++;
+ if(this.lastchoices[next] > this.node2Combine.elementAt(next).elementAt(0).getCid()) {
+ // break the rule that a node can only be combined to nodes with smaller colorid.
+ // backtrack
+ next--;
+ iter = true;
+ } else {
+ iter = false;
+ }
+ }while(iter && !(next < 0));
+ if(next < 0) {
+ return false;
+ }
+ for(next += 1; next < this.node2Combine.size(); next++) {
+ this.lastchoices[next] = 0;
+ }
+ this.first4choice = true;
+ trial = trial();
+ }
+ }
+ return trial;
+ }
+
+ private boolean trial() {
+ boolean suc = false;
+ if(this.first4choice) {
+ // first time for each choice
+ // put all the objects of one color into the first bucket indicated by the choice
+ int next = 0;
+ suc = firstexpand(next, this.first4choice);
+ this.first4choice = false;
+ } else {
+ int next = this.node2Combine.size() - 1;
+ int layer = 0;
+ suc = innertrial(next, layer);
+ }
+ return suc;
+ }
+
+ private boolean firstexpand(int next, boolean first) {
+ for(int i = next; i < this.node2Combine.size(); i++) {
+ int choice = this.lastchoices[i];
+ for(int j = 0; j < this.node2Combine.elementAt(i).size(); j++) {
+ Combine tmp = this.combine.elementAt(i).elementAt(j);
+ if(!first) {
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ }
+ tmp.root = choice;
+ tmp.index = 0;
+ if(!first) {
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ }
+ }
+ if(first) {
+ this.rootNStates.elementAt(choice).elementAt(0)[i] = this.node2Combine.elementAt(i).size();
+ for(int j = 1; j < this.rootNodes.elementAt(choice).size(); j++) {
+ this.rootNStates.elementAt(choice).elementAt(j)[i] = 0;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean innertrial(int next, int layer) {
+ Combine tmp = this.combine.elementAt(next).lastElement();
+ // try to move it backward
+ int root = tmp.root;
+ int index = tmp.index;
+ index++;
+ if(index == this.rootNodes.elementAt(root).size()) {
+ // no more place in this color bucket
+ index = 0;
+ root++;
+ }else if(this.rootNStates.elementAt(root).elementAt(index - 1)[next] <
+ this.rootNStates.elementAt(root).elementAt(index)[next] + 2) {
+ // break the law of non-increase order inside one color bucket
+ // try next bucket of another color
+ index = 0;
+ root++;
+ }
+ if(root == this.rootNodes.size()) {
+ // no more bucket
+ // backtrack
+ root = tmp.root;
+ index = tmp.index;
+ int t = this.combine.elementAt(next).size() - 2;
+ while(true) {
+ while(!(t < 0)) {
+ tmp = this.combine.elementAt(next).elementAt(t);
+ if ((tmp.root != root) || (tmp.index != index)) {
+ break;
+ }
+ t--;
+ }
+ if(t < 0) {
+ // try the bucket in node2combine before
+ if(next - 1 < 0) {
+ return false;
+ } else {
+ return innertrial(next - 1, ++layer);
+ }
+ } else if(tmp.root != root) {
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = root;
+ tmp.index = 0;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ // make all left things in this color bucket reset
+ for(t += 1; t < this.combine.elementAt(next).size(); t++) {
+ tmp = this.combine.elementAt(next).elementAt(t);
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = root;
+ tmp.index = 0;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ }
+ if(layer != 0) {
+ return firstexpand(next+1, this.first4choice);
+ }
+ return true;
+ } else if(tmp.index != index) {
+ if(this.rootNStates.elementAt(root).elementAt(tmp.index)[next] ==
+ this.rootNStates.elementAt(root).elementAt(index)[next]) {
+ // break the law of non-increase order inside one color bucket
+ // go on search forward
+ index = tmp.index;
+ } else if(this.rootNStates.elementAt(root).elementAt(tmp.index)[next] <
+ this.rootNStates.elementAt(root).elementAt(index)[next] + 2) {
+ // break the law of non-increase order inside one color bucket
+ // and now they only differ by 1
+ // propagate this difference to see if it can fix
+ boolean suc = propagateOne(next, root, index, t, tmp);
+ if(suc) {
+ return suc;
+ } else {
+ // go on search forward
+ index = tmp.index;
+ }
+ } else {
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = root;
+ tmp.index = index;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ if(layer != 0) {
+ return firstexpand(next+1, this.first4choice);
+ }
+ return true;
+ }
+ }
+ }
+ } else {
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = root;
+ tmp.index = index;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ if(layer != 0) {
+ return firstexpand(next+1, this.first4choice);
+ }
+ return true;
+ }
+ }
+
+ private boolean propagateOne(int next, int rooti, int indexi, int ti, Combine tmp) {
+ int root = rooti;
+ int index = indexi;
+ int t = ti;
+ int rootbk = tmp.root;
+ int indexbk = tmp.index;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = root;
+ tmp.index = index;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ t += 2;
+ if(this.rootNStates.elementAt(root).elementAt(index - 1)[next] <
+ this.rootNStates.elementAt(root).elementAt(index)[next]) {
+ // need to continue propagate
+ while(t < this.combine.elementAt(next).size()) {
+ tmp = this.combine.elementAt(next).elementAt(t);
+ if ((tmp.root != root) || (tmp.index != index)) {
+ break;
+ }
+ t++;
+ }
+ if(t == this.combine.elementAt(next).size()) {
+ if(index + 1 < this.rootNodes.elementAt(root).size()) {
+ // there is available place inside the same color bucket
+ Combine tmpbk = this.combine.elementAt(next).elementAt(t - 1);
+ boolean suc = propagateOne(next, root, index + 1, t - 1, tmpbk);
+ if(!suc) {
+ // fail, roll back
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = rootbk;
+ tmp.index = indexbk;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ }
+ return suc;
+ } else if(root+1 < this.rootNodes.size()) { // check if there are another bucket
+ // yes
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = root + 1;
+ tmp.index = 0;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ return firstexpand(next+1, this.first4choice);
+ } else {
+ // no, roll back
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = rootbk;
+ tmp.index = indexbk;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ return false;
+ }
+ } else if(tmp.root != root) {
+ Combine tmpbk = this.combine.elementAt(next).elementAt(t - 1);
+ this.rootNStates.elementAt(tmpbk.root).elementAt(tmpbk.index)[next]--;
+ tmpbk.root = tmp.root;
+ tmpbk.index = 0;
+ root = tmp.root;
+ this.rootNStates.elementAt(tmpbk.root).elementAt(tmpbk.index)[next]++;
+ index = tmp.index;
+ // make all left things in this color bucket reset
+ for(t += 1; t < this.combine.elementAt(next).size(); t++) {
+ tmp = this.combine.elementAt(next).elementAt(t);
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = root;
+ tmp.index = 0;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ }
+ return firstexpand(next+1, this.first4choice);
+ } else if(tmp.index != index) {
+ Combine tmpbk = this.combine.elementAt(next).elementAt(t - 1);
+ boolean suc = propagateOne(next, root, tmp.index, t - 1, tmpbk);
+ if(!suc) {
+ // fail, roll back
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]--;
+ tmp.root = rootbk;
+ tmp.index = indexbk;
+ this.rootNStates.elementAt(tmp.root).elementAt(tmp.index)[next]++;
+ }
+ return suc;
+ }
+ // won't reach here, only to avoid compiler's complain
+ return true;
+ } else {
+ return true;
+ }
+ }
+ }
+}
\ No newline at end of file
sFStates = null;
}
+ ScheduleNode startupNode = null;
// For each ClassNode create a ScheduleNode containing it
int i = 0;
for(i = 0; i < classNodes.size(); i++) {
- ScheduleNode sn = new ScheduleNode(classNodes.elementAt(i), 0);
- classNodes.elementAt(i).setScheduleNode(sn);
+ ClassNode cn = classNodes.elementAt(i);
+ ScheduleNode sn = new ScheduleNode(cn, 0);
+ if(cn.getClassDescriptor().getSymbol().equals(TypeUtil.StartupClass)) {
+ startupNode = sn;
+ }
+ cn.setScheduleNode(sn);
scheduleNodes.add(sn);
try {
sn.calExeTime();
}
}
cdToCNodes = null;
-
+
// Break down the 'cycle's
try {
for(i = 0; i < toBreakDown.size(); i++ ) {
scheduleEdges = ssev;
ssev = null;
sorted = true;
+
+ // Set the cid of these ScheduleNode
+ Queue<ScheduleNode> toVisit = new LinkedList<ScheduleNode>();
+ toVisit.add(startupNode);
+ while(!toVisit.isEmpty()) {
+ ScheduleNode sn = toVisit.poll();
+ if(sn.getCid() == -1) {
+ // not visited before
+ sn.setCid(ScheduleNode.colorID++);
+ Iterator it_edge = sn.edges();
+ while(it_edge.hasNext()) {
+ toVisit.add((ScheduleNode)((ScheduleEdge)it_edge.next()).getTarget());
+ }
+ }
+ }
SchedulingUtil.printScheduleGraph("scheduling_ori.dot", this.scheduleNodes);
}
int reduceNum = this.scheduleNodes.size() - this.coreNum;
- // Enough cores, no need to merge more ScheduleEdge
+ // Combine some ScheduleNode if necessary
+ // May generate multiple graphs suggesting candidate schedulings
if(!(reduceNum > 0)) {
+ // Enough cores, no need to combine any ScheduleNode
this.scheduleGraphs.addElement(this.scheduleNodes);
int gid = 1;
String path = "scheduling_" + gid + ".dot";
SchedulingUtil.printScheduleGraph(path, this.scheduleNodes);
} else {
- // sort the ScheduleEdges in dececending order of transmittime
- Vector<ScheduleEdge> sEdges = new Vector<ScheduleEdge>();
- sEdges.addElement(this.scheduleEdges.elementAt(0));
- for(int i = 1; i < this.scheduleEdges.size(); i++) {
- ScheduleEdge temp = this.scheduleEdges.elementAt(i);
- int j = sEdges.size() - 1;
- do {
- if(temp.getTransTime() > sEdges.elementAt(j--).getTransTime()) {
- break;
- }
- } while(j >= 0);
- sEdges.add(j+1, temp);
- }
-
- int temp = sEdges.elementAt(reduceNum - 1).getTransTime();
- for(int i = sEdges.size() - 1; i > reduceNum - 1; i--) {
- if(sEdges.elementAt(i).getTransTime() != temp) {
- sEdges.removeElementAt(i);
- } else {
- break;
+ // Go through all the Scheudle Nodes, organize them in order of their cid
+ Vector<Vector<ScheduleNode>> sNodeVecs = new Vector<Vector<ScheduleNode>>();
+ for(int i = 0; i < this.scheduleNodes.size(); i++) {
+ ScheduleNode tmpn = this.scheduleNodes.elementAt(i);
+ int index = tmpn.getCid();
+ while(sNodeVecs.size() <= index) {
+ sNodeVecs.add(null);
}
+ if(sNodeVecs.elementAt(index) == null) {
+ sNodeVecs.setElementAt(new Vector<ScheduleNode>(), index);
+ }
+ sNodeVecs.elementAt(index).add(tmpn);
}
- int start = reduceNum - 2;
- for(; start >= 0; start--) {
- if(sEdges.elementAt(start).getTransTime() != temp) {
- start++;
- reduceNum -= start;
- break;
- }
- }
- if(start < 0) {
- start = 0;
- }
-
- // generate scheduling
- Vector candidates = new Vector();
- for(int i = start; i < sEdges.size(); i++) {
- candidates.addElement(Integer.valueOf(i));
- }
- Combination combGen = new Combination(candidates, reduceNum);
- int gid = 1;
- do {
- Vector toreduce = combGen.next();
- if(toreduce != null) {
- Vector<ScheduleEdge> reduceEdges = new Vector<ScheduleEdge>();
- for(int i = 0; i < start; i++) {
- reduceEdges.add(sEdges.elementAt(i));
- }
- for(int i = 0; i < toreduce.size(); i++) {
- reduceEdges.add(sEdges.elementAt(((Integer)toreduce.elementAt(i)).intValue()));
- }
- Vector<ScheduleNode> sNodes = generateScheduling(reduceEdges, gid++);
+
+ CombinationUtil.RootsGenerator rGen = CombinationUtil.allocateRootsGenerator(sNodeVecs, this.coreNum);
+
+ while(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);
+ int gid = 1;
+ while (cGen.nextGen()) {
+ Vector<Vector<CombinationUtil.Combine>> combine = cGen.getCombine();
+ Vector<ScheduleNode> sNodes = generateScheduling(rootNodes, combine, gid++);
this.scheduleGraphs.add(sNodes);
- reduceEdges = null;
+ combine = null;
sNodes = null;
- } else {
- break;
}
- toreduce = null;
- }while(true);
- sEdges = null;
- candidates = null;
-
+ rootNodes = null;
+ nodes2combine = null;
+ }
+ sNodeVecs = null;
}
+ // Generate schedulings according to result schedule graph
if(this.schedulings == null) {
this.schedulings = new Vector<Vector<Schedule>>();
}
this.schedulings.add(scheduling);
}
-
}
- public Vector<ScheduleNode> generateScheduling(Vector<ScheduleEdge> reduceEdges, int gid) {
+ public Vector<ScheduleNode> generateScheduling(Vector<Vector<ScheduleNode>> rootnodes, Vector<Vector<CombinationUtil.Combine>> combine, int gid) {
Vector<ScheduleNode> result = new Vector<ScheduleNode>();
// clone the ScheduleNodes
sn2sn.put(tocopy, temp);
cn2cn = null;
}
- // clone the ScheduleEdges and merge those in reduceEdges at the same time
- Vector<ScheduleEdge> toMerge = new Vector<ScheduleEdge>();
+ // clone the ScheduleEdges
for(int i = 0; i < this.scheduleEdges.size(); i++) {
ScheduleEdge sse = this.scheduleEdges.elementAt(i);
ScheduleNode csource = sn2sn.get(sse.getSource());
se.setTargetFState(sse.getTargetFState());
se.setIsclone(true);
csource.addEdge(se);
- if(reduceEdges.contains(sse)) {
- toMerge.add(se);
- }
sourcecn2cn = null;
targetcn2cn = null;
}
- sn2hash = null;
- sn2sn = null;
- for(int i = 0; i < toMerge.size(); i++) {
- ScheduleEdge sEdge = toMerge.elementAt(i);
- // merge this edge
- switch(sEdge.getType()) {
- case ScheduleEdge.NEWEDGE: {
- try {
- ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
- } catch(Exception e) {
- e.printStackTrace();
- System.exit(-1);
- }
- break;
- }
- case ScheduleEdge.TRANSEDGE: {
- try {
- ((ScheduleNode)sEdge.getSource()).mergeSEdge(sEdge);
+ // combine those nodes in combine with corresponding rootnodes
+ for(int i = 0; i < combine.size(); i++) {
+ for(int j = 0; j < combine.elementAt(i).size(); j++) {
+ CombinationUtil.Combine tmpcombine = combine.elementAt(i).elementAt(j);
+ ScheduleNode tocombine = sn2sn.get(tmpcombine.node);
+ ScheduleNode root = sn2sn.get(rootnodes.elementAt(tmpcombine.root).elementAt(tmpcombine.index));
+ 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);
+ }
+ } else {
+ root.mergeSNode(tocombine);
+ }
} catch(Exception e) {
e.printStackTrace();
System.exit(-1);
}
- break;
- }
+ result.removeElement(tocombine);
}
- result.removeElement(sEdge.getTarget());
- if(ScheduleEdge.NEWEDGE == sEdge.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.
- sEdge.setTarget(sEdge.getTargetCNode());
- sEdge.setSource(sEdge.getSourceCNode());
- sEdge.getTargetCNode().addEdge(sEdge);
- }
}
- toMerge = null;
+
+ sn2hash = null;
+ sn2sn = null;
String path = "scheduling_" + gid + ".dot";
SchedulingUtil.printScheduleGraph(path, result);
return result;
}
-
- class Combination{
- Combination tail;
- Object head;
- Vector factors;
- int selectNum;
- int resultNum;
-
- public Combination(Vector factors, int selectNum) throws Exception{
- this.factors = factors;
- if(factors.size() < selectNum) {
- throw new Exception("Error: selectNum > candidates' number in combination.");
- }
- if(factors.size() == selectNum) {
- this.resultNum = 1;
- head = null;
- tail = null;
- return;
- }
- this.head = this.factors.remove(0);
- if(selectNum == 1) {
- this.resultNum = this.factors.size() + 1;
- this.tail = null;
- return;
- }
- this.tail = new Combination((Vector)this.factors.clone(), selectNum - 1);
- this.selectNum = selectNum;
- this.resultNum = 1;
- for(int i = factors.size(); i > selectNum; i--) {
- this.resultNum *= i;
- }
- for(int i = factors.size() - selectNum; i > 0; i--) {
- this.resultNum /= i;
- }
- }
-
- public Vector next() {
- if(resultNum == 0) {
- return null;
- }
- if(head == null) {
- resultNum--;
- Vector result = this.factors;
- return result;
- }
- if(this.tail == null) {
- resultNum--;
- Vector result = new Vector();
- result.add(this.head);
- if(resultNum != 0) {
- this.head = this.factors.remove(0);
- }
- return result;
- }
- Vector result = this.tail.next();
- if(result == null) {
- if(this.factors.size() == this.selectNum) {
- this.head = null;
- this.tail = null;
- result = this.factors;
- this.resultNum--;
- return result;
- }
- this.head = this.factors.remove(0);
- try {
- this.tail = new Combination((Vector)this.factors.clone(), selectNum - 1);
- result = this.tail.next();
- } catch(Exception e) {
- e.printStackTrace();
- }
-
- }
- result.add(0, head);
- resultNum--;
- return result;
- }
- }
}
private int uid;
private int gid;
+ private int cid;
private static int nodeID=0;
+ public static int colorID = 0;
private Vector<ClassNode> classNodes;
Vector<ScheduleEdge> scheduleEdges;
public ScheduleNode(int gid) {
this.uid = ScheduleNode.nodeID++;
this.gid = gid;
+ this.cid = -1;
this.executionTime = -1;
this.classNodes = null;
this.scheduleEdges = null;
public ScheduleNode(ClassNode cn, int gid) {
this.uid = ScheduleNode.nodeID++;
this.gid = gid;
+ this.cid = -1;
this.classNodes = new Vector<ClassNode>();
this.scheduleEdges = new Vector<ScheduleEdge>();
this.classNodes.add(cn);
return uid;
}
+ public int getCid() {
+ return cid;
+ }
+
+ public void setCid(int cid) {
+ this.cid = cid;
+ }
+
public String toString() {
String temp = new String("");
for(int i = 0; i < classNodes.size(); i++) {
if(fs.uid != this.uid) {
return false;
}
+ if(fs.cid != this.cid) {
+ return false;
+ }
}
if ((fs.executionTime != this.executionTime)){
return false;
}
public int hashCode() {
- int hashcode = gid^uid^executionTime;
+ int hashcode = gid^uid^cid^executionTime;
if(this.classNodes != null) {
hashcode ^= classNodes.hashCode();
}
}
o.uid = ScheduleNode.nodeID++;
o.gid = gid;
+ o.cid = this.cid;
// Clone all the internal ClassNodes and ScheduleEdges
Vector<ClassNode> tcns = new Vector<ClassNode>();
Vector<ScheduleEdge> tses = new Vector<ScheduleEdge>();
this.executionTime += ((ScheduleNode)se.getTarget()).getExeTime();
}
}
+
+ public void mergeSNode(ScheduleNode sn) throws Exception {
+ Vector<ClassNode> targetCNodes = (Vector<ClassNode>)sn.getClassNodes();
+ Vector<ScheduleEdge> targetSEdges = (Vector<ScheduleEdge>)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;
+
+ // redirect external ScheduleEdges to this ScheduleNode
+ Iterator it_edges = sn.edges();
+ while(it_edges.hasNext()) {
+ ScheduleEdge tse = (ScheduleEdge)it_edges.next();
+ tse.setSource(this);
+ this.edges.addElement(tse);
+ }
+
+ it_edges = sn.inedges();
+ while(it_edges.hasNext()) {
+ ScheduleEdge tse = (ScheduleEdge)it_edges.next();
+ tse.setTarget(this);
+ this.inedges.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 += sn.getExeTime();
+
+ }
}
+++ /dev/null
-public class Estimator {
- flag estimate;
- flag prob;
-
- int stages;
- int time;
- float variance;
- float[] probtable;
-
- public Estimator(int stages) {
- this.stages = stages;
- this.time = 0;
- this.variance = 0;
-
- this.probtable = new float[31];
- int i = 0;
- this.probtable[i++] = (float)0.5000;
- this.probtable[i++] = (float)0.5398;
- this.probtable[i++] = (float)0.5793;
- this.probtable[i++] = (float)0.6179;
- this.probtable[i++] = (float)0.6554;
- this.probtable[i++] = (float)0.6915;
- this.probtable[i++] = (float)0.7257;
- this.probtable[i++] = (float)0.7580;
- this.probtable[i++] = (float)0.7881;
- this.probtable[i++] = (float)0.8159;
- this.probtable[i++] = (float)0.8413;
- this.probtable[i++] = (float)0.8643;
- this.probtable[i++] = (float)0.8849;
- this.probtable[i++] = (float)0.9032;
- this.probtable[i++] = (float)0.9192;
- this.probtable[i++] = (float)0.9332;
- this.probtable[i++] = (float)0.9452;
- this.probtable[i++] = (float)0.9554;
- this.probtable[i++] = (float)0.9641;
- this.probtable[i++] = (float)0.9713;
- this.probtable[i++] = (float)0.9772;
- this.probtable[i++] = (float)0.9821;
- this.probtable[i++] = (float)0.9861;
- this.probtable[i++] = (float)0.9893;
- this.probtable[i++] = (float)0.9918;
- this.probtable[i++] = (float)0.9938;
- this.probtable[i++] = (float)0.9953;
- this.probtable[i++] = (float)0.9965;
- this.probtable[i++] = (float)0.9974;
- this.probtable[i++] = (float)0.9981;
- this.probtable[i++] = (float)0.9987;
- }
-
- public boolean estimate(int time, float variance2) {
- //System.printI(0xff30);
- this.time += time;
- this.variance += variance2;
- --this.stages;
- //System.printI(0xff31);
- //System.printI(this.stages);
- //System.printI(this.time);
- //System.printI((int)this.variance);
- if(this.stages == 0) {
- //System.printI(0xff32);
- //System.printString("variance2: " + (int)(this.variance*100) + "(/100); ");
- this.variance = Math.sqrtf(this.variance);
- //System.printString("variance: " + (int)(this.variance*100) + "(/100)\n");
- return true;
- }
- //System.printI(0xff33);
- return false;
- }
-
- public float getProbability(int x, int y) {
- int l = x;
- int r = y;
- if(x > y) {
- l = y;
- r = x;
- }
-
- float prob = prob(r) - prob(l);
- return prob;
- }
-
- private float prob(int s) {
- int tmp = (int)((s - this.time) * 10 / this.variance);
- //System.printString(tmp + "\n");
- int abs = (int)Math.abs(tmp);
- float prob = 0;
- if(abs > this.probtable.length - 1) {
- prob = 1;
- } else {
- prob = this.probtable[abs];
- }
- if(tmp < 0) {
- return (float)1.0 - prob;
- } else {
- return prob;
- }
- }
-
- public int getTime() {
- return this.time;
- }
-
- public float getVariance() {
- return this.variance;
- }
-
-}
+++ /dev/null
-task t1(StartupObject s{initialstate}) {
- //System.printString("task t1\n");
- int stages = 2;
- Estimator estimator = new Estimator(stages){estimate};
- for(int i = 0; i < stages; ++i) {
- Stage stage = new Stage(i){sampling};
- }
-
- taskexit(s{!initialstate});
-}
-
-task t2(Stage s{sampling}) {
- //System.printString("task t2\n");
-
- s.sampling();
-
- taskexit(s{!sampling, estimate});
-}
-
-task t3(Stage s{estimate}) {
- //System.printString("task t3\n");
-
- s.estimate();
-
- taskexit(s{!estimate, merge});
-}
-
-task t4(Estimator e{estimate}, Stage s{merge}) {
- //System.printString("task t4\n");
-
- boolean fake = false;
- boolean finish = e.estimate(s.getAntTime(), s.getAntVariance2());
-
- if(finish) {
- //System.printI(0xff40);
- taskexit(e{!estimate, prob}, s{!merge});
- } else {
- //System.printI(0xff41);
- taskexit(s{!merge});
- }
-}
-
-task t5(Estimator e{prob}) {
- //System.printString("task t5\n");
-
- int x = 10;
- int y = 20;
- //System.printString("x: " + x + "; y: " + y + "\n");
- //System.printString("The anticipate days need to finish this project is: " + e.getTime() + "\n");
- //System.printString("And the anticipate variance is: " + (int)(e.getVariance()*100) + "(/100)\n");
- float prob = e.getProbability(x, y);
-
- //System.printString("The probability of this project to be finished in " + x + " to " + y + " days is: " + (int)(prob*100) + "%\n");
- //System.printI((int)(prob*100));
- taskexit(e{!prob});
-}
+++ /dev/null
-public class Stage {
- flag sampling;
- flag estimate;
- flag merge;
-
- int ID;
-
- int[] samplings;
- int optime;
- int nortime;
- int petime;
- int time;
- float variance2;
-
- public Stage(int id) {
- //System.printI(0xff20);
- this.ID = id;
-
- this.samplings = new int[10];
- //System.printI(0xff21);
- for(int i = 0; i < this.samplings.length; ++i) {
- this.samplings[i] = 0;
- //System.printString(tint + "; ");
- }
- //System.printI(0xff23);
-
- this.optime = 0;
- this.nortime = 0;
- this.petime = 0;
- this.time = 0;
- this.variance2 = 0;
- //System.printI(0xff24);
- }
-
- public void sampling() {
- //System.printI(0xff00);
- int tint = 0;
- //System.printI(this.samplings.length);
- int i = 0;
- if(this.ID == 0) {
- //System.printI(0xff01);
- this.samplings[i++] = 33;
- this.samplings[i++] = 36;
- this.samplings[i++] = 27;
- this.samplings[i++] = 15;
- this.samplings[i++] = 43;
- this.samplings[i++] = 35;
- this.samplings[i++] = 36;
- this.samplings[i++] = 42;
- this.samplings[i++] = 49;
- this.samplings[i++] = 21;
- } else if(this.ID == 1) {
- //System.printI(0xff02);
- this.samplings[i++] = 12;
- this.samplings[i++] = 27;
- this.samplings[i++] = 40;
- this.samplings[i++] = 9;
- this.samplings[i++] = 13;
- this.samplings[i++] = 26;
- this.samplings[i++] = 40;
- this.samplings[i++] = 26;
- this.samplings[i++] = 22;
- this.samplings[i++] = 36;
- }
- //System.printI(0xff03);
- }
-
- public void estimate() {
- //System.printI(0xff10);
- int highest = this.samplings[0];
- //System.printI(0xff12);
- int lowest = this.samplings[0];
- int sum = this.samplings[0];
- //System.printI(0xff13);
- //System.printI(this.samplings.length);
- for(int i = 1; i < this.samplings.length; ++i) {
- //System.printI(0xff14);
- int temp = this.samplings[i];
- if(temp > highest) {
- highest = temp;
- } else if(temp < lowest) {
- lowest = temp;
- }
- sum += temp;
- }
- //System.printI(0xff15);
- sum = sum - highest - lowest;
- int ordinary = sum / (this.samplings.length - 2);
- this.optime = lowest;;
- this.petime = highest;
- this.nortime = ordinary;
- //System.printI(0xff16);
- this.time = (this.optime + 4 * this.nortime + this.petime) / 6;
- //System.printI(0xff17);
- this.variance2 = (float)(this.optime - this.petime) * (float)(this.optime - this.petime) / (float)36.0;
- //System.printI(0xff18);
- //System.printString("Op time: " + this.optime + "; Nor time: " + this.nortime + "; Pe time: " + this.petime + "; variance2: " + (int)(this.variance2*100) + "(/100)\n");
- }
-
- public int getAntTime() {
- return this.time;
- }
-
- public float getAntVariance2() {
- return this.variance2;
- }
-
-}
int newRate = 1;
String cdname = cd.getSymbol();
if(cdname.equals("SeriesRunner")) {
- newRate = 10;
+ newRate = 16;
} else if(cdname.equals("MapWorker")) {
newRate = 6;
} else if(cdname.equals("ReduceWorker")) {
/*do {
tint = r.nextInt()%10;
} while(tint <= 0);*/
- tint = 1;
+ tint = 3;
((FEdge)it_edges.next()).setExeTime(tint);
}
}
}
System.out.print("Selected schedulings with least exectution time " + processTime + ": \n\t");
for(int i = 0; i < selectedScheduling.size(); i++) {
- System.out.print(selectedScheduling.elementAt(i) + ", ");
+ System.out.print((selectedScheduling.elementAt(i) + 1) + ", ");
}
System.out.println();