Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Scheduler.C
Go to the documentation of this file.
1 /* *******************************************************************
2  * Rocstar Simulation Suite *
3  * Copyright@2015, Illinois Rocstar LLC. All rights reserved. *
4  * *
5  * Illinois Rocstar LLC *
6  * Champaign, IL *
7  * www.illinoisrocstar.com *
8  * sales@illinoisrocstar.com *
9  * *
10  * License: See LICENSE file in top level of distribution package or *
11  * http://opensource.org/licenses/NCSA *
12  *********************************************************************/
13 /* *******************************************************************
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES *
16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND *
17  * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR *
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
21  * USE OR OTHER DEALINGS WITH THE SOFTWARE. *
22  *********************************************************************/
23 // $Id: Scheduler.C,v 1.14 2008/12/06 08:45:22 mtcampbe Exp $
24 
25 #include <assert.h>
26 
27 #include "rocman.h"
28 #include "roccom.h"
29 #include "Action.h"
30 #include "Scheduler.h"
31 
36 Scheduler::Scheduler(): alphaT(-1), scheduled(0), inited(0)
37 {
38  scheduler_name = "Scheduler";
39 }
40 
42 {
43  ActionItem *aitem = new ActionItem(action);
44  actions.push_back(aitem);
45  // call back action
46  action->declare(*this);
47 }
48 
49 void Scheduler::reads(Action *a, const char *attr, int idx)
50 {
51  // FIXME: locate this action, doing linear search now
52  ActionList::iterator aitem;
53  for (aitem = actions.begin(); aitem != actions.end(); aitem++)
54  if ((*aitem)->action() == a) break;
55  if (aitem == actions.end()) {
56  printf("ERROR: action '%s' not registered to scheduler. \n", a->name());
57  exit(1);
58  }
59  (*aitem)->read_attr.push_back(strdup(attr)); // copy the string
60  (*aitem)->read_idx.push_back(idx);
61  (*aitem)->input.push_back(NULL);
62 }
63 
64 void Scheduler::writes(Action *a, const char *attr, int idx)
65 {
66  // locate this action
67  ActionList::iterator aitem = actions.begin();
68  for (; aitem != actions.end(); aitem++)
69  if ((*aitem)->action() == a) break;
70  if (aitem == actions.end()) {
71  printf("ERROR: action '%s' not registered to scheduler. \n", a->name());
72  COM_assertion(false);
73  }
74  (*aitem)->write_attr.push_back(strdup(attr)); // copy the string
75  (*aitem)->write_idx.push_back(idx);
76  (*aitem)->output.push_back(NULL);
77 }
78 
80 {
81 #if 0
82  ActionList pool;
83  pool = actions;
84 
85  while (pool.size()!=0) {
86  // find one leaf with no output or output already fullfiled
87  ActionList::iterator act = pool.end()-1;
88  for (; act>=pool.begin(); act--)
89  {
90  if ((*act)->fullfilled()== 1) {
91 //printf("FOUND LEAF: %s\n", (*act)->name());
92  break;
93  }
94  }
95  if (act < pool.begin()) { // error with loop
96  printf("Loop detected!\n");
97  COM_assertion(false);
98  }
99 
100  ActionItem *item = *act;
101  pool.erase(act); // don't use iterator act afterwards
102 
103  if (item->n_read() == 0) { // this is a tree root
104  roots.push_back(item);
105  }
106  else
107  for (unsigned int i=0; i<item->n_read(); i++) {
108  if (item->input[i] == NULL) {
109  // find matching input actions for item from pool
110  ActionList::iterator a = pool.end()-1;
111  for (; a>=pool.begin(); a--) {
112  int inIdx = (*a)->hasOutput(item->read_attr[i], item->read_idx[i]);
113  if (inIdx != -1) { // set up double link
114 //printf("updated output of %s for %s %d\n", (*a)->name(), item->read_attr[i], item->read_idx[i]);
115  item->input[i] = *a;
116  (*a)->output[inIdx] = item;
117  break; // only do once
118  }
119  }
120  if (a < pool.begin()) { // a read without any matching write
121  printf("Error: can not find matching input for action %s of attr:%s index:%d. \n", (*a)->name(), item->read_attr[i], item->read_idx[i]);
122  }
123  } // end of for i
124  }
125  } // end of while
126 #else
127  // make links
128  ActionList pool;
129  pool = actions;
130 
131  unsigned int idx = 1;
132  while (idx<pool.size()) {
133 
134  ActionItem *item = pool[idx];
135  // search all input
136  for (unsigned int i=0; i<item->n_read(); i++) {
137  for (int j=idx-1; j>=0; j--) {
138  ActionItem *aitem = pool[j];
139  int inIdx = aitem->hasOutput(item->read_attr[i], item->read_idx[i]);
140  if (inIdx != -1) {
141  item->input[i] = aitem;
142  aitem->output[inIdx] = item;
143  }
144  }
145  }
146  idx ++;
147  }
148  // identify root nodes
149  for (idx=0; idx<pool.size(); idx++) {
150  ActionItem *item = pool[idx];
151  int isroot = 1;
152  for (unsigned int i=0; i<item->n_read(); i++)
153  if (item->input[i] != NULL) {
154  isroot = 0;
155  break;
156  }
157  if (isroot) roots.push_back(item);
158  }
159 #endif
160 }
161 
163 {
164  MAN_DEBUG(1, ("Scheduler::schedule called.\n"));
165  COM_assertion_msg(!scheduled, "ERROR: Scheduler has already been scheduled.\n");
166 
167  // schedule all sub-schedulers
168  for (unsigned int i=0; i<actions.size(); i++)
169  actions[i]->action()->schedule();
170 
171  // debugging
172  printActions();
173 
174  buildDDG();
175 
176  sanityCheck();
177 
179 
180  printf("Topological sort:\n");
181  print_toposort(stdout);
182  printf("\n");
183 
184  scheduled = 1;
185 }
186 
188 {
189  for (unsigned int i=0; i<actions.size(); i++)
190  actions[i]->print(stdout);
191  printf("\n");
192 }
193 
194 void Scheduler::print_helper(FILE *f, ActionItem *aitem)
195 {
196  unsigned int i;
197  if (aitem->print_flag == 1) return;
198  aitem->print_flag = 1;
199  aitem->action()->print(f);
200  for (i=0; i<aitem->n_read(); i++) {
201  if (aitem->input[i])
202  fprintf(f, "edge: { sourcename: \"%s\" targetname: \"%s\" label: \"%s,%d\"}\n", aitem->input[i]->name(), aitem->name(), aitem->read_attr[i], aitem->read_idx[i]);
203  }
204  for (i=0; i<aitem->n_write(); i++)
205  if ( aitem->output[i]) print_helper(f, aitem->output[i]);
206 }
207 
208 char * Scheduler::print(FILE *f, const char *container_name)
209 {
210  if (actions.size() == 0) return NULL;
211 
212  std::string sched_name = container_name;
213  sched_name = sched_name + "-" + name();
214  fprintf(f, "graph: { title: \"%s\" label: \"%s\" \n\
215  status: folded \n\
216  display_edge_labels: yes \n\
217  layoutalgorithm: tree \n\
218  scaling: maxspect \n\
219  color : white \n\
220  node.color : lightblue \n\
221  node.textcolor : black \n\
222  node.bordercolor: black \n\
223  node.borderwidth: 1 \n\
224  edge.color : lightblue \n\
225  edge.arrowsize : 7 \n\
226  edge.thickness : 2 \n\
227  edge.fontname:\"helvO08\" \n\
228  node.label: \"no type\" \n", sched_name.c_str(), sched_name.c_str());
229 
230  unsigned int i;
231  for (i=0; i<actions.size(); i++)
232  actions[i]->print_flag = 0;
233 
234  for (i=0; i<roots.size(); i++) {
235  print_helper(f, roots[i]);
236  }
237 
238  fprintf(f, "}\n");
239 
240  return strdup(sched_name.c_str());
241 }
242 
243 // print in GDL
244 void Scheduler::print(const char *fname)
245 {
246  FILE *f = fopen(fname, "w");
247 
248  fprintf(f, "graph: { title: \"DependenceTree\" \n\
249  display_edge_labels: yes \n\
250  layoutalgorithm: tree \n\
251  scaling: maxspect \n\
252  node.color : green \n\
253  node.textcolor : black \n\
254  node.bordercolor: black \n\
255  node.borderwidth: 1 \n\
256  edge.color : blue \n\
257  edge.arrowsize : 7 \n\
258  edge.thickness : 2 \n\
259  edge.fontname:\"helvO08\" \n\
260  node.label: \"no type\" \n");
261 
262  print(f, "scheduler");
263 
264  fprintf(f, "} \n");
265  fclose(f);
266 }
267 
269 {
270  ActionList pool;
271  pool = actions;
272  while (1) {
273  ActionList::iterator aitem = pool.begin();
274  for (; aitem!=pool.end(); aitem++) {
275  if ((*aitem)->n_read() == 0) { break; }
276  // check every input
277  int flag = 1;
278  for (unsigned int i=0; i<(*aitem)->n_read(); i++) {
279  ActionItem *in = (*aitem)->input[i];
280  // search in sort
281  ActionList::iterator s;
282  for (s = sort.begin(); s!=sort.end(); ++s)
283  if ((*s)->action() == in->action()) break;
284  if (s == sort.end()) { flag = 0; break; }
285  }
286  if (flag) break;
287  }
288  if (aitem != pool.end()) {
289  sort.push_back(*aitem);
290  pool.erase(aitem);
291  }
292  else
293  break;
294  }
295 
296  if (pool.size() != 0) {
297  printf("ERROR in sorting!\n");
298  exit (1);
299  }
300 }
301 
303 {
304  for (unsigned int i=0; i<sort.size(); i++) sort[i]->action()->print_toposort(f);
305 }
306 
308 {
309  // make sure all input and output are not null
310  ActionList::iterator aitem;
311  for (aitem = actions.begin(); aitem!=actions.end(); aitem++)
312  {
313  ActionItem *item = *aitem;
314  unsigned int i;
315  COM_assertion_msg(item->n_read() == item->input.size(), "ERROR: Scheduler::sanityCheck failed.\n");
316  for (i=0; i<item->n_read(); i++)
317  COM_assertion_msg(item->input[i] != NULL, "ERROR: Scheduler::sanityCheck failed at 2.\n");
318  COM_assertion_msg(item->n_write() == item->output.size(), "ERROR: Scheduler::sanityCheck failed at 3.\n");
319  for (i=0; i<item->n_write(); i++)
320  COM_assertion_msg(item->output[i] != NULL, "ERROR: Scheduler::sanityCheck failed at 4.\n");
321  }
322 }
323 
325 {
326  COM_assertion_msg(scheduled, "RROR: Scheduler has not been scheduled.\n");
327  if (inited) return;
328  inited = 1;
329 
330  // do at sorted order
331  ActionList::iterator aitem;
332  for (aitem = sort.begin(); aitem!=sort.end(); aitem++)
333  {
334  ActionItem *item = *aitem;
335  item->action()->init(t);
336  }
337 }
338 
339 void Scheduler::run_actions(double t, double dt)
340 {
341  COM_assertion_msg(scheduled, "RROR: Scheduler has not been scheduled when calling run_actions.\n");
342  // do at sorted order
343  ActionList::iterator aitem;
344  for (aitem = sort.begin(); aitem!=sort.end(); aitem++)
345  {
346  ActionItem *item = *aitem;
347  item->action()->run(t, dt, alphaT);
348  }
349 }
350 
352 {
353  COM_assertion_msg(scheduled, "ERROR: Scheduler has not been scheduled when calling finalize_actions.\n");
354  if (sort.size()==0) return;
355  // do at reversed order
356  ActionList::iterator aitem;
357  for (aitem = sort.end()-1; aitem>=sort.begin(); aitem--)
358  {
359  ActionItem *item = *aitem;
360  item->action()->finalize();
361  }
362 }
363 
364 
365 
366 // return true if all output actions satisfied
368 {
369  for (unsigned int i=0; i<n_write(); i++)
370  if (output[i] == NULL) return 0;
371  return 1;
372 }
373 
374 int Scheduler::ActionItem::hasInput(const char *attr, int idx)
375 {
376  for (unsigned int i=0; i<n_read(); i++)
377  if (strcasecmp(attr, read_attr[i]) == 0 && idx == read_idx[i]) return i;
378  return -1;
379 }
380 
381 int Scheduler::ActionItem::hasOutput(const char *attr, int idx)
382 {
383  for (unsigned int i=0; i<n_write(); i++)
384  if (strcasecmp(attr, write_attr[i]) == 0 && idx == write_idx[i]) return i;
385  return -1;
386 }
387 
388 
390 {
391  unsigned int i;
392  fprintf(f, "=========== Action %s =============\n", name());
393  for (i=0; i<n_read(); i++)
394  printf("reads: %s %d \n", read_attr[i], read_idx[i]);
395  for (i=0; i<n_write(); i++)
396  printf("writes: %s %d \n", write_attr[i], write_idx[i]);
397 }
398 
399 
400 // scheduler is done by user specified add action sequence
402 {
403  Scheduler::add_action(action);
404  if (roots.size() == 0) roots.push_back(actions[actions.size()-1]);
405  sort.push_back(actions[actions.size()-1]);
406 }
407 
409 {
410 /*
411  for (unsigned int i=0; i<actions.size(); i++) {
412  if (i+1<actions.size()) {
413  actions[i]->output.push_back(actions[i+1]);
414  actions[i+1]->input.push_back(actions[i]);
415  }
416  }
417 */
418  buildDDG();
419  scheduled = 1;
420 }
421 
422 
423 
424 
425 
426 
double alphaT
Definition: Scheduler.h:82
#define COM_assertion(EX)
Error checking utility similar to the assert macro of the C language.
virtual char * name()
Definition: Action.h:53
virtual void init(double t)
Definition: Action.h:50
virtual void schedule()
Definition: Scheduler.C:408
ActionList roots
Definition: Scheduler.h:79
std::string scheduler_name
Definition: Scheduler.h:52
void print_helper(FILE *f, ActionItem *aitem)
Definition: Scheduler.C:194
unsigned int n_write()
Definition: Scheduler.h:68
void printActions()
Definition: Scheduler.C:187
#define COM_assertion_msg(EX, msg)
double s
Definition: blastest.C:80
ActionList actions
Definition: Scheduler.h:78
virtual void declare(Scheduler &)
Definition: Action.C:77
This file contains the prototypes for Roccom API.
ActionList input
Definition: Scheduler.h:63
virtual void add_action(Action *)
Definition: Scheduler.C:401
ActionList output
Definition: Scheduler.h:64
int fclose(std::FILE *file)
Close a file, and check for possible errors.
Definition: CImg.h:5507
virtual void finalize()
Definition: Action.h:52
virtual void schedule()
Definition: Scheduler.C:162
void buildDDG()
Definition: Scheduler.C:79
vector< int > read_idx
Definition: Scheduler.h:60
void sanityCheck()
Definition: Scheduler.C:307
Scheduler()
Scheduler.
Definition: Scheduler.C:36
Definition: Action.h:32
void print_toposort(FILE *f)
Definition: Scheduler.C:302
void writes(Action *, const char *attr, int idx)
Definition: Scheduler.C:64
void print(const char *fname)
Definition: Scheduler.C:244
virtual void run(double t, double dt, double alpha)
Definition: Action.h:51
void print(FILE *f)
Definition: Scheduler.C:389
int scheduled
Definition: Scheduler.h:84
void reads(Action *, const char *attr, int idx)
Definition: Scheduler.C:49
static void write_attr(std::ostream &os, const COM::Attribute *attr, int i)
int strcasecmp(const char *const s1, const char *const s2)
Compare two C-strings, ignoring the case.
Definition: CImg.h:4928
vector< ActionItem * > ActionList
Definition: Scheduler.h:54
blockLoc i
Definition: read.cpp:79
vector< const char * > read_attr
Definition: Scheduler.h:59
unsigned int n_read()
Definition: Scheduler.h:69
void finalize_actions()
Definition: Scheduler.C:351
Action * action()
Definition: Scheduler.h:71
j indices j
Definition: Indexing.h:6
int hasOutput(const char *attr, int idx)
Definition: Scheduler.C:381
const char * name()
Definition: Scheduler.h:49
#define MAN_DEBUG(l, x)
Definition: rocman.h:98
int inited
Definition: Scheduler.h:85
ActionList sort
Definition: Scheduler.h:80
int hasInput(const char *attr, int idx)
Definition: Scheduler.C:374
virtual void add_action(Action *)
Definition: Scheduler.C:41
void init_actions(double t)
Definition: Scheduler.C:324
void run_actions(double t, double dt)
Definition: Scheduler.C:339
std::FILE * fopen(const char *const path, const char *const mode)
Open a file, and check for possible errors.
Definition: CImg.h:5494
virtual void print(FILE *f)
Definition: Action.C:87
void topological_sort()
Definition: Scheduler.C:268