MyraMath
UserJobGraph.h
Go to the documentation of this file.
1 // ========================================================================= //
2 // This file is part of MyraMath, copyright (c) 2014-2019 by Ryan A Chilton //
3 // and distributed by MyraCore, LLC. See LICENSE.txt for license terms. //
4 // ========================================================================= //
5 
6 #ifndef MYRAMATH_JOBGRAPH_USERJOBGRAPH_H
7 #define MYRAMATH_JOBGRAPH_USERJOBGRAPH_H
8 
14 #include <myramath/MYRAMATH_EXPORT.h>
16 #include <myramath/utility/detail/ssize.h>
17 
18 #include <myramath/jobgraph/Job.h>
21 
22 #include <string>
23 #include <stdint.h>
24 
25 #include <vector>
26 #include <set>
27 
28 namespace myra {
29 
32  {
33  public:
34 
35  // --------------------------- UserJobBase
36 
38  class UserJobBase : public :: myra::Job
39  {
40  public:
41 
43  UserJobBase(uint64_t j, const std::string& s)
44  : job(j), n(s) { }
45 
47  virtual UserJobBase* clone() const = 0;
48 
50  virtual JobID id() const
51  { return JobID(job); }
52 
54  virtual void parents(JobIDs& output) const
55  {
56  for (int p = 0; p < pids.size(); ++p)
57  output.push_back( JobID(pids[p]) );
58  }
59 
61  virtual void children(JobIDs& output) const
62  {
63  for (int c = 0; c < cids.size(); ++c)
64  output.push_back( JobID(cids[c]) );
65  }
66 
68  virtual std::string name() const { return n; }
69 
71  void add_parent(uint64_t p)
72  { pids.push_back(p); }
73 
75  void add_child(uint64_t c)
76  { cids.push_back(c); }
77 
80  { }
81 
82  protected:
83 
84  // A unique identifier for this Job.
85  uint64_t job;
86 
87  // Name string.
88  std::string n;
89 
90  // Parent JobID's
91  std::vector<uint64_t> pids;
92 
93  // Children JobID's
94  std::vector<uint64_t> cids;
95 
96  };
97 
99  template<class Functor> class UserJob : public UserJobBase
100  {
101  public:
102 
104  UserJob(uint64_t j, const Functor& f, const std::string& s)
105  : UserJobBase(j,s), functor(f) { }
106 
108  UserJob(const UserJob& that) : UserJobBase(that.job, that.n), functor(that.functor)
109  {
110  this->pids = that.pids;
111  this->cids = that.cids;
112  }
113 
115  virtual UserJobBase* clone() const
116  { return new UserJob<Functor>(*this); }
117 
119  virtual uint64_t execute()
120  { functor(); return 1; }
121 
123  virtual ~UserJob() { }
124 
125  private:
126 
127  // Executable payload.
128  Functor functor;
129 
130  };
131 
132  // --------------------------- Graph/container API.
133 
136  { }
137 
139  template<class Functor> uint64_t insert(const Functor& f)
140  {
141  uint64_t id = jobs.size();
142  jobs.push_back( new UserJob<Functor>(id,f,"UserJob") );
143  bids.insert(id);
144  eids.insert(id);
145  return id;
146  }
147 
149  template<class Functor> uint64_t insert(const Functor& f, const std::string& n)
150  {
151  uint64_t id = jobs.size();
152  jobs.push_back( new UserJob<Functor>(id,f,n) );
153  bids.insert(id);
154  eids.insert(id);
155  return id;
156  }
157 
159  void add_edge(uint64_t j0, uint64_t j1)
160  {
161  uint64_t J = ssize(jobs);
162  if (j0 < 0) throw eprintf("UserJobGraph::add_edge(), underflow j0 < 0", j0);
163  if (j1 < 0) throw eprintf("UserJobGraph::add_edge(), underflow j1 < 0", j1);
164  if (j0 >= J) throw eprintf("UserJobGraph::add_edge(), overflow j0 >= J", j0, J);
165  if (j1 >= J) throw eprintf("UserJobGraph::add_edge(), overflow j1 >= J", j1, J);
166  // Add child/parent links.
167  jobs[j0]->add_child(j1);
168  jobs[j1]->add_parent(j0);
169  // Job j0 has a child, so it can't be an end.
170  eids.erase(j0);
171  // Job j1 has a parent, so it can't be a begin.
172  bids.erase(j1);
173  }
174 
175  // --------------------------- JobGraphBase obligations.
176 
178  virtual JobGraphBase* clone() const
179  {
180  UserJobGraph* that = new UserJobGraph();
181  for (uint64_t j = 0; j < this->jobs.size(); ++j)
182  that->jobs.push_back( this->jobs[j]->clone() );
183  that->bids = this->bids;
184  that->eids = this->eids;
185  return that;
186  }
187 
189  virtual uint64_t n_work() const
190  { return jobs.size(); }
191 
193  virtual std::string name() const
194  { return "UserJobGraph"; }
195 
197  virtual void begins(JobIDs& output) const
198  {
199  typedef std::set<uint64_t>::const_iterator Iterator;
200  for (Iterator b = bids.begin(); b != bids.end(); ++b)
201  output.push_back( JobID(*b) );
202  }
203 
205  virtual void ends(JobIDs& output) const
206  {
207  typedef std::set<uint64_t>::const_iterator Iterator;
208  for (Iterator e = eids.begin(); e != eids.end(); ++e)
209  output.push_back( JobID(*e) );
210  }
211 
213  virtual Job* create(JobID id)
214  { return jobs[id.unpack()]->clone(); }
215 
217  uint64_t size() const
218  { return jobs.size(); }
219 
221  virtual ~UserJobGraph()
222  {
223  for (uint64_t j = 0; j < jobs.size(); ++j)
224  delete jobs[j];
225  }
226 
227  private:
228 
229  // Internal contents.
230  std::vector<UserJobBase*> jobs;
231 
232  // Begin JobID's
233  std::set<uint64_t> bids;
234 
235  // End JobID's
236  std::set<uint64_t> eids;
237 
238  };
239 
240 } // namespace myra
241 
242 #endif
UserJob(const UserJob &that)
Copy constructor.
Definition: UserJobGraph.h:108
Abstraction to represent one node of a JobGraph.
Definition: Job.h:25
Abstraction to represent one node of a JobGraph.
uint64_t insert(const Functor &f)
Inserts a Job (in the form of a C++11 lambda) to this JobGraph, returns its unique JobID...
Definition: UserJobGraph.h:139
Returns a std::runtime_error() whose message has been populated using printf()-style formatting...
virtual uint64_t execute()
Executes the underlying Functor.
Definition: UserJobGraph.h:119
virtual std::string name() const
Returns a printable name for this Job, for debugging.
Definition: UserJobGraph.h:68
virtual UserJobBase * clone() const =0
Implementation detail of FunctorJobGraph::clone()
~UserJobBase()
Frees internal resources.
Definition: UserJobGraph.h:79
Implementation detail of UserJobGraph Job&#39;s, structural aspects.
Definition: UserJobGraph.h:38
virtual Job * create(JobID id)
Constructs the Job corresponding to the given JobID.
Definition: UserJobGraph.h:213
uint64_t size() const
Returns maximum JobID.
Definition: UserJobGraph.h:217
virtual JobID id() const
Returns the JobID of this Job.
Definition: UserJobGraph.h:50
virtual UserJobBase * clone() const
Implementation detail of UserJobGraph::clone()
Definition: UserJobGraph.h:115
Definition: syntax.dox:1
Base/contract class for all other JobGraph&#39;s.
Definition: JobGraph.h:30
void add_child(uint64_t c)
Adds a child dependency.
Definition: UserJobGraph.h:75
virtual ~UserJobGraph()
Virtual destructor, so subtypes can release resources.
Definition: UserJobGraph.h:221
virtual void children(JobIDs &output) const
Returns the JobID&#39;s of children.
Definition: UserJobGraph.h:61
Abstraction for representing a directed acyclic graph of Job&#39;s.
UserJobBase(uint64_t j, const std::string &s)
Constructor, requires ID and name.
Definition: UserJobGraph.h:43
void add_parent(uint64_t p)
Adds a parent dependency.
Definition: UserJobGraph.h:71
virtual void ends(JobIDs &output) const
Enumerates the JobIDs of Job&#39;s that have no children (where execution ends)
Definition: UserJobGraph.h:205
virtual JobGraphBase * clone() const
Virtual copy-constructor.
Definition: UserJobGraph.h:178
virtual void begins(JobIDs &output) const
Enumerates the JobIDs of Job&#39;s that have no parents (where execution begins)
Definition: UserJobGraph.h:197
virtual void parents(JobIDs &output) const
Returns the JobID&#39;s of parents.
Definition: UserJobGraph.h:54
void add_edge(uint64_t j0, uint64_t j1)
Adds a dependency, that Job j0 must execute before Job j1.
Definition: UserJobGraph.h:159
virtual ~UserJob()
Frees internal resources.
Definition: UserJobGraph.h:123
UserJob(uint64_t j, const Functor &f, const std::string &s)
Constructor, requires ID and Functor payload.
Definition: UserJobGraph.h:104
UserJobGraph()
Default constructor, empty Graph.
Definition: UserJobGraph.h:135
Key type used to identify the Job&#39;s of a JobGraph.
Implementation detail of UserJobGraph Job&#39;s, calculational aspects.
Definition: UserJobGraph.h:99
virtual uint64_t n_work() const
Total "work" over all Job&#39;s of this JobGraph.
Definition: UserJobGraph.h:189
virtual std::string name() const
Returns a printable name for this JobGraph, for debugging.
Definition: UserJobGraph.h:193
Key type used to identify the Job&#39;s of a JobGraph.
Definition: JobID.h:60
std::vector< JobID > JobIDs
Useful typedef.
Definition: JobID.h:118
uint64_t insert(const Functor &f, const std::string &n)
Like insert(f), but can also give a name to the Job (useful for debugging).
Definition: UserJobGraph.h:149
Container-like JobGraph class, can be manually populated with user-defined Job&#39;s and dependencies...
Definition: UserJobGraph.h:31