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 <OP/OP_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  OP_GraphProxy::NodeOrIdx getNodeOrIdx() const { return OP_GraphProxy::NodeOrIdx(myNodeIdx, getNode()); }
202  GU_DetailHandle getDetailHandle(const TaskStateArray &state) { return state(myStateId).myGdh; }
203  bool hasCECache(const TaskStateArray &state) const { return state(myStateId).myCECache; }
204  bool getTimeDependent(const TaskStateArray &state) const { return state(myStateId).myTimeDependent; }
205  void setTimeDependent(TaskStateArray &state, bool timedep) { state(myStateId).myTimeDependent = timedep; }
206  GU_DetailHandle unloadDetailHandle(TaskStateArray &state, bool flushce, UnloadMode unloadmode, UT_ErrorManager &errors, bool allowuncooked=false);
207 
208  void setDetailHandle(TaskStateArray &state, GU_DetailHandle gdh, bool cecache)
209  {
210  markClean(state);
211  state(myStateId).myGdh = gdh;
212  state(myStateId).myCECache = cecache;
213  }
214 
215  void setDelayedCook(TaskStateArray &state, SOP_Node *cooknode, const OP_Context &context)
216  {
217  delete state(myStateId).myDelayedCook;
218  state(myStateId).myDelayedCook = new DelayedCook(cooknode, context);
219  }
220 
221  void lock(TaskStateArray &state)
222  {
223  state(myStateId).myLocked = true;
224  }
225  bool isLocked(TaskStateArray &state) const
226  {
227  return state(myStateId).myLocked;
228  }
229 
230  bool isDirty(const TaskStateArray &state) const { return state(myStateId).myDirty; }
231  void dirty(TaskStateArray &state)
232  {
233  state(myStateId).myDirty = true;
234  state(myStateId).myUseCount = 0;
235  }
236  void markClean(TaskStateArray &state) { state(myStateId).myDirty = false; }
237 
238  bool isParmsDirty(const TaskStateArray &state) const { return state(myStateId).myParmsDirty; }
239  void dirtyParms(TaskStateArray &state) { state(myStateId).myParmsDirty = true; }
240  void markParmsClean(TaskStateArray &state) { state(myStateId).myParmsDirty = false; }
241  bool dependsOnExprInputs(const TaskStateArray &state) const { return state(myStateId).myDependsOnExprInputs; }
242  void clearDependsOnExprInputs(TaskStateArray &state) { state(myStateId).myDependsOnExprInputs = false; }
243  void setDependsOnExprInputs(TaskStateArray &state) { state(myStateId).myDependsOnExprInputs = true; }
244 
245  /// Dirties ourself and all children until we hit something
246  /// already dirty.
247  void dirtyChildren(TaskStateArray &state);
248 
249  /// Computes myself, and chains to any inputs, provided not
250  /// dirty.
251  bool execute(const ExecuteParms &parms);
252 
253  virtual bool doExecute(const ExecuteParms &parms) = 0;
254 
255  bool executeInputs(const ExecuteParms &parms);
256  bool executeExprInputs(const ExecuteParms &parms);
257 
258  void dump(std::ostream &os) const;
259  UT_StringHolder buildName() const;
260 
261  void addError(UT_ErrorManager &errors, const char *messsage) const;
262 
263  const UT_Array<Task *> &inputs() const { return myInputs; }
264  const UT_Array<Task *> &exprInputs() const { return myExprInputs; }
265  const UT_Array<Task *> &outputs() const { return myOutputs; }
266  int stateId() const { return myStateId; }
267 
268  const OP_GraphProxy *graph() const { return myGraph; }
269  OP_GraphProxy::NodeIdx nodeIdx() const { return myNodeIdx; }
270 
271  protected:
272  virtual void dumpSubclass(std::ostream &os) const {}
273 
284  };
285 
286  /// Determine if the compiled task list still matches what
287  /// the SOP network has.
288  bool isTopologyDirty(const OP_Context &context);
289 
290  bool isTopologyTimeDependent() const;
291 
292  void dump(std::ostream &os) const;
293 
294  /// Compile a node block, only rebuilding if Topo dependency is
295  /// invalid
296  bool compile(UT_SharedPtr<const OP_GraphProxy> graph, exint nodeidx, const OP_Context &context, UT_ErrorManager &errors);
297  bool compile(SOP_Node *root, const OP_Context &context, UT_ErrorManager &errors);
298  bool compileMulti(UT_SharedPtr<const OP_GraphProxy> graph, const UT_Array<exint> &roots, const OP_Context &context, UT_ErrorManager &errors);
299  bool compileMulti(const UT_Array<SOP_Node *> &roots, const OP_Context &context, UT_ErrorManager &errors);
300 
301  /// Determines what node is at the root of the compile block
302  OP_Node *getRoot(exint idx = 0) const;
303  OP_GraphProxy::NodeIdx getRootIdx(exint idx = 0) const;
304  exint getNumRoots() const;
305 
306  /// Is the task list compiled & valid?
307  bool isCompiled() const;
308 
309  /// Donate the provided detail to be recycled if needed.
310  /// The passed in handle will be cleared.
311  void donateForRecycling(GU_DetailHandle &gdh);
312 
313  /// Execute our cached block
314  /// The inputgdhs will be cleared as they are used, allowing
315  /// them to be stolen & written to if they are unique.
316  GU_DetailHandle execute(bool &hascedata,
317  TaskStateArray &states,
318  bool flushce,
319  UnloadMode unload,
320  const OP_Context &context,
321  UT_ErrorManager &errors,
322  DEP_MicroNode *depnode,
323  const UT_StringArray &inputnames,
324  UT_Array<GU_DetailHandle> &inputgdhs,
325  const UT_Array<bool> &inputhascedata);
326 
327  /// Execute a compiled block that has multiple roots.
328  void executeMulti(
329  UT_Array<GU_DetailHandle> &outputgdhs,
330  UT_Array<bool> &hascedata,
331  TaskStateArray &states,
332  bool flushce,
333  UnloadMode unload,
334  const OP_Context &context,
335  UT_ErrorManager &errors,
336  DEP_MicroNode *depnode,
337  const UT_StringArray &inputnames,
338  UT_Array<GU_DetailHandle> &inputgdhs,
339  const UT_Array<bool> &inputhascedata);
340 
341  void clear();
342 
343  exint taskCount() const { return myTasks.size(); }
344  exint taskInputCount() const { return myTaskInputs.size(); }
345  exint nodeCount() const { return myNodeSet ? myNodeSet->size() : 0; }
346  void taskNodes(UT_Set<OP_Node *> &usednodes) const;
347 
348  /// Determines somewhat conservatively if the node is eligbile for
349  /// compilation. Verbs always are, but things like subnets are only
350  /// if their SOP contents are as well.
351  static bool canBeCompiled(const OP_Node *node);
352 
353  const UT_Array<Task *> &tasks() const { return myTasks; }
354  const UT_Array<Task *> &roots() const { return myRoots; }
355  const UT_Array<Task *> &taskInputs() const { return myTaskInputs; }
356 
357 
358 protected:
360 
362 
366 
369 };
370 
371 #endif
372 
DelayedCook(SOP_Node *cooknode, const OP_Context &context)
Definition: SOP_Compiled.h:39
void stashAll()
Definition: GA_Detail.h:147
exint taskCount() const
Definition: SOP_Compiled.h:343
exint nodeCount() const
Definition: SOP_Compiled.h:345
UT_Array< Task * > myTaskInputs
Definition: SOP_Compiled.h:365
const UT_Array< Task * > & roots() const
Definition: SOP_Compiled.h:354
void lock(TaskStateArray &state)
Definition: SOP_Compiled.h:221
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:265
UT_Array< Task * > myOutputs
Definition: SOP_Compiled.h:283
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:622
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:230
const UT_Array< Task * > & tasks() const
Definition: SOP_Compiled.h:353
bool hasCECache(const TaskStateArray &state) const
Definition: SOP_Compiled.h:203
UT_Array< Task * > myRoots
Definition: SOP_Compiled.h:363
const OP_Context & context() const
Definition: SOP_Compiled.h:116
const OP_GraphProxy * graph() const
Definition: SOP_Compiled.h:268
void allocateAndSet(GU_Detail *gdp, bool own=true)
const UT_Array< Task * > & inputs() const
Definition: SOP_Compiled.h:263
TaskStateArray & myState
Definition: SOP_Compiled.h:164
UT_Array< GU_DetailHandle > myRecyclingBin
Definition: SOP_Compiled.h:368
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:275
OP_Node * getNode() const
Definition: SOP_Compiled.h:199
void dirtyParms(TaskStateArray &state)
Definition: SOP_Compiled.h:239
OP_GraphProxy::NodeOrIdx getNodeOrIdx() const
Definition: SOP_Compiled.h:201
UT_Array< OP_GraphProxy::NodeIdx > myNodeInputIds
Definition: SOP_Compiled.h:279
GU_DetailHandle getDetailHandle(const TaskStateArray &state)
Definition: SOP_Compiled.h:202
SOP_NodeParms * myNodeParms
Definition: SOP_Compiled.h:85
SOP_NodeVerb::ForbiddenNodeMap * myNodeSet
Definition: SOP_Compiled.h:367
void clearDependsOnExprInputs(TaskStateArray &state)
Definition: SOP_Compiled.h:242
void setTimeDependent(TaskStateArray &state, bool timedep)
Definition: SOP_Compiled.h:205
void setDetailHandle(TaskStateArray &state, GU_DetailHandle gdh, bool cecache)
Definition: SOP_Compiled.h:208
virtual void dumpSubclass(std::ostream &os) const
Definition: SOP_Compiled.h:272
UT_Array< Task * > myInputs
Definition: SOP_Compiled.h:281
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:264
GU_Detail * gdpNC()
void dirty(TaskStateArray &state)
Definition: SOP_Compiled.h:231
DelayedCook * myDelayedCook
Definition: SOP_Compiled.h:87
exint getUniqueId() const
Definition: GA_Detail.h:126
UT_Array< Task * > myTasks
Definition: SOP_Compiled.h:364
void markClean(TaskStateArray &state)
Definition: SOP_Compiled.h:236
UT_ErrorManager & errors() const
Definition: SOP_Compiled.h:117
GA_API const UT_StringHolder parms
DEP_TimedMicroNode myTopoMicroNode
Definition: SOP_Compiled.h:359
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:225
void setDependsOnExprInputs(TaskStateArray &state)
Definition: SOP_Compiled.h:243
UT_ExintArray myRecycledGdpId
Definition: SOP_Compiled.h:171
exint taskInputCount() const
Definition: SOP_Compiled.h:344
const UT_Array< Task * > & taskInputs() const
Definition: SOP_Compiled.h:355
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:240
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:266
void setDelayedCook(TaskStateArray &state, SOP_Node *cooknode, const OP_Context &context)
Definition: SOP_Compiled.h:215
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:165
const OP_Context & myContext
Definition: SOP_Compiled.h:166
OP_GraphProxy::NodeIdx nodeIdx() const
Definition: SOP_Compiled.h:269
SOP_NodeVerb::ForbiddenNodeMap & myForbiddenNodes
Definition: SOP_Compiled.h:169
const OP_GraphProxy * myGraph
Definition: SOP_Compiled.h:274
bool isParmsDirty(const TaskStateArray &state) const
Definition: SOP_Compiled.h:238
bool dependsOnExprInputs(const TaskStateArray &state) const
Definition: SOP_Compiled.h:241
state
Definition: core.h:2289
UT_SharedPtr< const OP_GraphProxy > myGraphProxy
Definition: SOP_Compiled.h:361
UT_Array< Task * > myExprInputs
Definition: SOP_Compiled.h:282
bool getTimeDependent(const TaskStateArray &state) const
Definition: SOP_Compiled.h:204
GU_DetailHandle myGdh
Definition: SOP_Compiled.h:75
virtual OP_Node * idxToNode(NodeIdx idx) const =0