1 package Analysis.Scheduling;
3 import Analysis.TaskStateAnalysis.*;
6 import Util.GraphNode.SCC;
8 import java.io.FileInputStream;
11 /** This class holds flag transition diagram(s) can be put on one core.
13 public class ScheduleAnalysis {
16 TaskAnalysis taskanalysis;
18 Vector<ScheduleNode> scheduleNodes;
19 Vector<ClassNode> classNodes;
20 Vector<ScheduleEdge> scheduleEdges;
21 Hashtable<ClassDescriptor, ClassNode> cd2ClassNode;
22 boolean sorted = false;
26 int scheduleThreshold;
28 Vector<Vector<ScheduleNode>> scheduleGraphs;
30 public ScheduleAnalysis(State state,
31 TaskAnalysis taskanalysis) {
33 this.taskanalysis = taskanalysis;
34 this.scheduleNodes = new Vector<ScheduleNode>();
35 this.classNodes = new Vector<ClassNode>();
36 this.scheduleEdges = new Vector<ScheduleEdge>();
37 this.cd2ClassNode = new Hashtable<ClassDescriptor, ClassNode>();
38 this.transThreshold = 45; // defaultly 45
39 this.scheduleThreshold = 1000; // defaultly 1000
41 this.scheduleGraphs = null;
44 public void setTransThreshold(int tt) {
45 this.transThreshold = tt;
48 public void setScheduleThreshold(int stt) {
49 this.scheduleThreshold = stt;
52 public int getCoreNum() {
56 public void setCoreNum(int coreNum) {
57 this.coreNum = coreNum;
60 public Vector<Vector<ScheduleNode>> getScheduleGraphs() {
61 return this.scheduleGraphs;
65 public Vector<ScheduleEdge> getSEdges4Test() {
69 public void schedule() {
71 Vector<ScheduleEdge> toBreakDown = new Vector<ScheduleEdge>();
72 ScheduleNode startupNode = null;
74 // necessary preparation such as read profile info etc.
77 startupNode = buildCFSTG(toBreakDown);
79 treeTransform(toBreakDown, startupNode);
80 // do CFSTG transform to explore the potential parallelism as much
83 // mappint to real multi-core processor
85 } catch (Exception e) {
91 private void preSchedule() {
94 // set up profiling data
95 if(state.USEPROFILE) {
96 java.util.Hashtable<String, TaskInfo> taskinfos =
97 new java.util.Hashtable<String, TaskInfo>();
98 this.readProfileInfo(taskinfos);
101 Iterator it_classes =
102 state.getClassSymbolTable().getDescriptorsIterator();
103 while(it_classes.hasNext()) {
104 ClassDescriptor cd = (ClassDescriptor) it_classes.next();
106 Vector rootnodes = this.taskanalysis.getRootNodes(cd);
107 if(rootnodes!=null) {
108 Iterator it_rootnodes = rootnodes.iterator();
109 while(it_rootnodes.hasNext()) {
110 FlagState root = (FlagState)it_rootnodes.next();
111 Vector allocatingTasks = root.getAllocatingTasks();
112 if(allocatingTasks != null) {
113 for(int k = 0; k < allocatingTasks.size(); k++) {
115 (TaskDescriptor)allocatingTasks.elementAt(k);
117 this.taskanalysis.getFEdgesFromTD(td);
118 int numEdges = fev.size();
119 for(int j = 0; j < numEdges; j++) {
120 FEdge pfe = fev.elementAt(j);
122 taskinfos.get(td.getSymbol());
123 tint = taskinfo.m_exetime[pfe.getTaskExitIndex()];
124 pfe.setExeTime(tint);
126 taskinfo.m_probability[pfe.getTaskExitIndex()];
127 pfe.setProbability(idouble);
129 if((taskinfo.m_newobjinfo.elementAt(pfe.getTaskExitIndex()) != null)
130 && (taskinfo.m_newobjinfo.elementAt(pfe.getTaskExitIndex()).containsKey(cd.getSymbol()))) {
131 newRate = taskinfo.m_newobjinfo.elementAt(pfe.getTaskExitIndex()).get(cd.getSymbol());
133 pfe.addNewObjInfo(cd, newRate, idouble);
134 if(taskinfo.m_byObj != -1) {
135 ((FlagState)pfe.getSource()).setByObj(taskinfo.m_byObj);
143 Iterator it_flags = this.taskanalysis.getFlagStates(cd).iterator();
144 while(it_flags.hasNext()) {
145 FlagState fs = (FlagState)it_flags.next();
146 Iterator it_edges = fs.edges();
147 while(it_edges.hasNext()) {
148 FEdge edge = (FEdge)it_edges.next();
149 TaskInfo taskinfo = taskinfos.get(edge.getTask().getSymbol());
150 tint = taskinfo.m_exetime[edge.getTaskExitIndex()];
151 edge.setExeTime(tint);
152 double idouble = taskinfo.m_probability[edge.getTaskExitIndex()];
153 edge.setProbability(idouble);
154 if(taskinfo.m_byObj != -1) {
155 ((FlagState)edge.getSource()).setByObj(taskinfo.m_byObj);
163 randomProfileSetting();
167 private void checkBackEdge() {
168 // Indentify backedges
169 Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();
170 while(it_classes.hasNext()) {
171 ClassDescriptor cd=(ClassDescriptor) it_classes.next();
173 Set<FlagState> fss = this.taskanalysis.getFlagStates(cd);
174 SCC scc=GraphNode.DFS.computeSCC(fss);
175 if (scc.hasCycles()) {
176 for(int i=0; i<scc.numSCC(); i++) {
177 if (scc.hasCycle(i)) {
178 Set cycleset = scc.getSCC(i);
179 Iterator it_fs = cycleset.iterator();
180 while(it_fs.hasNext()) {
181 FlagState fs = (FlagState)it_fs.next();
182 Iterator it_edges = fs.edges();
183 while(it_edges.hasNext()) {
184 FEdge edge = (FEdge)it_edges.next();
185 if(cycleset.contains(edge.getTarget())) {
187 edge.setisbackedge(true);
199 private void readProfileInfo(java.util.Hashtable<String, TaskInfo> taskinfos) {
201 // read in profile data and set
202 FileInputStream inStream = new FileInputStream("/scratch/profile.rst");
203 byte[] b = new byte[1024 * 100];
204 int length = inStream.read(b);
206 System.out.print("No content in input file: /scratch/profile.rst\n");
209 String profiledata = new String(b, 0, length);
211 // profile data format:
212 // taskname, numoftaskexits(; exetime, probability, numofnewobjtypes(, newobj type, num of objs)+)+
213 int inindex = profiledata.indexOf('\n');
214 while((inindex != -1) ) {
215 String inline = profiledata.substring(0, inindex);
216 profiledata = profiledata.substring(inindex + 1);
217 //System.printString(inline + "\n");
218 int tmpinindex = inline.indexOf(',');
219 if(tmpinindex == -1) {
222 String inname = inline.substring(0, tmpinindex);
223 String inint = inline.substring(tmpinindex + 1);
224 while(inint.startsWith(" ")) {
225 inint = inint.substring(1);
227 tmpinindex = inint.indexOf(',');
228 if(tmpinindex == -1) {
231 int numofexits = Integer.parseInt(inint.substring(0, tmpinindex));
232 TaskInfo tinfo = new TaskInfo(numofexits);
233 inint = inint.substring(tmpinindex + 1);
234 while(inint.startsWith(" ")) {
235 inint = inint.substring(1);
237 tmpinindex = inint.indexOf(';');
238 int byObj = Integer.parseInt(inint.substring(0, tmpinindex));
240 tinfo.m_byObj = byObj;
242 inint = inint.substring(tmpinindex + 1);
243 while(inint.startsWith(" ")) {
244 inint = inint.substring(1);
246 for(int i = 0; i < numofexits; i++) {
247 String tmpinfo = null;
248 if(i < numofexits - 1) {
249 tmpinindex = inint.indexOf(';');
250 tmpinfo = inint.substring(0, tmpinindex);
251 inint = inint.substring(tmpinindex + 1);
252 while(inint.startsWith(" ")) {
253 inint = inint.substring(1);
259 tmpinindex = tmpinfo.indexOf(',');
260 tinfo.m_exetime[i] = Integer.parseInt(tmpinfo.substring(0, tmpinindex));
261 tmpinfo = tmpinfo.substring(tmpinindex + 1);
262 while(tmpinfo.startsWith(" ")) {
263 tmpinfo = tmpinfo.substring(1);
265 tmpinindex = tmpinfo.indexOf(',');
266 tinfo.m_probability[i] = Double.parseDouble(tmpinfo.substring(0, tmpinindex));
267 tmpinfo = tmpinfo.substring(tmpinindex + 1);
268 while(tmpinfo.startsWith(" ")) {
269 tmpinfo = tmpinfo.substring(1);
271 tmpinindex = tmpinfo.indexOf(',');
273 if(tmpinindex == -1) {
274 numofnobjs = Integer.parseInt(tmpinfo);
275 if(numofnobjs != 0) {
276 System.err.println("Error profile data format!");
280 tinfo.m_newobjinfo.setElementAt(new Hashtable<String,Integer>(), i);
281 numofnobjs = Integer.parseInt(tmpinfo.substring(0, tmpinindex));
282 tmpinfo = tmpinfo.substring(tmpinindex + 1);
283 while(tmpinfo.startsWith(" ")) {
284 tmpinfo = tmpinfo.substring(1);
286 for(int j = 0; j < numofnobjs; j++) {
287 tmpinindex = tmpinfo.indexOf(',');
288 String nobjtype = tmpinfo.substring(0, tmpinindex);
289 tmpinfo = tmpinfo.substring(tmpinindex + 1);
290 while(tmpinfo.startsWith(" ")) {
291 tmpinfo = tmpinfo.substring(1);
294 if(j < numofnobjs - 1) {
295 tmpinindex = tmpinfo.indexOf(',');
296 objnum = Integer.parseInt(tmpinfo.substring(0, tmpinindex));
297 tmpinfo = tmpinfo.substring(tmpinindex + 1);
298 while(tmpinfo.startsWith(" ")) {
299 tmpinfo = tmpinfo.substring(1);
302 objnum = Integer.parseInt(tmpinfo);
304 tinfo.m_newobjinfo.elementAt(i).put(nobjtype, objnum);
308 taskinfos.put(inname, tinfo);
309 inindex = profiledata.indexOf('\n');
311 } catch(Exception e) {
317 private void randomProfileSetting() {
318 // Randomly set the newRate and probability of FEdges
319 java.util.Random r=new java.util.Random();
321 for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator(); it_classes.hasNext();) {
322 ClassDescriptor cd=(ClassDescriptor) it_classes.next();
324 Vector rootnodes=this.taskanalysis.getRootNodes(cd);
325 if(rootnodes!=null) {
326 for(Iterator it_rootnodes=rootnodes.iterator(); it_rootnodes.hasNext();) {
327 FlagState root=(FlagState)it_rootnodes.next();
328 Vector allocatingTasks = root.getAllocatingTasks();
329 if(allocatingTasks != null) {
330 for(int k = 0; k < allocatingTasks.size(); k++) {
331 TaskDescriptor td = (TaskDescriptor)allocatingTasks.elementAt(k);
332 Vector<FEdge> fev = (Vector<FEdge>)this.taskanalysis.getFEdgesFromTD(td);
333 int numEdges = fev.size();
335 for(int j = 0; j < numEdges; j++) {
336 FEdge pfe = fev.elementAt(j);
337 if(numEdges - j == 1) {
338 pfe.setProbability(total);
340 if((total != 0) && (total != 1)) {
342 tint = r.nextInt()%total;
345 pfe.setProbability(tint);
349 // tint = r.nextInt()%10;
350 // } while(tint <= 0);
351 //int newRate = tint;
352 //int newRate = (j+1)%2+1;
354 String cdname = cd.getSymbol();
355 if((cdname.equals("SeriesRunner")) ||
356 (cdname.equals("MDRunner")) ||
357 (cdname.equals("Stage")) ||
358 (cdname.equals("AppDemoRunner")) ||
359 (cdname.equals("FilterBankAtom")) ||
360 (cdname.equals("Grid")) ||
361 (cdname.equals("Fractal"))) {
363 } else if(cdname.equals("SentenceParser")) {
367 // tint = r.nextInt()%100;
368 // } while(tint <= 0);
369 // int probability = tint;
370 int probability = 100;
371 pfe.addNewObjInfo(cd, newRate, probability);
379 Iterator it_flags = this.taskanalysis.getFlagStates(cd).iterator();
380 while(it_flags.hasNext()) {
381 FlagState fs = (FlagState)it_flags.next();
382 Iterator it_edges = fs.edges();
384 while(it_edges.hasNext()) {
386 // tint = r.nextInt()%10;
387 // } while(tint <= 0);
389 FEdge edge = (FEdge)it_edges.next();
390 edge.setExeTime(tint);
391 if((fs.getClassDescriptor().getSymbol().equals("MD"))
392 && (edge.getTask().getSymbol().equals("t6"))) {
393 if(edge.isbackedge()) {
394 if(edge.getTarget().equals(edge.getSource())) {
395 edge.setProbability(93.75);
397 edge.setProbability(3.125);
400 edge.setProbability(3.125);
404 if(!it_edges.hasNext()) {
405 edge.setProbability(total);
407 if((total != 0) && (total != 1)) {
409 tint = r.nextInt()%total;
412 edge.setProbability(tint);
421 private ScheduleNode buildCFSTG(Vector<ScheduleEdge> toBreakDown) {
422 Hashtable<ClassDescriptor, ClassNode> cdToCNodes =
423 new Hashtable<ClassDescriptor, ClassNode>();
424 // Build the combined flag transition diagram
425 // First, for each class create a ClassNode
426 Iterator it_classes = state.getClassSymbolTable().getDescriptorsIterator();
427 while(it_classes.hasNext()) {
428 ClassDescriptor cd = (ClassDescriptor) it_classes.next();
429 Set<FlagState> fStates = taskanalysis.getFlagStates(cd);
431 //Sort flagState nodes inside this ClassNode
432 Vector<FlagState> sFStates = FlagState.DFS.topology(fStates, null);
434 Vector rootnodes = taskanalysis.getRootNodes(cd);
435 if(((rootnodes != null) && (rootnodes.size() > 0))
436 || (cd.getSymbol().equals(TypeUtil.StartupClass))) {
437 ClassNode cNode = new ClassNode(cd, sFStates);
438 cNode.setSorted(true);
439 classNodes.add(cNode);
440 cd2ClassNode.put(cd, cNode);
441 cdToCNodes.put(cd, cNode);
445 if(cd.getSymbol().equals("C")) {
446 cNode.setTransTime(45);
453 ScheduleNode startupNode = null;
454 // For each ClassNode create a ScheduleNode containing it
456 for(i = 0; i < classNodes.size(); i++) {
457 ClassNode cn = classNodes.elementAt(i);
458 ScheduleNode sn = new ScheduleNode(cn, 0);
459 if(cn.getClassDescriptor().getSymbol().equals(TypeUtil.StartupClass)) {
462 cn.setScheduleNode(sn);
463 scheduleNodes.add(sn);
466 } catch (Exception e) {
471 // Create 'new' edges between the ScheduleNodes.
472 //Vector<ScheduleEdge> toBreakDown = new Vector<ScheduleEdge>();
473 for(i = 0; i < classNodes.size(); i++) {
474 ClassNode cNode = classNodes.elementAt(i);
475 ClassDescriptor cd = cNode.getClassDescriptor();
476 Vector rootnodes = taskanalysis.getRootNodes(cd);
477 if(rootnodes != null) {
478 for(int h = 0; h < rootnodes.size(); h++) {
479 FlagState root=(FlagState)rootnodes.elementAt(h);
480 Vector allocatingTasks = root.getAllocatingTasks();
481 if(allocatingTasks != null) {
482 for(int k = 0; k < allocatingTasks.size(); k++) {
483 TaskDescriptor td = (TaskDescriptor)allocatingTasks.elementAt(k);
484 Vector<FEdge> fev = (Vector<FEdge>)taskanalysis.getFEdgesFromTD(td);
485 int numEdges = fev.size();
486 ScheduleNode sNode = cNode.getScheduleNode();
487 for(int j = 0; j < numEdges; j++) {
488 FEdge pfe = fev.elementAt(j);
489 FEdge.NewObjInfo noi = pfe.getNewObjInfo(cd);
490 if ((noi == null) || (noi.getNewRate() == 0) || (noi.getProbability() == 0)) {
491 // fake creating edge, do not need to create corresponding 'new' edge
494 if(noi.getRoot() == null) {
495 // set root FlagState
498 FlagState pfs = (FlagState)pfe.getTarget();
499 ClassDescriptor pcd = pfs.getClassDescriptor();
500 ClassNode pcNode = cdToCNodes.get(pcd);
502 ScheduleEdge sEdge = new ScheduleEdge(sNode,
505 ScheduleEdge.NEWEDGE,
508 sEdge.setSourceCNode(pcNode);
509 sEdge.setTargetCNode(cNode);
510 sEdge.setTargetFState(root);
511 sEdge.setNewRate(noi.getNewRate());
512 sEdge.setProbability(noi.getProbability());
513 pcNode.getScheduleNode().addEdge(sEdge);
514 scheduleEdges.add(sEdge);
515 if((j !=0 ) || (k != 0) || (h != 0)) {
516 toBreakDown.add(sEdge);
521 allocatingTasks = null;
532 private void treeTransform(Vector<ScheduleEdge> toBreakDown,
533 ScheduleNode startupNode) {
536 // Break down the 'cycle's
538 for(i = 0; i < toBreakDown.size(); i++ ) {
539 cloneSNodeList(toBreakDown.elementAt(i), false);
542 } catch (Exception e) {
547 // Remove fake 'new' edges
548 for(i = 0; i < scheduleEdges.size(); i++) {
549 ScheduleEdge se = (ScheduleEdge)scheduleEdges.elementAt(i);
550 if((0 == se.getNewRate()) || (0 == se.getProbability())) {
551 scheduleEdges.removeElement(se);
552 scheduleNodes.removeElement(se.getTarget());
556 // Do topology sort of the ClassNodes and ScheduleEdges.
557 Vector<ScheduleEdge> ssev = new Vector<ScheduleEdge>();
558 Vector<ScheduleNode> tempSNodes = ClassNode.DFS.topology(scheduleNodes, ssev);
559 scheduleNodes.removeAllElements();
560 scheduleNodes = tempSNodes;
562 scheduleEdges.removeAllElements();
563 scheduleEdges = ssev;
567 // Set the cid of these ScheduleNode
568 Queue<ScheduleNode> toVisit = new LinkedList<ScheduleNode>();
569 toVisit.add(startupNode);
570 while(!toVisit.isEmpty()) {
571 ScheduleNode sn = toVisit.poll();
572 if(sn.getCid() == -1) {
573 // not visited before
574 sn.setCid(ScheduleNode.colorID++);
575 Iterator it_edge = sn.edges();
576 while(it_edge.hasNext()) {
577 toVisit.add((ScheduleNode)((ScheduleEdge)it_edge.next()).getTarget());
583 if(this.state.PRINTSCHEDULING) {
584 SchedulingUtil.printScheduleGraph("scheduling_ori.dot",
589 private void CFSTGTransform() {
592 //Access the ScheduleEdges in reverse topology order
593 Hashtable<FEdge, Vector<ScheduleEdge>> fe2ses = new Hashtable<FEdge, Vector<ScheduleEdge>>();
594 Hashtable<ScheduleNode, Vector<FEdge>> sn2fes = new Hashtable<ScheduleNode, Vector<FEdge>>();
595 ScheduleNode preSNode = null;
596 for(i = scheduleEdges.size(); i > 0; i--) {
597 ScheduleEdge se = (ScheduleEdge)scheduleEdges.elementAt(i-1);
598 if(ScheduleEdge.NEWEDGE == se.getType()) {
599 if(preSNode == null) {
600 preSNode = (ScheduleNode)se.getSource();
603 boolean split = false;
604 FEdge fe = se.getFEdge();
605 if(fe.getSource() == fe.getTarget()) {
608 int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
611 for(int j = 1; j< repeat; j++ ) {
612 cloneSNodeList(se, true);
615 se.setProbability(100);
618 rate = (int)Math.ceil(se.getListExeTime()/ calInExeTime(se.getSourceFState()));
619 } catch (Exception e) {
622 for(int j = rate - 1; j > 0; j--) {
623 for(int k = repeat; k > 0; k--) {
624 cloneSNodeList(se, true);
627 } catch (Exception e) {
632 // if preSNode is not the same as se's source ScheduleNode
633 // handle any ScheduleEdges previously put into fe2ses whose source ScheduleNode is preSNode
634 boolean same = (preSNode == se.getSource());
636 // check the topology sort, only process those after se.getSource()
637 if(preSNode.getFinishingTime() < se.getSource().getFinishingTime()) {
638 if(sn2fes.containsKey(preSNode)) {
639 Vector<FEdge> fes = sn2fes.remove(preSNode);
640 for(int j = 0; j < fes.size(); j++) {
641 FEdge tempfe = fes.elementAt(j);
642 Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
643 ScheduleEdge tempse = ses.elementAt(0);
644 int temptime = tempse.getListExeTime();
645 // find out the ScheduleEdge with least exeTime
646 for(int k = 1; k < ses.size(); k++) {
647 int ttemp = ses.elementAt(k).getListExeTime();
648 if(ttemp < temptime) {
649 tempse = ses.elementAt(k);
654 handleScheduleEdge(tempse, true);
655 ses.removeElement(tempse);
656 // handle other ScheduleEdges
657 for(int k = 0; k < ses.size(); k++) {
658 handleScheduleEdge(ses.elementAt(k), false);
661 fe2ses.remove(tempfe);
666 preSNode = (ScheduleNode)se.getSource();
669 // if fe is the last task inside this ClassNode, delay the expanding and merging until we find all such 'new' edges
670 // associated with a last task inside this ClassNode
671 if(!fe.getTarget().edges().hasNext()) {
672 if(fe2ses.get(fe) == null) {
673 fe2ses.put(fe, new Vector<ScheduleEdge>());
675 if(sn2fes.get((ScheduleNode)se.getSource()) == null) {
676 sn2fes.put((ScheduleNode)se.getSource(), new Vector<FEdge>());
678 if(!fe2ses.get(fe).contains(se)) {
679 fe2ses.get(fe).add(se);
681 if(!sn2fes.get((ScheduleNode)se.getSource()).contains(fe)) {
682 sn2fes.get((ScheduleNode)se.getSource()).add(fe);
685 // As this is not a last task, first handle available ScheduleEdges previously put into fe2ses
686 if((same) && (sn2fes.containsKey(preSNode))) {
687 Vector<FEdge> fes = sn2fes.remove(preSNode);
688 for(int j = 0; j < fes.size(); j++) {
689 FEdge tempfe = fes.elementAt(j);
690 Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
691 ScheduleEdge tempse = ses.elementAt(0);
692 int temptime = tempse.getListExeTime();
693 // find out the ScheduleEdge with least exeTime
694 for(int k = 1; k < ses.size(); k++) {
695 int ttemp = ses.elementAt(k).getListExeTime();
696 if(ttemp < temptime) {
697 tempse = ses.elementAt(k);
702 handleScheduleEdge(tempse, true);
703 ses.removeElement(tempse);
704 // handle other ScheduleEdges
705 for(int k = 0; k < ses.size(); k++) {
706 handleScheduleEdge(ses.elementAt(k), false);
709 fe2ses.remove(tempfe);
714 if((!(se.getTransTime() < this.transThreshold)) && (se.getSourceCNode().getTransTime() < se.getTransTime())) {
716 splitSNode(se, true);
718 // handle this ScheduleEdge
719 handleScheduleEdge(se, true);
725 if(!fe2ses.isEmpty()) {
726 Set<FEdge> keys = fe2ses.keySet();
727 Iterator it_keys = keys.iterator();
728 while(it_keys.hasNext()) {
729 FEdge tempfe = (FEdge)it_keys.next();
730 Vector<ScheduleEdge> ses = fe2ses.get(tempfe);
731 ScheduleEdge tempse = ses.elementAt(0);
732 int temptime = tempse.getListExeTime();
733 // find out the ScheduleEdge with least exeTime
734 for(int k = 1; k < ses.size(); k++) {
735 int ttemp = ses.elementAt(k).getListExeTime();
736 if(ttemp < temptime) {
737 tempse = ses.elementAt(k);
742 handleScheduleEdge(tempse, true);
743 ses.removeElement(tempse);
744 // handle other ScheduleEdges
745 for(int k = 0; k < ses.size(); k++) {
746 handleScheduleEdge(ses.elementAt(k), false);
757 if(this.state.PRINTSCHEDULING) {
758 SchedulingUtil.printScheduleGraph("scheduling_extend.dot", this.scheduleNodes);
762 private void handleScheduleEdge(ScheduleEdge se,
766 int repeat = (int)Math.ceil(se.getNewRate() * se.getProbability() / 100);
769 if(se.getListExeTime() == 0) {
772 rate = (int)Math.ceil((se.getTransTime() - calInExeTime(se.getSourceFState()))/ se.getListExeTime());
777 } catch (Exception e) {
781 // clone the whole ScheduleNode lists starting with se's target
782 for(int j = 1; j < repeat; j++ ) {
783 cloneSNodeList(se, true);
786 se.setProbability(100);
790 // clone the whole ScheduleNode lists starting with se's target
791 for(int j = 0; j < repeat; j++ ) {
792 cloneSNodeList(se, true);
795 se.setProbability(100);
798 // merge the original ScheduleNode to the source ScheduleNode
799 ((ScheduleNode)se.getSource()).mergeSEdge(se);
800 scheduleNodes.remove(se.getTarget());
801 scheduleEdges.remove(se);
802 // As se has been changed into an internal edge inside a ScheduleNode,
803 // change the source and target of se from original ScheduleNodes
805 if(se.getType() == ScheduleEdge.NEWEDGE) {
806 se.setTarget(se.getTargetCNode());
807 //se.setSource(se.getSourceCNode());
808 //se.getTargetCNode().addEdge(se);
809 se.getSourceCNode().addEdge(se);
812 // clone the whole ScheduleNode lists starting with se's target
813 for(int j = 1; j < repeat; j++ ) {
814 cloneSNodeList(se, true);
817 se.setProbability(100);
819 } catch (Exception e) {
825 private void cloneSNodeList(ScheduleEdge sEdge,
826 boolean copyIE) throws Exception {
827 Hashtable<ClassNode, ClassNode> cn2cn = new Hashtable<ClassNode, ClassNode>(); // hashtable from classnode in orignal se's targe to cloned one
828 ScheduleNode csNode = (ScheduleNode)((ScheduleNode)sEdge.getTarget()).clone(cn2cn, 0);
829 scheduleNodes.add(csNode);
831 // Clone all the external in ScheduleEdges
834 Vector inedges = sEdge.getTarget().getInedgeVector();
835 for(i = 0; i < inedges.size(); i++) {
836 ScheduleEdge tse = (ScheduleEdge)inedges.elementAt(i);
838 switch(tse.getType()) {
839 case ScheduleEdge.NEWEDGE: {
840 se = new ScheduleEdge(csNode, "new", tse.getFstate(), tse.getType(), 0);
841 se.setProbability(100);
846 case ScheduleEdge.TRANSEDGE: {
847 se = new ScheduleEdge(csNode, "transmit", tse.getFstate(), tse.getType(), 0);
848 se.setProbability(tse.getProbability());
849 se.setNewRate(tse.getNewRate());
854 throw new Exception("Error: not valid ScheduleEdge here");
857 se.setSourceCNode(tse.getSourceCNode());
858 se.setTargetCNode(cn2cn.get(tse.getTargetCNode()));
859 se.setFEdge(tse.getFEdge());
860 se.setTargetFState(tse.getTargetFState());
862 tse.getSource().addEdge(se);
863 scheduleEdges.add(se);
867 sEdge.getTarget().removeInedge(sEdge);
868 sEdge.setTarget(csNode);
869 csNode.getInedgeVector().add(sEdge);
870 sEdge.setTargetCNode(cn2cn.get(sEdge.getTargetCNode()));
871 sEdge.setIsclone(true);
874 Queue<ScheduleNode> toClone = new LinkedList<ScheduleNode>(); // all nodes to be cloned
875 Queue<ScheduleNode> clone = new LinkedList<ScheduleNode>(); //clone nodes
876 Queue<Hashtable> qcn2cn = new LinkedList<Hashtable>(); // queue of the mappings of classnodes inside cloned ScheduleNode
877 Vector<ScheduleNode> origins = new Vector<ScheduleNode>(); // queue of source ScheduleNode cloned
878 Hashtable<ScheduleNode, ScheduleNode> sn2sn = new Hashtable<ScheduleNode, ScheduleNode>(); // mapping from cloned ScheduleNode to clone ScheduleNode
880 toClone.add((ScheduleNode)sEdge.getTarget());
881 origins.addElement((ScheduleNode)sEdge.getTarget());
882 sn2sn.put((ScheduleNode)sEdge.getTarget(), csNode);
884 while(!toClone.isEmpty()) {
885 Hashtable<ClassNode, ClassNode> tocn2cn = new Hashtable<ClassNode, ClassNode>();
886 csNode = clone.poll();
887 ScheduleNode osNode = toClone.poll();
888 cn2cn = qcn2cn.poll();
889 // Clone all the external ScheduleEdges and the following ScheduleNodes
890 Vector edges = osNode.getEdgeVector();
891 for(i = 0; i < edges.size(); i++) {
892 ScheduleEdge tse = (ScheduleEdge)edges.elementAt(i);
893 ScheduleNode tSNode = (ScheduleNode)((ScheduleNode)tse.getTarget()).clone(tocn2cn, 0);
894 scheduleNodes.add(tSNode);
896 toClone.add((ScheduleNode)tse.getTarget());
897 origins.addElement((ScheduleNode)tse.getTarget());
898 sn2sn.put((ScheduleNode)tse.getTarget(), tSNode);
900 ScheduleEdge se = null;
901 switch(tse.getType()) {
902 case ScheduleEdge.NEWEDGE: {
903 se = new ScheduleEdge(tSNode, "new", tse.getFstate(), tse.getType(), 0);
907 case ScheduleEdge.TRANSEDGE: {
908 se = new ScheduleEdge(tSNode, "transmit", tse.getFstate(), tse.getType(), 0);
913 throw new Exception("Error: not valid ScheduleEdge here");
916 se.setSourceCNode(cn2cn.get(tse.getSourceCNode()));
917 se.setTargetCNode(tocn2cn.get(tse.getTargetCNode()));
918 se.setFEdge(tse.getFEdge());
919 se.setTargetFState(tse.getTargetFState());
920 se.setProbability(tse.getProbability());
921 se.setNewRate(tse.getNewRate());
924 scheduleEdges.add(se);
938 private int calInExeTime(FlagState fs) throws Exception {
940 ClassDescriptor cd = fs.getClassDescriptor();
941 ClassNode cNode = cd2ClassNode.get(cd);
942 exeTime = cNode.getFlagStates().elementAt(0).getExeTime() - fs.getExeTime();
944 Vector inedges = cNode.getInedgeVector();
945 // Now that there are associate ScheduleEdges, there may be multiple inedges of a ClassNode
946 if(inedges.size() > 1) {
947 throw new Exception("Error: ClassNode's inedges more than one!");
949 if(inedges.size() > 0) {
950 ScheduleEdge sEdge = (ScheduleEdge)inedges.elementAt(0);
951 cNode = (ClassNode)sEdge.getSource();
952 exeTime += cNode.getFlagStates().elementAt(0).getExeTime();
958 exeTime = cNode.getScheduleNode().getExeTime() - exeTime;
962 private ScheduleNode splitSNode(ScheduleEdge se,
964 assert(ScheduleEdge.NEWEDGE == se.getType());
966 FEdge fe = se.getFEdge();
967 FlagState fs = (FlagState)fe.getTarget();
968 FlagState nfs = (FlagState)fs.clone();
969 fs.getEdgeVector().removeAllElements();
970 nfs.getInedgeVector().removeAllElements();
971 ClassNode sCNode = se.getSourceCNode();
973 // split the subtree whose root is nfs from the whole flag transition tree
974 Vector<FlagState> sfss = sCNode.getFlagStates();
975 Vector<FlagState> fStates = new Vector<FlagState>();
976 Queue<FlagState> toiterate = new LinkedList<FlagState>();
979 while(!toiterate.isEmpty()) {
980 FlagState tfs = toiterate.poll();
981 Iterator it_edges = tfs.edges();
982 while(it_edges.hasNext()) {
983 FlagState temp = (FlagState)((FEdge)it_edges.next()).getTarget();
984 if(!fStates.contains(temp)) {
987 sfss.removeElement(temp);
992 Vector<FlagState> sFStates = FlagState.DFS.topology(fStates, null);
994 // create a ClassNode and ScheduleNode for this subtree
995 ClassNode cNode = new ClassNode(sCNode.getClassDescriptor(), sFStates);
996 ScheduleNode sNode = new ScheduleNode(cNode, 0);
997 cNode.setScheduleNode(sNode);
998 cNode.setSorted(true);
999 cNode.setTransTime(sCNode.getTransTime());
1000 classNodes.add(cNode);
1001 scheduleNodes.add(sNode);
1004 } catch (Exception e) {
1005 e.printStackTrace();
1007 // flush the exeTime of fs and its ancestors
1010 while(!toiterate.isEmpty()) {
1011 FlagState tfs = toiterate.poll();
1012 int ttime = tfs.getExeTime();
1013 Iterator it_inedges = tfs.inedges();
1014 while(it_inedges.hasNext()) {
1015 FEdge fEdge = (FEdge)it_inedges.next();
1016 FlagState temp = (FlagState)fEdge.getSource();
1017 int time = fEdge.getExeTime() + ttime;
1018 if(temp.getExeTime() > time) {
1019 temp.setExeTime(time);
1020 toiterate.add(temp);
1026 // create a 'trans' ScheudleEdge between this new ScheduleNode and se's source ScheduleNode
1027 ScheduleEdge sEdge = new ScheduleEdge(sNode, "transmit", fs, ScheduleEdge.TRANSEDGE, 0); //new ScheduleEdge(sNode, "transmit", cNode.getClassDescriptor(), false, 0);
1029 sEdge.setSourceCNode(sCNode);
1030 sEdge.setTargetCNode(cNode);
1031 sEdge.setTargetFState(nfs);
1033 // Add calculation codes for calculating transmit time of an object
1034 sEdge.setTransTime(cNode.getTransTime());
1035 se.getSource().addEdge(sEdge);
1036 scheduleEdges.add(sEdge);
1037 // remove the ClassNodes and internal ScheduleEdges out of this subtree
1038 // to the new ScheduleNode
1039 ScheduleNode oldSNode = (ScheduleNode)se.getSource();
1040 Iterator it_isEdges = oldSNode.getScheduleEdgesIterator();
1041 Vector<ScheduleEdge> toremove = new Vector<ScheduleEdge>();
1042 Vector<ClassNode> rCNodes = new Vector<ClassNode>();
1043 rCNodes.addElement(sCNode);
1044 if(it_isEdges != null) {
1045 while(it_isEdges.hasNext()) {
1046 ScheduleEdge tse = (ScheduleEdge)it_isEdges.next();
1047 if(rCNodes.contains(tse.getSourceCNode())) {
1048 if(sCNode.equals(tse.getSourceCNode())) {
1049 if (!(tse.getSourceFState().equals(fs))
1050 && (sFStates.contains(tse.getSourceFState()))) {
1051 tse.setSource(cNode);
1052 tse.setSourceCNode(cNode);
1057 sNode.getScheduleEdges().addElement(tse);
1058 sNode.getClassNodes().addElement(tse.getTargetCNode());
1059 rCNodes.addElement(tse.getTargetCNode());
1060 oldSNode.getClassNodes().removeElement(tse.getTargetCNode());
1061 toremove.addElement(tse);
1065 oldSNode.getScheduleEdges().removeAll(toremove);
1067 // redirect ScheudleEdges out of this subtree to the new ScheduleNode
1068 Iterator it_sEdges = se.getSource().edges();
1069 while(it_sEdges.hasNext()) {
1070 ScheduleEdge tse = (ScheduleEdge)it_sEdges.next();
1071 if(!(tse.equals(se)) && !(tse.equals(sEdge))
1072 && (tse.getSourceCNode().equals(sCNode))) {
1073 if(!(tse.getSourceFState().equals(fs))
1074 && (sFStates.contains(tse.getSourceFState()))) {
1075 tse.setSource(sNode);
1076 tse.setSourceCNode(cNode);
1077 sNode.getEdgeVector().addElement(tse);
1082 se.getSource().getEdgeVector().removeAll(toremove);
1089 //merge se into its source ScheduleNode
1090 sNode.setCid(((ScheduleNode)se.getSource()).getCid());
1091 ((ScheduleNode)se.getSource()).mergeSEdge(se);
1092 scheduleNodes.remove(se.getTarget());
1093 scheduleEdges.removeElement(se);
1094 // As se has been changed into an internal edge inside a ScheduleNode,
1095 // change the source and target of se from original ScheduleNodes
1097 if(se.getType() == ScheduleEdge.NEWEDGE) {
1098 se.setTarget(se.getTargetCNode());
1099 //se.setSource(se.getSourceCNode());
1100 //se.getTargetCNode().addEdge(se);
1101 se.getSourceCNode().addEdge(se);
1104 sNode.setCid(ScheduleNode.colorID++);
1105 handleScheduleEdge(se, true);
1107 } catch (Exception e) {
1108 e.printStackTrace();
1115 // TODO: restrict the number of generated scheduling according to the setted
1116 // scheduleThreshold
1117 private void coreMapping() throws Exception {
1118 if(this.coreNum == -1) {
1119 throw new Exception("Error: un-initialized coreNum when doing scheduling.");
1122 if(this.scheduleGraphs == null) {
1123 this.scheduleGraphs = new Vector<Vector<ScheduleNode>>();
1126 int reduceNum = this.scheduleNodes.size() - this.coreNum;
1128 // Combine some ScheduleNode if necessary
1129 // May generate multiple graphs suggesting candidate schedulings
1130 if(!(reduceNum > 0)) {
1131 // Enough cores, no need to combine any ScheduleNode
1132 this.scheduleGraphs.addElement(this.scheduleNodes);
1134 if(this.state.PRINTSCHEDULING) {
1135 String path = "scheduling_" + gid + ".dot";
1136 SchedulingUtil.printScheduleGraph(path, this.scheduleNodes);
1139 // Go through all the Schedule Nodes, organize them in order of their cid
1140 Vector<Vector<ScheduleNode>> sNodeVecs =
1141 SchedulingUtil.rangeScheduleNodes(this.scheduleNodes);
1143 CombinationUtil.RootsGenerator rGen =
1144 CombinationUtil.allocateRootsGenerator(sNodeVecs,
1148 while((gid <= this.scheduleThreshold) && (rGen.nextGen())) {
1149 // first get the chosen rootNodes
1150 Vector<Vector<ScheduleNode>> rootNodes = rGen.getRootNodes();
1151 Vector<Vector<ScheduleNode>> nodes2combine = rGen.getNode2Combine();
1153 CombinationUtil.CombineGenerator cGen =
1154 CombinationUtil.allocateCombineGenerator(rootNodes,
1156 while((gid <= this.scheduleThreshold) && cGen.nextGen()) {
1157 Vector<Vector<CombinationUtil.Combine>> combine = cGen.getCombine();
1158 Vector<ScheduleNode> sNodes = SchedulingUtil.generateScheduleGraph(this.state,
1164 this.scheduleGraphs.add(sNodes);
1169 nodes2combine = null;
1175 static class TaskInfo {
1176 public int m_numofexits;
1177 public int[] m_exetime;
1178 public double[] m_probability;
1179 public Vector<Hashtable<String, Integer>> m_newobjinfo;
1182 public TaskInfo(int numofexits) {
1183 this.m_numofexits = numofexits;
1184 this.m_exetime = new int[this.m_numofexits];
1185 this.m_probability = new double[this.m_numofexits];
1186 this.m_newobjinfo = new Vector<Hashtable<String, Integer>>();
1187 for(int i = 0; i < this.m_numofexits; i++) {
1188 this.m_newobjinfo.add(null);