1 package Analysis.Scheduling;
4 import java.io.FileOutputStream;
5 import java.io.PrintStream;
6 import java.io.PrintWriter;
7 import java.util.Hashtable;
8 import java.util.Iterator;
9 import java.util.Random;
10 import java.util.Vector;
12 import Analysis.OwnershipAnalysis.OwnershipAnalysis;
13 import Analysis.TaskStateAnalysis.FEdge;
14 import Analysis.TaskStateAnalysis.FlagState;
15 import Analysis.TaskStateAnalysis.TaskAnalysis;
16 import IR.ClassDescriptor;
18 import IR.TaskDescriptor;
21 public class MCImplSynthesis {
24 ScheduleAnalysis scheduleAnalysis;
25 TaskAnalysis taskAnalysis;
26 OwnershipAnalysis ownershipAnalysis;
27 ScheduleSimulator scheduleSimulator;
30 int scheduleThreshold;
32 int generateThreshold;
36 public MCImplSynthesis(State state,
38 OwnershipAnalysis oa) {
40 this.coreNum = state.CORENUM;
41 this.taskAnalysis = ta;
42 this.ownershipAnalysis = oa;
43 this.scheduleAnalysis = new ScheduleAnalysis(state,
45 this.scheduleAnalysis.setCoreNum(this.coreNum);
46 this.scheduleSimulator = new ScheduleSimulator(this.coreNum,
49 this.scheduleThreshold = 1000;
50 this.probThreshold = 0;
51 this.generateThreshold = 30;
52 //this.rand = new Random();
55 public int getCoreNum() {
56 return this.scheduleAnalysis.getCoreNum();
59 public int getScheduleThreshold() {
60 return scheduleThreshold;
63 public void setScheduleThreshold(int scheduleThreshold) {
64 this.scheduleThreshold = scheduleThreshold;
67 public int getProbThreshold() {
71 public void setProbThreshold(int probThreshold) {
72 this.probThreshold = probThreshold;
75 public int getGenerateThreshold() {
76 return generateThreshold;
79 public void setGenerateThreshold(int generateThreshold) {
80 this.generateThreshold = generateThreshold;
83 public Vector<Schedule> synthesis() {
84 // Print stuff to the original output and error streams.
85 // The stuff printed through the 'origOut' and 'origErr' references
86 // should go to the console on most systems while the messages
87 // printed through the 'System.out' and 'System.err' will end up in
88 // the files we created for them.
89 //origOut.println ("\nRedirect: Round #2");
90 //System.out.println ("Test output via 'SimulatorResult.out'.");
91 //origOut.println ("Test output via 'origOut' reference.");
93 // Save the current standard input, output, and error streams
94 // for later restoration.
95 PrintStream origOut = System.out;
97 // Create a new output stream for the standard output.
98 PrintStream stdout = null;
100 stdout = new PrintStream(
101 new FileOutputStream(this.state.outputdir + "SimulatorResult_"
102 + this.coreNum + ".out"));
103 } catch (Exception e) {
104 // Sigh. Couldn't open the file.
105 System.out.println("Redirect: Unable to open output file!");
109 // Print stuff to the original output and error streams.
110 // On most systems all of this will end up on your console when you
111 // run this application.
112 //origOut.println ("\nRedirect: Round #1");
113 //System.out.println ("Test output via 'System.out'.");
114 //origOut.println ("Test output via 'origOut' reference.");
116 // Set the System out and err streams to use our replacements.
117 System.setOut(stdout);
119 Vector<Schedule> scheduling = null;
120 Vector<ScheduleNode> schedulinggraph = null;
123 // generate multiple schedulings
124 this.scheduleAnalysis.setScheduleThreshold(this.scheduleThreshold);
125 this.scheduleAnalysis.schedule(this.generateThreshold);
126 if(this.generateThreshold > 5) {
127 this.generateThreshold = 5;
130 Vector<Vector<ScheduleNode>> scheduleGraphs = null;
131 Vector<Vector<ScheduleNode>> newscheduleGraphs =
132 this.scheduleAnalysis.getScheduleGraphs();
133 Vector<Vector<Schedule>> schedulings = new Vector<Vector<Schedule>>();
134 Vector<Integer> selectedSchedulings = new Vector<Integer>();
135 Vector<Vector<SimExecutionEdge>> selectedSimExeGraphs =
136 new Vector<Vector<SimExecutionEdge>>();
138 // check all multi-parameter tasks
139 Vector<TaskDescriptor> multiparamtds = new Vector<TaskDescriptor>();
140 Iterator it_tasks = this.state.getTaskSymbolTable().getDescriptorsIterator();
141 while(it_tasks.hasNext()) {
142 TaskDescriptor td = (TaskDescriptor)it_tasks.next();
143 if(td.numParameters() > 1) {
144 multiparamtds.addElement(td);
150 int bestexetime = Integer.MAX_VALUE;
151 Random rand = new Random();
152 // simulate the generated schedulings and try to optimize it
154 System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
155 System.out.print("Simulate and optimize round: #" + tryindex + ": \n");
156 gid += newscheduleGraphs.size();
157 if(scheduleGraphs != null) {
158 for(int i = 0; i < scheduleGraphs.size(); i++) {
159 Vector<ScheduleNode> tmpgraph = scheduleGraphs.elementAt(i);
160 for(int j = 0; j < tmpgraph.size(); j++) {
161 tmpgraph.elementAt(j).getEdgeVector().clear();
162 tmpgraph.elementAt(j).getInedgeVector().clear();
167 scheduleGraphs.clear();
169 scheduleGraphs = newscheduleGraphs;
171 // get scheduling layouts from schedule graphs
172 for(int i = 0; i < scheduleGraphs.size(); i++) {
173 Vector<ScheduleNode> scheduleGraph = scheduleGraphs.elementAt(i);
174 Vector<Schedule> tmpscheduling =
175 generateScheduling(scheduleGraph, multiparamtds);
176 schedulings.add(tmpscheduling);
177 scheduleGraph = null;
178 tmpscheduling = null;
180 selectedSchedulings.clear();
181 for(int i = 0; i < selectedSimExeGraphs.size(); i++) {
182 selectedSimExeGraphs.elementAt(i).clear();
184 selectedSimExeGraphs.clear();
185 int tmpexetime = this.scheduleSimulator.simulate(schedulings,
187 selectedSimExeGraphs);
188 if(tmpexetime < bestexetime) {
189 bestexetime = tmpexetime;
190 if(scheduling != null) {
192 for(int j = 0; j < schedulinggraph.size(); j++) {
193 schedulinggraph.elementAt(j).getEdgeVector().clear();
194 schedulinggraph.elementAt(j).getInedgeVector().clear();
196 schedulinggraph.clear();
198 scheduling = schedulings.elementAt(selectedSchedulings.elementAt(0));
199 schedulinggraph = scheduleGraphs.elementAt(selectedSchedulings.elementAt(0));
200 System.out.print("end of: #" + tryindex + " (bestexetime: " + bestexetime + ")\n");
201 System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
203 } else if(tmpexetime == bestexetime) {
204 System.out.print("end of: #" + tryindex + " (bestexetime: " + bestexetime + ")\n");
205 System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
207 if((Math.abs(rand.nextInt()) % 100) < this.probThreshold) {
214 // try to optimize the best one scheduling
215 newscheduleGraphs = optimizeScheduling(scheduleGraphs,
217 selectedSimExeGraphs,
219 this.scheduleThreshold);
220 if(tmpexetime < bestexetime) {
221 scheduleGraphs.remove(selectedSchedulings.elementAt(0));
223 }while(newscheduleGraphs != null); // TODO: could it possibly lead to endless loop?
225 if(scheduleGraphs != null) {
226 scheduleGraphs.clear();
228 scheduleGraphs = null;
229 newscheduleGraphs = null;
232 selectedSchedulings.clear();
233 selectedSchedulings = null;
234 for(int i = 0; i < selectedSimExeGraphs.size(); i++) {
235 selectedSimExeGraphs.elementAt(i).clear();
237 selectedSimExeGraphs.clear();
238 selectedSimExeGraphs = null;
239 multiparamtds.clear();
240 multiparamtds = null;
242 System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
243 System.out.print("selected bestexetime: " + bestexetime + "\n");
244 String path = this.state.outputdir + "scheduling_selected.dot";
245 SchedulingUtil.printScheduleGraph(path, schedulinggraph);
247 // Close the streams.
251 System.setOut(origOut);
252 } catch (Exception e) {
253 origOut.println("Redirect: Unable to close files!");
256 schedulinggraph.clear();
257 schedulinggraph = null;
263 // get the distribution info of new search algorithm
264 public void distribution() {
265 // Print stuff to the original output and error streams.
266 // The stuff printed through the 'origOut' and 'origErr' references
267 // should go to the console on most systems while the messages
268 // printed through the 'System.out' and 'System.err' will end up in
269 // the files we created for them.
270 //origOut.println ("\nRedirect: Round #2");
271 //System.out.println ("Test output via 'SimulatorResult.out'.");
272 //origOut.println ("Test output via 'origOut' reference.");
274 // Save the current standard input, output, and error streams
275 // for later restoration.
276 PrintStream origOut = System.out;
278 // Create a new output stream for the standard output.
279 PrintStream stdout = null;
281 stdout = new PrintStream(
282 new FileOutputStream(this.state.outputdir + "SimulatorResult_"
283 + this.coreNum + ".out"));
284 } catch (Exception e) {
285 // Sigh. Couldn't open the file.
286 System.out.println("Redirect: Unable to open output file!");
290 // Print stuff to the original output and error streams.
291 // On most systems all of this will end up on your console when you
292 // run this application.
293 //origOut.println ("\nRedirect: Round #1");
294 //System.out.println ("Test output via 'System.out'.");
295 //origOut.println ("Test output via 'origOut' reference.");
297 // Set the System out and err streams to use our replacements.
298 System.setOut(stdout);
300 // generate multiple schedulings
301 this.scheduleAnalysis.setScheduleThreshold(1000);
302 this.scheduleAnalysis.schedule(20);
303 this.generateThreshold = 5;
304 this.probThreshold = 0;
306 Vector<Vector<ScheduleNode>> scheduleGraphs = null;
307 Vector<Vector<ScheduleNode>> totestscheduleGraphs =
308 this.scheduleAnalysis.getScheduleGraphs();
309 Vector<Vector<Schedule>> schedulings = new Vector<Vector<Schedule>>();
310 Vector<Integer> selectedSchedulings = new Vector<Integer>();
311 Vector<Vector<SimExecutionEdge>> selectedSimExeGraphs =
312 new Vector<Vector<SimExecutionEdge>>();
314 // check all multi-parameter tasks
315 Vector<TaskDescriptor> multiparamtds = new Vector<TaskDescriptor>();
316 Iterator it_tasks = this.state.getTaskSymbolTable().getDescriptorsIterator();
317 while(it_tasks.hasNext()) {
318 TaskDescriptor td = (TaskDescriptor)it_tasks.next();
319 if(td.numParameters() > 1) {
320 multiparamtds.addElement(td);
325 File file=new File(this.state.outputdir + "distributeinfo_s_" + this.coreNum + ".out");
326 FileOutputStream dotstream = null;
327 File file2=new File(this.state.outputdir + "distributeinfo_o_" + this.coreNum + ".out");
328 FileOutputStream dotstream2 = null;
330 dotstream = new FileOutputStream(file,false);
331 dotstream2 = new FileOutputStream(file2,false);
332 } catch (Exception e) {
336 PrintWriter output = new java.io.PrintWriter(dotstream, true);
337 PrintWriter output2 = new java.io.PrintWriter(dotstream2, true);
338 output.println("start time(1,000,000 cycles): " + totestscheduleGraphs.size());
339 output2.println("optimized time(1,000,000 cycles): " + totestscheduleGraphs.size());
340 for(int ii = 0; ii < 1/*totestscheduleGraphs.size()*/; ii++) {
341 Vector<Vector<ScheduleNode>> newscheduleGraphs =
342 new Vector<Vector<ScheduleNode>>();
343 newscheduleGraphs.add(totestscheduleGraphs.elementAt(ii));
345 int bestexetime = Integer.MAX_VALUE;
347 Vector<Schedule> scheduling = null;
348 Vector<ScheduleNode> schedulinggraph = null;
349 boolean isfirst = true;
350 Random rand = new Random();
351 // simulate the generated schedulings and try to optimize it
352 System.out.print("=========================================================\n");
353 System.out.print("# " + ii + ": \n");
355 System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
356 System.out.print("Simulate and optimize round: #" + tryindex + ": \n");
357 gid += newscheduleGraphs.size();
358 if(scheduleGraphs != null) {
359 for(int i = 0; i < scheduleGraphs.size(); i++) {
360 Vector<ScheduleNode> tmpgraph = scheduleGraphs.elementAt(i);
361 for(int j = 0; j < tmpgraph.size(); j++) {
362 ScheduleNode snode = tmpgraph.elementAt(j);
363 snode.getEdgeVector().clear();
364 snode.getInedgeVector().clear();
365 snode.getScheduleEdges().clear();
366 snode.getClassNodes().clear();
371 scheduleGraphs.clear();
373 scheduleGraphs = newscheduleGraphs;
375 // get scheduling layouts from schedule graphs
376 for(int i = 0; i < scheduleGraphs.size(); i++) {
377 Vector<ScheduleNode> scheduleGraph = scheduleGraphs.elementAt(i);
378 Vector<Schedule> tmpscheduling =
379 generateScheduling(scheduleGraph, multiparamtds);
380 schedulings.add(tmpscheduling);
381 scheduleGraph = null;
382 tmpscheduling = null;
384 selectedSchedulings.clear();
385 for(int i = 0; i < selectedSimExeGraphs.size(); i++) {
386 selectedSimExeGraphs.elementAt(i).clear();
388 selectedSimExeGraphs.clear();
389 int tmpexetime = this.scheduleSimulator.simulate(schedulings,
391 selectedSimExeGraphs);
393 output.println(((float)tmpexetime/1000000));
396 if(tmpexetime < bestexetime) {
397 bestexetime = tmpexetime;
398 if(scheduling != null) {
400 for(int j = 0; j < schedulinggraph.size(); j++) {
401 ScheduleNode snode = schedulinggraph.elementAt(j);
402 snode.getEdgeVector().clear();
403 snode.getInedgeVector().clear();
404 snode.getScheduleEdges().clear();
405 snode.getClassNodes().clear();
407 schedulinggraph.clear();
409 scheduling = schedulings.elementAt(selectedSchedulings.elementAt(0));
410 schedulinggraph = scheduleGraphs.elementAt(selectedSchedulings.elementAt(0));
412 System.out.print("end of: #" + tryindex + " (bestexetime: " + bestexetime + ")\n");
413 System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
414 } else if(tmpexetime == bestexetime) {
415 System.out.print("end of: #" + tryindex + " (bestexetime: " + bestexetime + ")\n");
416 System.out.print("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
418 if((Math.abs(rand.nextInt()) % 100) < this.probThreshold) {
425 // try to optimize theschedulings best one scheduling
426 newscheduleGraphs = optimizeScheduling(scheduleGraphs,
428 selectedSimExeGraphs,
430 this.scheduleThreshold);
431 if(tmpexetime < bestexetime) {
432 scheduleGraphs.remove(selectedSchedulings.elementAt(0));
434 }while(newscheduleGraphs != null); // TODO: could it possibly lead to endless loop?
436 scheduleGraphs.clear();
437 scheduleGraphs = null;
439 schedulinggraph = null;
440 if(newscheduleGraphs != null) {
441 newscheduleGraphs.clear();
443 newscheduleGraphs = null;
444 totestscheduleGraphs.elementAt(ii).clear();
445 for(int i = 0; i < schedulings.size(); i++) {
446 schedulings.elementAt(i).clear();
449 selectedSchedulings.clear();
450 for(int i = 0; i < selectedSimExeGraphs.size(); i++) {
451 selectedSimExeGraphs.elementAt(i).clear();
453 selectedSimExeGraphs.clear();
455 output2.println(((float)bestexetime/1000000));
456 System.out.print("=========================================================\n");
459 if(scheduleGraphs != null) {
460 scheduleGraphs.clear();
462 scheduleGraphs = null;
463 totestscheduleGraphs = null;
464 for(int i = 0; i < schedulings.size(); i++) {
465 schedulings.elementAt(i).clear();
469 selectedSchedulings.clear();
470 selectedSchedulings = null;
471 selectedSimExeGraphs.clear();
472 selectedSimExeGraphs = null;
473 multiparamtds.clear();
474 multiparamtds = null;
476 // Close the streams.
482 System.setOut(origOut);
483 } catch (Exception e) {
484 origOut.println("Redirect: Unable to close files!");
490 private Vector<Vector<ScheduleNode>> optimizeScheduling(Vector<Vector<ScheduleNode>> scheduleGraphs,
491 Vector<Integer> selectedScheduleGraphs,
492 Vector<Vector<SimExecutionEdge>> selectedSimExeGraphs,
495 if(this.coreNum == 1) {
500 Vector<Vector<ScheduleNode>> optimizeschedulegraphs = null;
504 for(int i = 0; i < selectedScheduleGraphs.size(); i++) {
505 Vector<ScheduleNode> schedulegraph = scheduleGraphs.elementAt(
506 selectedScheduleGraphs.elementAt(i));
507 Vector<SimExecutionEdge> simexegraph = selectedSimExeGraphs.elementAt(i);
508 Vector<SimExecutionEdge> criticalPath = analyzeCriticalPath(simexegraph);
509 Vector<Vector<ScheduleNode>> tmposchedulegraphs = optimizeCriticalPath(schedulegraph,
513 if(tmposchedulegraphs != null) {
514 if(optimizeschedulegraphs == null) {
515 optimizeschedulegraphs = new Vector<Vector<ScheduleNode>>();
517 optimizeschedulegraphs.addAll(tmposchedulegraphs);
518 lgid += tmposchedulegraphs.size();
519 left -= tmposchedulegraphs.size();
521 schedulegraph = null;
524 tmposchedulegraphs = null;
528 schedulegraph = null;
531 tmposchedulegraphs = null;
534 return optimizeschedulegraphs;
537 private Vector<SimExecutionEdge> analyzeCriticalPath(Vector<SimExecutionEdge> simexegraph) {
538 // first figure out the critical path
539 Vector<SimExecutionEdge> criticalPath = new Vector<SimExecutionEdge>();
540 SimExecutionNode senode = (SimExecutionNode)simexegraph.elementAt(0).getSource();
541 getCriticalPath(senode, criticalPath);
542 computeBestStartPoint(criticalPath);
547 private void computeBestStartPoint(Vector<SimExecutionEdge> criticalPath) {
548 // calculate the earliest start time of each task on the critial path
549 for(int i = 0; i < criticalPath.size(); i++) {
550 SimExecutionEdge seedge = criticalPath.elementAt(i);
551 Vector<SimExecutionEdge> predicates = seedge.getPredicates();
552 if(predicates != null) {
555 // check the latest finish time of all the predicates
556 for(int j = 0; j < predicates.size(); j++) {
557 SimExecutionEdge predicate = predicates.elementAt(j);
558 int tmptime = predicate.getBestStartPoint() + predicate.getWeight();
559 if(tmptime > starttime) {
561 seedge.setLastpredicateEdge(predicate);
562 if(predicate.getTd() != null) {
563 seedge.setLastpredicateNode((SimExecutionNode)predicate.getTarget());
566 seedge.setLastpredicateNode((SimExecutionNode)predicate.getSource());
570 seedge.setBestStartPoint(starttime);
571 } else if(seedge.getSource().getInedgeVector().size() > 0) {
572 // should have only one in edge
573 int starttime = ((SimExecutionNode)seedge.getSource()).getTimepoint();
574 seedge.setBestStartPoint(starttime);
577 seedge.setBestStartPoint(0);
583 // TODO: currently only get one critical path. It's possible that there are
584 // multiple critical paths and some of them can not be optimized while others
585 // can. Need to fix up for this situation.
586 private int getCriticalPath(SimExecutionNode senode,
587 Vector<SimExecutionEdge> criticalPath) {
588 Vector<SimExecutionEdge> edges = (Vector<SimExecutionEdge>)senode.getEdgeVector();
589 if((edges == null) || (edges.size() == 0)) {
593 Vector<SimExecutionEdge> subcriticalpath = new Vector<SimExecutionEdge>();
594 SimExecutionEdge edge = edges.elementAt(0);
595 int sum = edge.getWeight() + getCriticalPath((SimExecutionNode)edge.getTarget(),
597 criticalPath.clear();
598 criticalPath.add(edge);
599 criticalPath.addAll(subcriticalpath);
600 for(int i = 1; i < edges.size(); i++) {
601 edge = edges.elementAt(i);
602 subcriticalpath.clear();
603 int tmpsum = edge.getWeight()
604 + getCriticalPath((SimExecutionNode)edge.getTarget(),
607 // find a longer path
609 criticalPath.clear();
610 criticalPath.add(edge);
611 criticalPath.addAll(subcriticalpath);
615 subcriticalpath.clear();
616 subcriticalpath = null;
620 private Vector<Vector<ScheduleNode>> optimizeCriticalPath(Vector<ScheduleNode> scheduleGraph,
621 Vector<SimExecutionEdge> criticalPath,
624 Vector<Vector<ScheduleNode>> optimizeschedulegraphs = null;
628 // for test, print out the criticalPath
629 if(this.state.PRINTCRITICALPATH) {
630 SchedulingUtil.printCriticalPath(this.state.outputdir + "criticalpath_" + lgid + ".dot",
634 // first check all seedges whose real start point is late than predicted
635 // earliest start time and group them
636 int opcheckpoint = Integer.MAX_VALUE;
637 Vector<Integer> sparecores = null;
638 // first group according to core index,
639 // then group according to task type
640 Hashtable<Integer, Hashtable<TaskDescriptor, Vector<SimExecutionEdge>>> tooptimize =
641 new Hashtable<Integer, Hashtable<TaskDescriptor, Vector<SimExecutionEdge>>>();
642 for(int i = 0; i < criticalPath.size(); i++) {
643 SimExecutionEdge seedge = criticalPath.elementAt(i);
644 int starttime = seedge.getBestStartPoint();
645 if(starttime < ((SimExecutionNode)seedge.getSource()).getTimepoint()) {
646 // no restrictions due to data dependencies
647 // have potential to be parallelled and start execution earlier
648 seedge.setFixedTime(false);
649 // consider to optimize it only when its predicates can NOT
650 // be optimized, otherwise first considering optimize its predicates
651 SimExecutionEdge lastpredicateedge = seedge.getLastpredicateEdge();
652 if(lastpredicateedge.isFixedTime()) {
653 if(opcheckpoint >= starttime) {
654 // only consider the tasks with smallest best start time
655 if(opcheckpoint > starttime) {
657 opcheckpoint = starttime;
658 SimExecutionNode lastpredicatenode = seedge.getLastpredicateNode();
659 int timepoint = lastpredicatenode.getTimepoint();
660 if(lastpredicateedge.getTd() == null) {
662 timepoint += lastpredicateedge.getWeight();
664 // mapping to critical path
665 for(int index = 0; index < criticalPath.size(); index++) {
666 SimExecutionEdge tmpseedge = criticalPath.elementAt(index);
667 SimExecutionNode tmpsenode =
668 (SimExecutionNode)tmpseedge.getTarget();
669 if(tmpsenode.getTimepoint() > timepoint) {
670 // get the spare core info
671 sparecores = tmpsenode.getSpareCores();
676 int corenum = seedge.getCoreNum();
677 if(!tooptimize.containsKey(corenum)) {
678 tooptimize.put(corenum,
679 new Hashtable<TaskDescriptor, Vector<SimExecutionEdge>>());
681 if(!tooptimize.get(corenum).containsKey(seedge.getTd())) {
682 tooptimize.get(corenum).put(seedge.getTd(),
683 new Vector<SimExecutionEdge>());
685 tooptimize.get(corenum).get(seedge.getTd()).add(seedge);
691 if(tooptimize.size() > 0) {
692 Iterator<Integer> it_cores = tooptimize.keySet().iterator();
693 // check if it is possible to optimize these tasks
694 if((sparecores == null) || (sparecores.size() == 0)) {
695 // lack of spare cores
696 while(it_cores.hasNext()) {
697 int corenum = it_cores.next();
698 Hashtable<TaskDescriptor, Vector<SimExecutionEdge>> candidatetasks =
699 tooptimize.get(corenum);
700 if(candidatetasks.keySet().size() > 1) {
701 // there are multiple tasks could be optimized to start from
702 // this timepoint, try to change original execution order
703 Iterator<TaskDescriptor> it_tds = candidatetasks.keySet().iterator();
704 TaskDescriptor td = null;
705 int starttime = Integer.MAX_VALUE;
707 TaskDescriptor tmptd = it_tds.next();
708 Vector<SimExecutionEdge> seedges = candidatetasks.get(td);
709 int tmptime = ((SimExecutionNode)seedges.elementAt(0).getSource()).getTimepoint();
710 for(int i = 1; i < seedges.size(); i++) {
711 int ttime = ((SimExecutionNode)seedges.elementAt(i).getSource()).getTimepoint();
712 if(ttime < tmptime) {
716 if(tmptime < starttime) {
721 }while(it_tds.hasNext());
723 // TODO: only consider non-multi-param tasks currently
724 if(td.numParameters() == 1) {
725 Hashtable<Integer, Hashtable<TaskDescriptor, Vector<SimExecutionEdge>>> tooptimize2 =
726 new Hashtable<Integer, Hashtable<TaskDescriptor, Vector<SimExecutionEdge>>>();
727 tooptimize2.put(corenum, candidatetasks);
728 Vector<Vector<ScheduleNode>> ops = innerOptimizeCriticalPath(scheduleGraph,
734 if(optimizeschedulegraphs == null) {
735 optimizeschedulegraphs = new Vector<Vector<ScheduleNode>>();
737 optimizeschedulegraphs.addAll(ops);
738 lgid += optimizeschedulegraphs.size();
739 left -= optimizeschedulegraphs.size();
746 candidatetasks = null;
751 return optimizeschedulegraphs;
754 // flush the dependences and earliest start time
755 it_cores = tooptimize.keySet().iterator();
756 while(it_cores.hasNext()) {
757 Hashtable<TaskDescriptor, Vector<SimExecutionEdge>> candidatetasks =
758 tooptimize.get(it_cores.next());
759 Iterator<Vector<SimExecutionEdge>> it_edgevecs =
760 candidatetasks.values().iterator();
761 while(it_edgevecs.hasNext()) {
762 Vector<SimExecutionEdge> edgevec = it_edgevecs.next();
763 for(int j = 0; j < edgevec.size(); j++) {
764 SimExecutionEdge edge = edgevec.elementAt(j);
765 SimExecutionEdge lastpredicateedge = edge.getLastpredicateEdge();
766 SimExecutionNode lastpredicatenode = edge.getLastpredicateNode();
767 // if(edge.getCoreNum() != lastpredicate.getCoreNum()) // should never hit this
768 int timepoint = lastpredicatenode.getTimepoint();
769 if(lastpredicateedge.getTd() == null) {
771 timepoint += lastpredicateedge.getWeight();
773 // mapping to critical path
774 for(int index = 0; index < criticalPath.size(); index++) {
775 SimExecutionEdge tmpseedge = criticalPath.elementAt(index);
776 SimExecutionNode tmpsenode =
777 (SimExecutionNode)tmpseedge.getTarget();
778 if(tmpsenode.getTimepoint() > timepoint) {
779 // update the predicate info
780 if(edge.getPredicates() != null) {
781 edge.getPredicates().remove(lastpredicateedge);
783 edge.addPredicate(criticalPath.elementAt(index));
790 candidatetasks = null;
794 computeBestStartPoint(criticalPath);
795 Vector<Vector<ScheduleNode>> ops = optimizeCriticalPath(scheduleGraph,
800 if(optimizeschedulegraphs == null) {
801 optimizeschedulegraphs = new Vector<Vector<ScheduleNode>>();
803 optimizeschedulegraphs.addAll(ops);
807 // there are spare cores, try to reorganize the tasks to the spare
809 Vector<Vector<ScheduleNode>> ops = innerOptimizeCriticalPath(scheduleGraph,
815 if(optimizeschedulegraphs == null) {
816 optimizeschedulegraphs = new Vector<Vector<ScheduleNode>>();
818 optimizeschedulegraphs.addAll(ops);
827 return optimizeschedulegraphs;
830 private Vector<Vector<ScheduleNode>> innerOptimizeCriticalPath(Vector<ScheduleNode> scheduleGraph,
831 Hashtable<Integer, Hashtable<TaskDescriptor, Vector<SimExecutionEdge>>> tooptimize,
832 Vector<Integer> sparecores,
837 Vector<Vector<ScheduleNode>> optimizeschedulegraphs = null;
839 // first clone the whole graph
840 Vector<ScheduleNode> newscheduleGraph =
841 cloneScheduleGraph(scheduleGraph, lgid);
843 // these nodes are root nodes
844 Vector<ScheduleNode> roots = new Vector<ScheduleNode>();
845 for(int i = 0; i < newscheduleGraph.size(); i++) {
846 if((sparecores == null) || (sparecores.contains(i))) {
847 roots.add(newscheduleGraph.elementAt(i));
851 // map the tasks associated to SimExecutionedges to original
852 // ClassNode in the ScheduleGraph and split them from previous
854 Vector<ScheduleNode> tocombines = new Vector<ScheduleNode>();
855 Iterator<Integer> it_cores = tooptimize.keySet().iterator();
856 while(it_cores.hasNext()) {
857 int corenum = it_cores.next();
858 Hashtable<TaskDescriptor, Vector<SimExecutionEdge>> candidatetasks =
859 tooptimize.get(corenum);
860 Iterator<TaskDescriptor> it_tds = candidatetasks.keySet().iterator();
861 while(it_tds.hasNext()) {
862 TaskDescriptor td = it_tds.next();
863 int numtosplit = candidatetasks.get(td).size();
864 // TODO: currently do not consider multi-param tasks
865 if(td.numParameters() == 1) {
866 ClassDescriptor cd = td.getParamType(0).getClassDesc();
867 ScheduleNode snode = newscheduleGraph.elementAt(corenum); // corresponding ScheduleNode
868 Iterator<ClassNode> it_cnodes = snode.getClassNodesIterator();
869 Vector<ClassNode> tosplit = new Vector<ClassNode>();
870 while((numtosplit > 0) && (it_cnodes.hasNext())) {
871 ClassNode cnode = it_cnodes.next();
872 if(cnode.getClassDescriptor().equals(cd)) {
879 for(int i = 0; i < tosplit.size(); i++) {
880 ScheduleNode splitnode = snode.spliteClassNode(tosplit.elementAt(i));
881 newscheduleGraph.add(splitnode);
882 tocombines.add(splitnode);
887 candidatetasks = null;
892 if(tocombines.size() == 0) {
893 return optimizeschedulegraphs;
896 SchedulingUtil.assignCids(newscheduleGraph);
898 // get all the ScheduleEdge
899 Vector<ScheduleEdge> scheduleEdges = new Vector<ScheduleEdge>();
900 for(int i= 0; i < newscheduleGraph.size(); i++) {
901 scheduleEdges.addAll((Vector<ScheduleEdge>)newscheduleGraph.elementAt(i).getEdgeVector());
904 Vector<Vector<ScheduleNode>> rootNodes =
905 SchedulingUtil.rangeScheduleNodes(roots);
906 Vector<Vector<ScheduleNode>> nodes2combine =
907 SchedulingUtil.rangeScheduleNodes(tocombines);
909 CombinationUtil.CombineGenerator cGen =
910 CombinationUtil.allocateCombineGenerator(rootNodes, nodes2combine);
911 Random rand = new Random();
912 while ((left > 0) && (cGen.nextGen())) {
913 if(Math.abs(rand.nextInt()) % 100 > this.generateThreshold) {
914 Vector<Vector<CombinationUtil.Combine>> combine = cGen.getCombine();
915 Vector<ScheduleNode> sNodes = SchedulingUtil.generateScheduleGraph(this.state,
921 if(optimizeschedulegraphs == null) {
922 optimizeschedulegraphs = new Vector<Vector<ScheduleNode>>();
924 optimizeschedulegraphs.add(sNodes);
932 nodes2combine = null;
933 newscheduleGraph = null;
934 scheduleEdges.clear();
935 scheduleEdges = null;
939 return optimizeschedulegraphs;
942 private Vector<ScheduleNode> cloneScheduleGraph(Vector<ScheduleNode> scheduleGraph,
944 Vector<ScheduleNode> result = new Vector<ScheduleNode>();
946 // get all the ScheduleEdge
947 Vector<ScheduleEdge> scheduleEdges = new Vector<ScheduleEdge>();
948 for(int i= 0; i < scheduleGraph.size(); i++) {
949 scheduleEdges.addAll((Vector<ScheduleEdge>)scheduleGraph.elementAt(i).getEdgeVector());
951 Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>> sn2hash =
952 new Hashtable<ScheduleNode, Hashtable<ClassNode, ClassNode>>();
953 Hashtable<ScheduleNode, ScheduleNode> sn2sn =
954 new Hashtable<ScheduleNode, ScheduleNode>();
955 SchedulingUtil.cloneScheduleGraph(scheduleGraph,
962 SchedulingUtil.assignCids(result);
963 scheduleEdges.clear();
964 scheduleEdges = null;
973 private Vector<Schedule> generateScheduling(Vector<ScheduleNode> scheduleGraph,
974 Vector<TaskDescriptor> multiparamtds) {
975 Hashtable<TaskDescriptor, Vector<Schedule>> td2cores =
976 new Hashtable<TaskDescriptor, Vector<Schedule>>(); // multiparam tasks reside on which cores
977 Vector<Schedule> scheduling = new Vector<Schedule>(scheduleGraph.size());
978 // for each ScheduleNode create a schedule node representing a core
979 Hashtable<ScheduleNode, Integer> sn2coreNum =
980 new Hashtable<ScheduleNode, Integer>();
982 for(j = 0; j < scheduleGraph.size(); j++) {
983 sn2coreNum.put(scheduleGraph.elementAt(j), j);
986 boolean setstartupcore = false;
987 Schedule startup = null;
988 int gid = scheduleGraph.elementAt(0).getGid();
989 for(j = 0; j < scheduleGraph.size(); j++) {
990 Schedule tmpSchedule = new Schedule(j, gid);
991 ScheduleNode sn = scheduleGraph.elementAt(j);
993 Vector<ClassNode> cNodes = sn.getClassNodes();
994 for(int k = 0; k < cNodes.size(); k++) {
995 Iterator it_flags = cNodes.elementAt(k).getFlags();
996 while(it_flags.hasNext()) {
997 FlagState fs = (FlagState)it_flags.next();
998 Iterator it_edges = fs.edges();
999 while(it_edges.hasNext()) {
1000 TaskDescriptor td = ((FEdge)it_edges.next()).getTask();
1001 tmpSchedule.addTask(td);
1002 if(!td2cores.containsKey(td)) {
1003 td2cores.put(td, new Vector<Schedule>());
1005 Vector<Schedule> tmpcores = td2cores.get(td);
1006 if(!tmpcores.contains(tmpSchedule)) {
1007 tmpcores.add(tmpSchedule);
1010 // if the FlagState can be fed to some multi-param tasks,
1011 // need to record corresponding ally cores later
1012 if(td.numParameters() > 1) {
1013 tmpSchedule.addFState4TD(td, fs);
1015 if(td.getParamType(0).getClassDesc().getSymbol().equals(
1016 TypeUtil.StartupClass)) {
1017 assert(!setstartupcore);
1019 startup = tmpSchedule;
1020 setstartupcore = true;
1029 // For each of the ScheduleEdge out of this ScheduleNode, add the target ScheduleNode into the queue inside sn
1030 Iterator it_edges = sn.edges();
1031 while(it_edges.hasNext()) {
1032 ScheduleEdge se = (ScheduleEdge)it_edges.next();
1033 ScheduleNode target = (ScheduleNode)se.getTarget();
1034 Integer targetcore = sn2coreNum.get(target);
1035 switch(se.getType()) {
1036 case ScheduleEdge.NEWEDGE: {
1037 for(int k = 0; k < se.getNewRate(); k++) {
1038 tmpSchedule.addTargetCore(se.getFstate(), targetcore);
1043 case ScheduleEdge.TRANSEDGE: {
1045 tmpSchedule.addTargetCore(se.getFstate(),
1047 se.getTargetFState());
1048 // check if missed some FlagState associated with some multi-parameter
1049 // task, which has been cloned when splitting a ClassNode
1050 FlagState fs = se.getSourceFState();
1051 FlagState tfs = se.getTargetFState();
1052 Iterator it = tfs.edges();
1053 while(it.hasNext()) {
1054 TaskDescriptor td = ((FEdge)it.next()).getTask();
1055 if(td.numParameters() > 1) {
1056 if(tmpSchedule.getTasks().contains(td)) {
1057 tmpSchedule.addFState4TD(td, fs);
1065 it_edges = sn.getScheduleEdgesIterator();
1066 while(it_edges.hasNext()) {
1067 ScheduleEdge se = (ScheduleEdge)it_edges.next();
1068 switch(se.getType()) {
1069 case ScheduleEdge.NEWEDGE: {
1070 for(int k = 0; k < se.getNewRate(); k++) {
1071 tmpSchedule.addTargetCore(se.getFstate(), j);
1076 case ScheduleEdge.TRANSEDGE: {
1078 tmpSchedule.addTargetCore(se.getFstate(),
1080 se.getTargetFState());
1086 scheduling.add(tmpSchedule);
1089 int number = this.coreNum;
1090 if(scheduling.size() < number) {
1091 number = scheduling.size();
1094 // set up all the associate ally cores
1095 if(multiparamtds.size() > 0) {
1096 for(j = 0; j < multiparamtds.size(); ++j) {
1097 TaskDescriptor td = multiparamtds.elementAt(j);
1099 (Vector<FEdge>) this.taskAnalysis.getFEdgesFromTD(td);
1100 Vector<Schedule> cores = td2cores.get(td);
1101 for(int k = 0; k < cores.size(); ++k) {
1102 Schedule tmpSchedule = cores.elementAt(k);
1104 for(int h = 0; h < fes.size(); ++h) {
1105 FEdge tmpfe = fes.elementAt(h);
1106 FlagState tmpfs = (FlagState)tmpfe.getTarget();
1107 Vector<TaskDescriptor> tmptds = new Vector<TaskDescriptor>();
1108 if((tmpSchedule.getTargetCoreTable() == null)
1109 || (!tmpSchedule.getTargetCoreTable().containsKey(tmpfs))) {
1110 // add up all possible cores' info
1111 Iterator it_edges = tmpfs.edges();
1112 while(it_edges.hasNext()) {
1113 TaskDescriptor tmptd = ((FEdge)it_edges.next()).getTask();
1114 if(!tmptds.contains(tmptd)) {
1116 Vector<Schedule> tmpcores = td2cores.get(tmptd);
1117 for(int m = 0; m < tmpcores.size(); ++m) {
1118 if(m != tmpSchedule.getCoreNum()) {
1119 // if the FlagState can be fed to some multi-param tasks,
1120 // need to record corresponding ally cores later
1121 if(tmptd.numParameters() > 1) {
1122 tmpSchedule.addAllyCore(tmpfs,
1123 tmpcores.elementAt(m).getCoreNum());
1125 tmpSchedule.addTargetCore(tmpfs,
1126 tmpcores.elementAt(m).getCoreNum());
1138 if(cores.size() > 1) {
1139 Vector<FlagState> tmpfss = tmpSchedule.getFStates4TD(td);
1140 for(int h = 0; h < tmpfss.size(); ++h) {
1141 for(int l = 0; l < cores.size(); ++l) {
1143 tmpSchedule.addAllyCore(tmpfss.elementAt(h),
1144 cores.elementAt(l).getCoreNum());