HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SOP_Compiled.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: SOP_Compiled.h ( SOP Library, C++)
7  *
8  * COMMENTS:
9  * Compiles chains of nodes into a single object
10  * that can be evaluated.
11  */
12 
13 #ifndef __SOP_Compiled_h__
14 #define __SOP_Compiled_h__
15 
16 #include "SOP_API.h"
17 #include "SOP_Node.h"
18 #include "SOP_NodeVerb.h"
19 #include "SOP_GraphProxy.h"
20 #include <DEP/DEP_TimedMicroNode.h>
21 #include <CE/CE_Error.h>
22 
24 {
25 public:
26  SOP_Compiled();
27  virtual ~SOP_Compiled();
28 
30  {
34  };
35 
37  {
38  public:
39  DelayedCook(SOP_Node *cooknode, const OP_Context &context)
40  : myCookNode(cooknode)
41  , myContext(context)
42  {
43  }
44 
47  };
48 
49  class TaskState
50  {
51  public:
53  {
54  myDirty = true;
55  myCooking = false;
56  myUseCount = 0;
57  myLocked = false;
58  myCECache = false;
59  myTimeDependent = false;
60  myNodeCache = 0;
61  myNodeParms = 0;
62  myNodeParmsOrig = 0;
63  myParmsDirty = true;
64  myDependsOnExprInputs = true;
65  myDelayedCook = 0;
66  }
68  {
69  delete myNodeCache;
70  delete myNodeParms;
71  delete myNodeParmsOrig;
72  delete myDelayedCook;
73  }
74 
76  bool myDirty;
77  bool myCECache;
79  bool myCooking; // recursion flag.
81  bool myLocked;
82  bool myParmsDirty; // Whether node parms current
83  bool myDependsOnExprInputs; // If expr inputs used.
86  SOP_NodeParms *myNodeParmsOrig; // Pre-vexpression cache
88  };
89 
91 
93  {
94  bool executeInputs(TaskStateArray &state, const OP_Context &context, UT_ErrorManager &errors, DEP_MicroNode *depnode);
95 
96  public:
97  ExecuteParms(TaskStateArray &state, UnloadMode unloadmode,
98  const OP_Context &context,
99  UT_ErrorManager &errors, DEP_MicroNode *depnode,
100  SOP_NodeVerb::ForbiddenNodeMap &forbiddennodes,
101  UT_Array<GU_DetailHandle> *recyclingbin)
102  : myState(state)
103  , myUnloadMode(unloadmode)
104  , myContext(context)
105  , myErrors(errors)
106  , myDepNode(depnode)
107  , myForbiddenNodes(forbiddennodes)
108  , myRecyclingBin(recyclingbin)
109  { }
110 
112  {}
113 
114  TaskStateArray &state() const { return myState; }
115  UnloadMode unloadMode() const { return myUnloadMode; }
116  const OP_Context &context() const { return myContext; }
117  UT_ErrorManager &errors() const { return myErrors; }
118  DEP_MicroNode *depnode() const { return myDepNode; }
119 
120  SOP_NodeVerb::ForbiddenNodeMap &forbiddenNodes() const { return myForbiddenNodes; }
121 
122  bool hasRecycleableGdp() const
123  {
124  if (!myRecyclingBin)
125  return false;
126  return myRecyclingBin->entries() > 0;
127  }
128  GU_DetailHandle allocGdp(bool clear = true) const
129  {
131  if (!hasRecycleableGdp())
132  {
134  }
135  else
136  {
137  result = myRecyclingBin->last();
138  myRecyclingBin->removeLast();
139  if (clear)
140  result.gdpNC()->stashAll();
141  myRecycledGdpId.append(result.gdp()->getUniqueId());
142  myRecycledGdpShareCount.append(result.getRefCount());
143  }
144  return result;
145  }
146 
147  bool isGdpIdRecycled(const GU_DetailHandle &gdh) const
148  {
149  UT_ASSERT(gdh.isValid());
150  exint idx = myRecycledGdpId.find(gdh.gdp()->getUniqueId());
151  if (idx < 0)
152  return false;
153  // Verify we haven't had any extra copies made of us during
154  // task execution. We compare against our stashed use
155  // count when first built.
156  if (gdh.getRefCount() != myRecycledGdpShareCount(idx))
157  {
158  return false;
159  }
160  return true;
161  }
162 
163  protected:
173  };
174 
175  class Task
176  {
177  public:
178  Task(const OP_GraphProxy *graph, OP_GraphProxy::NodeIdx noderef, int stateid);
179  virtual ~Task();
180 
181  void setInput(int inputidx, Task *input);
182  void setExprInput(int inputidx, Task *input);
183  void appendOutput(Task *output);
184 
185  // Verify we are still wired up the way we used to be. Only the
186  // node id is valid at this point.
187  virtual bool validate();
188  virtual void addNodes(SOP_NodeVerb::ForbiddenNodeMap &nodeset) const;
189  virtual void usedNodes(UT_Set<OP_Node *> &usednodes) const;
190 
191  // Unloads any cached gdps, but not necessarily things like
192  // VEX bindings.
193  virtual void forceUnload(TaskStateArray &state);
194 
195  // Resets the time dependencies of its own node's parm lists,
196  // and any child states node's parm lists.
197  virtual void clearNodeTimeDependencies();
198 
199  OP_Node *getNode() const { return graph()->idxToNode(getNodeIdx()); }
200  OP_GraphProxy::NodeIdx getNodeIdx() const { return myNodeIdx; }
201  GU_DetailHandle getDetailHandle(const TaskStateArray &state) { return state(myStateId).myGdh; }
202  bool hasCECache(const TaskStateArray &state) const { return state(myStateId).myCECache; }
203  bool getTimeDependent(const TaskStateArray &state) const { return state(myStateId).myTimeDependent; }
204  void setTimeDependent(TaskStateArray &state, bool timedep) { state(myStateId).myTimeDependent = timedep; }
205  GU_DetailHandle unloadDetailHandle(TaskStateArray &state, bool flushce, UnloadMode unloadmode, UT_ErrorManager &errors, bool allowuncooked=false);
206 
207  void setDetailHandle(TaskStateArray &state, GU_DetailHandle gdh, bool cecache)
208  {
209  markClean(state);
210  state(myStateId).myGdh = gdh;
211  state(myStateId).myCECache = cecache;
212  }
213 
214  void setDelayedCook(TaskStateArray &state, SOP_Node *cooknode, const OP_Context &context)
215  {
216  delete state(myStateId).myDelayedCook;
217  state(myStateId).myDelayedCook = new DelayedCook(cooknode, context);
218  }
219 
220  void lock(TaskStateArray &state)
221  {
222  state(myStateId).myLocked = true;
223  }
224  bool isLocked(TaskStateArray &state) const
225  {
226  return state(myStateId).myLocked;
227  }
228 
229  bool isDirty(const TaskStateArray &state) const { return state(myStateId).myDirty; }
230  void dirty(TaskStateArray &state)
231  {
232  state(myStateId).myDirty = true;
233  state(myStateId).myUseCount = 0;
234  }
235  void markClean(TaskStateArray &state) { state(myStateId).myDirty = false; }
236 
237  bool isParmsDirty(const TaskStateArray &state) const { return state(myStateId).myParmsDirty; }
238  void dirtyParms(TaskStateArray &state) { state(myStateId).myParmsDirty = true; }
239  void markParmsClean(TaskStateArray &state) { state(myStateId).myParmsDirty = false; }
240  bool dependsOnExprInputs(const TaskStateArray &state) const { return state(myStateId).myDependsOnExprInputs; }
241  void clearDependsOnExprInputs(TaskStateArray &state) { state(myStateId).myDependsOnExprInputs = false; }
242  void setDependsOnExprInputs(TaskStateArray &state) { state(myStateId).myDependsOnExprInputs = true; }
243 
244  /// Dirties ourself and all children until we hit something
245  /// already dirty.
246  void dirtyChildren(TaskStateArray &state);
247 
248  /// Computes myself, and chains to any inputs, provided not
249  /// dirty.
250  bool execute(const ExecuteParms &parms);
251 
252  virtual bool doExecute(const ExecuteParms &parms) = 0;
253 
254  bool executeInputs(const ExecuteParms &parms);
255  bool executeExprInputs(const ExecuteParms &parms);
256 
257  void dump(std::ostream &os) const;
258  UT_StringHolder buildName() const;
259 
260  void addError(UT_ErrorManager &errors, const char *messsage) const;
261 
262  const UT_Array<Task *> &inputs() const { return myInputs; }
263  const UT_Array<Task *> &exprInputs() const { return myExprInputs; }
264  const UT_Array<Task *> &outputs() const { return myOutputs; }
265  int stateId() const { return myStateId; }
266 
267  const OP_GraphProxy *graph() const { return myGraph; }
268  OP_GraphProxy::NodeIdx nodeIdx() const { return myNodeIdx; }
269 
270  protected:
271  virtual void dumpSubclass(std::ostream &os) const {}
272 
283  };
284 
285  /// Determine if the compiled task list still matches what
286  /// the SOP network has.
287  bool isTopologyDirty(const OP_Context &context);
288 
289  bool isTopologyTimeDependent() const;
290 
291  void dump(std::ostream &os) const;
292 
293  /// Compile a node block, only rebuilding if Topo dependency is
294  /// invalid
295  bool compile(UT_SharedPtr<const OP_GraphProxy> graph, exint nodeidx, const OP_Context &context, UT_ErrorManager &errors);
296  bool compile(SOP_Node *root, const OP_Context &context, UT_ErrorManager &errors);
297  bool compileMulti(UT_SharedPtr<const OP_GraphProxy> graph, const UT_Array<exint> &roots, const OP_Context &context, UT_ErrorManager &errors);
298  bool compileMulti(const UT_Array<SOP_Node *> &roots, const OP_Context &context, UT_ErrorManager &errors);
299 
300  /// Determines what node is at the root of the compile block
301  OP_Node *getRoot(exint idx = 0) const;
302  OP_GraphProxy::NodeIdx getRootIdx(exint idx = 0) const;
303  exint getNumRoots() const;
304 
305  /// Is the task list compiled & valid?
306  bool isCompiled() const;
307 
308  /// Donate the provided detail to be recycled if needed.
309  /// The passed in handle will be cleared.
310  void donateForRecycling(GU_DetailHandle &gdh);
311 
312  /// Execute our cached block
313  /// The inputgdhs will be cleared as they are used, allowing
314  /// them to be stolen & written to if they are unique.
315  GU_DetailHandle execute(bool &hascedata,
316  TaskStateArray &states,
317  bool flushce,
318  UnloadMode unload,
319  const OP_Context &context,
320  UT_ErrorManager &errors,
321  DEP_MicroNode *depnode,
322  const UT_StringArray &inputnames,
323  UT_Array<GU_DetailHandle> &inputgdhs,
324  const UT_Array<bool> &inputhascedata);
325 
326  /// Execute a compiled block that has multiple roots.
327  void executeMulti(
328  UT_Array<GU_DetailHandle> &outputgdhs,
329  UT_Array<bool> &hascedata,
330  TaskStateArray &states,
331  bool flushce,
332  UnloadMode unload,
333  const OP_Context &context,
334  UT_ErrorManager &errors,
335  DEP_MicroNode *depnode,
336  const UT_StringArray &inputnames,
337  UT_Array<GU_DetailHandle> &inputgdhs,
338  const UT_Array<bool> &inputhascedata);
339 
340  void clear();
341 
342  exint taskCount() const { return myTasks.size(); }
343  exint taskInputCount() const { return myTaskInputs.size(); }
344  exint nodeCount() const { return myNodeSet ? myNodeSet->size() : 0; }
345  void taskNodes(UT_Set<OP_Node *> &usednodes) const;
346 
347  /// Determines somewhat conservatively if the node is eligbile for
348  /// compilation. Verbs always are, but things like subnets are only
349  /// if their SOP contents are as well.
350  static bool canBeCompiled(const OP_Node *node);
351 
352  const UT_Array<Task *> &tasks() const { return myTasks; }
353  const UT_Array<Task *> &roots() const { return myRoots; }
354  const UT_Array<Task *> &taskInputs() const { return myTaskInputs; }
355 
356 
357 protected:
359 
361 
365 
368 };
369 
370 #endif
371 
DelayedCook(SOP_Node *cooknode, const OP_Context &context)
Definition: SOP_Compiled.h:39
void stashAll()
Definition: GA_Detail.h:138
exint taskCount() const
Definition: SOP_Compiled.h:342
exint nodeCount() const
Definition: SOP_Compiled.h:344
UT_Array< Task * > myTaskInputs
Definition: SOP_Compiled.h:364
const UT_Array< Task * > & roots() const
Definition: SOP_Compiled.h:353
void lock(TaskStateArray &state)
Definition: SOP_Compiled.h:220
Unsorted map container.
Definition: UT_Map.h:107
bool isValid() const
Determine if this is a valid handle (!isNull())
DEP_MicroNode * depnode() const
Definition: SOP_Compiled.h:118
DEP_MicroNode * myDepNode
Definition: SOP_Compiled.h:168
bool isGdpIdRecycled(const GU_DetailHandle &gdh) const
Definition: SOP_Compiled.h:147
const UT_Array< Task * > & outputs() const
Definition: SOP_Compiled.h:264
UT_Array< Task * > myOutputs
Definition: SOP_Compiled.h:282
UT_Array< TaskState > TaskStateArray
Definition: SOP_Compiled.h:90
int64 exint
Definition: SYS_Types.h:125
const GU_Detail * gdp() const
**But if you need a result
Definition: thread.h:613
GU_DetailHandle allocGdp(bool clear=true) const
Definition: SOP_Compiled.h:128
UT_ExintArray myRecycledGdpShareCount
Definition: SOP_Compiled.h:172
UT_Array< GU_DetailHandle > * myRecyclingBin
Definition: SOP_Compiled.h:170
bool isDirty(const TaskStateArray &state) const
Definition: SOP_Compiled.h:229
const UT_Array< Task * > & tasks() const
Definition: SOP_Compiled.h:352
bool hasCECache(const TaskStateArray &state) const
Definition: SOP_Compiled.h:202
UT_Array< Task * > myRoots
Definition: SOP_Compiled.h:362
const OP_Context & context() const
Definition: SOP_Compiled.h:116
const OP_GraphProxy * graph() const
Definition: SOP_Compiled.h:267
void allocateAndSet(GU_Detail *gdp, bool own=true)
const UT_Array< Task * > & inputs() const
Definition: SOP_Compiled.h:262
TaskStateArray & myState
Definition: SOP_Compiled.h:164
UT_Array< GU_DetailHandle > myRecyclingBin
Definition: SOP_Compiled.h:367
bool hasRecycleableGdp() const
Definition: SOP_Compiled.h:122
UnloadMode unloadMode() const
Definition: SOP_Compiled.h:115
int getRefCount() const
Returns the number of references made to the base handle.
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
SOP_NodeCache * myNodeCache
Definition: SOP_Compiled.h:84
UT_ErrorManager & myErrors
Definition: SOP_Compiled.h:167
OP_GraphProxy::NodeIdx myNodeIdx
Definition: SOP_Compiled.h:274
OP_Node * getNode() const
Definition: SOP_Compiled.h:199
void dirtyParms(TaskStateArray &state)
Definition: SOP_Compiled.h:238
UT_Array< OP_GraphProxy::NodeIdx > myNodeInputIds
Definition: SOP_Compiled.h:278
GU_DetailHandle getDetailHandle(const TaskStateArray &state)
Definition: SOP_Compiled.h:201
SOP_NodeParms * myNodeParms
Definition: SOP_Compiled.h:85
SOP_NodeVerb::ForbiddenNodeMap * myNodeSet
Definition: SOP_Compiled.h:366
void clearDependsOnExprInputs(TaskStateArray &state)
Definition: SOP_Compiled.h:241
void setTimeDependent(TaskStateArray &state, bool timedep)
Definition: SOP_Compiled.h:204
void setDetailHandle(TaskStateArray &state, GU_DetailHandle gdh, bool cecache)
Definition: SOP_Compiled.h:207
virtual void dumpSubclass(std::ostream &os) const
Definition: SOP_Compiled.h:271
UT_Array< Task * > myInputs
Definition: SOP_Compiled.h:280
TaskStateArray & state() const
Definition: SOP_Compiled.h:114
SOP_NodeParms * myNodeParmsOrig
Definition: SOP_Compiled.h:86
const UT_Array< Task * > & exprInputs() const
Definition: SOP_Compiled.h:263
GU_Detail * gdpNC()
void dirty(TaskStateArray &state)
Definition: SOP_Compiled.h:230
DelayedCook * myDelayedCook
Definition: SOP_Compiled.h:87
exint getUniqueId() const
Definition: GA_Detail.h:117
UT_Array< Task * > myTasks
Definition: SOP_Compiled.h:363
void markClean(TaskStateArray &state)
Definition: SOP_Compiled.h:235
UT_ErrorManager & errors() const
Definition: SOP_Compiled.h:117
DEP_TimedMicroNode myTopoMicroNode
Definition: SOP_Compiled.h:358
static GU_Detail * prepNewDetail(GU_Detail *gdp)
SOP_NodeVerb::ForbiddenNodeMap & forbiddenNodes() const
Definition: SOP_Compiled.h:120
bool isLocked(TaskStateArray &state) const
Definition: SOP_Compiled.h:224
void setDependsOnExprInputs(TaskStateArray &state)
Definition: SOP_Compiled.h:242
UT_ExintArray myRecycledGdpId
Definition: SOP_Compiled.h:171
exint taskInputCount() const
Definition: SOP_Compiled.h:343
const UT_Array< Task * > & taskInputs() const
Definition: SOP_Compiled.h:354
ExecuteParms(TaskStateArray &state, UnloadMode unloadmode, const OP_Context &context, UT_ErrorManager &errors, DEP_MicroNode *depnode, SOP_NodeVerb::ForbiddenNodeMap &forbiddennodes, UT_Array< GU_DetailHandle > *recyclingbin)
Definition: SOP_Compiled.h:97
void markParmsClean(TaskStateArray &state)
Definition: SOP_Compiled.h:239
OP_GraphProxy::NodeIdx getNodeIdx() const
Definition: SOP_Compiled.h:200
A global error manager scope.
#define SOP_API
Definition: SOP_API.h:10
int stateId() const
Definition: SOP_Compiled.h:265
void setDelayedCook(TaskStateArray &state, SOP_Node *cooknode, const OP_Context &context)
Definition: SOP_Compiled.h:214
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:156
const OP_Context & myContext
Definition: SOP_Compiled.h:166
OP_GraphProxy::NodeIdx nodeIdx() const
Definition: SOP_Compiled.h:268
SOP_NodeVerb::ForbiddenNodeMap & myForbiddenNodes
Definition: SOP_Compiled.h:169
const OP_GraphProxy * myGraph
Definition: SOP_Compiled.h:273
bool isParmsDirty(const TaskStateArray &state) const
Definition: SOP_Compiled.h:237
bool dependsOnExprInputs(const TaskStateArray &state) const
Definition: SOP_Compiled.h:240
UT_SharedPtr< const OP_GraphProxy > myGraphProxy
Definition: SOP_Compiled.h:360
UT_Array< Task * > myExprInputs
Definition: SOP_Compiled.h:281
bool getTimeDependent(const TaskStateArray &state) const
Definition: SOP_Compiled.h:203
GU_DetailHandle myGdh
Definition: SOP_Compiled.h:75
virtual OP_Node * idxToNode(NodeIdx idx) const =0