HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_Partitioner.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  * COMMENTS:
7  */
8 
9 #ifndef __PDG_PARTITIONER_H__
10 #define __PDG_PARTITIONER_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_AttributeMerge.h"
15 #include "PDG_Node.h"
16 #include "PDG_Types.h"
17 
18 #include <UT/UT_Array.h>
19 #include <UT/UT_ArrayMap.h>
20 #include <UT/UT_StringHolder.h>
21 #include <UT/UT_WorkBuffer.h>
22 
23 class PDG_FeedbackBegin;
25 
26 /**
27  * PDG_Node subclass that partitions incoming work items, e.g. it groups
28  * items together into a single unit that can be used for mapping or further
29  * work item generation.
30  */
32 {
33 public:
35  PDG_GraphContext* context,
36  const UT_StringHolder& name,
37  const PDG_NodeCallbackType* type_object,
38  int custom_id = -1);
39 
40  ~PDG_Partitioner() override {}
41 
42  /// Returns the total memory usage of the node, including any work items
43  /// owned by it.
44  void memoryInfo(
45  PDG_MemoryInfo& memory_info,
46  bool inclusive) const override;
47 
48  /// Deserialized the specified work item into this node. Most of the
49  /// work is handled by the parent class, but partitioner nodes need to
50  /// update the myPartitionMap
52  PDG_WorkItem* work_item) override;
53 
54  /// Called after deserializing a work item and adding its dependencies
55  void commitWorkItem(
56  PDG_WorkItem* work_item) override;
57 
58  /// Called when a work in this node cook. The partitioner uses this to
59  /// control the data merging process
60  bool cookWorkItem(
61  PDGE_Resolutions& resolutions,
62  PDG_WorkItem* work_item,
63  bool did_cook) override;
64 
65 protected:
66  /// Returns true if this partitioner generates when the target node is
67  /// generated rather than the input nodes
68  inline bool isTargetedPartitioner() const
69  { return (myPartitionWhen > eAllInputsCooked); }
70 
71  /// Sets the loop depth and loop block reference on the node
72  int preCookLoop(
73  const UT_Array<LoopInfo>& begin_info) override;
74 
75  /// Called when this node should clear all work items. Management of the
76  /// main work item array is handled by the parent class, but partitioners
77  /// need to clear their myPartitionMap contents.
78  void clearAllWorkItems() override;
79 
80  /// Called when this node should clear a specific work item. Partitioner
81  /// nodes need to update the myPartitionMap accordingly.
82  void clearWorkItem(PDG_WorkItem* work_item) override;
83 
84  /// Called when a work item in this node is building depenendcies
85  bool queueWorkItem(
86  PDG_WorkItem* work_item) override;
87 
88  /// Resets any dependencies owned by this node
89  void resetOwner() override;
90 
91  /// Called when a dependency on this node is resolved
94  PDGE_Resolutions& resolutions,
95  const PDGE_Evaluator& evaluator,
96  PDGE_Dependency* dependency) override;
97 
98  /// Called when a dependency on this node is partially resolved
100  evalPartial(
101  PDGE_Resolutions& resolutions,
102  const PDGE_Evaluator& evaluator,
103  PDGE_Dependency* dependency,
104  const PDGE_DependencyOwner::Array& owners)
105  override;
106 
107  /// Caches any built in parm state for the current cook
108  bool cacheBuiltinParms(
109  PDG_NodeSet& dirty,
110  bool dynamic_inputs) override;
111 
112  /// Adds node dependencies based on the current partitioner settings
113  void addInputDeps(PDG_Node* input_node) override;
114 
115  /// Adds depenencies are that not input specific
116  void addCommonDeps() override;
117 
118 
119  /// Returns true if this node needs to cook its inputs
120  bool requiresCookedInputs(bool cook) const override;
121 
122 private:
123  /// Enumeration of conditions for partitioning work item with missing
124  /// split attributes
125  enum SplitMissing
126  {
127  /// Work items missing the split attribute are ignored
128  eSplitIgnore,
129 
130  /// Work items missing the split attribute are added to the holder
131  /// and the node itself figures out what to do with them.
132  eSplitDefer,
133 
134  /// Work items missing the attribute are added to all partitions.
135  eSplitAll,
136 
137  /// Work items missing the attribute will use a default value
138  eSplitDefault
139  };
140 
141  /// Enumeration of partitioning conditions
142  enum PartitionWhen
143  {
144  /// Partition when all input work items are generated
145  eAllInputsGenerated,
146 
147  /// Partition when all input work items are cooked
148  eAllInputsCooked,
149 
150  /// Partition when all target items are generated
151  eAllTargetsGenerated,
152 
153  /// Partition when each target item group is generated
154  eEachTargetGenerated,
155  };
156 
157  /// Enumeration of frame configuration options
158  enum PartitionFrame
159  {
160  /// The partition will not have its frame set
161  eFrameNone,
162 
163  /// The partition will set its frame from the first work item with
164  /// a frame value
165  eFrameFirst,
166 
167  /// The partition will set its frame from the last work item with
168  /// a frame value
169  eFrameLast,
170 
171  /// The partition will set its frame to the largest frame value
172  /// from all work items
173  eFrameLargest,
174 
175  /// The partition will set its frame to the smallest frame value
176  /// from all work items
177  eFrameSmallest
178  };
179 
180 private:
181 
182  /// Validates and configures targeted nodes
183  bool cacheTargets();
184 
185  /// Loads merge options from pattern parms into our merge pattern object.
186  /// Returns true if the pattern has changed.
187  bool cacheMergePatterns();
188 
189  /// Merges partition data on a specified work item
190  void mergePartitionData(
191  PDG_WorkItem* work_item,
192  bool update);
193 
194  /// Constructs a new partition work item
195  PDG_WorkItem* createPartition(
196  int index,
197  int priority,
198  OptionalFrame frame);
199 
200  /// Partitions a list of work items that came from a target node
201  bool partitionFromTarget(
202  PDG_WorkItemArray& partitions,
203  PDG_WorkItemArray& new_partitions,
204  PDGE_Resolutions& resolutions,
205  const PDG_WorkItemArray& work_items);
206 
207  /// Constructs partitions from the input work items and target item, and
208  /// returns them back in the output array
209  bool partitionWorkItems(
210  PDG_WorkItemArray& partitions,
211  PDG_WorkItemArray& new_partitions,
212  const PDG_WorkItemArray& work_items,
213  const PDG_WorkItem* target);
214 
215  /// Standard parh for creating partitions
216  bool partitionWorkItems(
217  PDG_WorkItemArray& partitions,
218  PDG_WorkItemArray& new_partitions,
219  const PDG_WorkItemArray& work_items,
220  const PDG_WorkItem* target,
221  const PDG_PartitionHolder& holder);
222 
223  /// Optimized path for creating a single partition with all work items.
224  bool partitionAll(
225  PDG_WorkItemArray& partitions,
226  PDG_WorkItemArray& new_partitions,
227  const PDG_WorkItemArray& work_items,
228  const PDG_WorkItem* target,
229  const PDG_PartitionHolder& holder,
230  bool add_all);
231 
232  /// Adds a loop dependency for a specified work item
233  void addLoopDependency(
234  PDG_WorkItem* work_item);
235 
236  /// Adds loop dependencies for the specified partitions and input work
237  /// items
238  void addLoopDependencies(
239  const PDG_WorkItemArray& work_items);
240 
241  /// Removes stale partitions from the node.
242  void removeStalePartitions();
243 
244 
245 private:
246  using PartitionMap = UT_ArrayMap<int, PDG_WorkItem*>;
247  using LoopDependencies = UT_Array<UT_UniquePtr<PDGE_Dependency>>;
248 
249  PartitionMap myPartitionMap;
250  PDG_NodeSet myPartitionTargets;
251  PDG_FeedbackBegin* myFeedbackBegin;
252 
253  LoopDependencies myLoopDependencies;
254  PDG_WorkItemMap myTargetPartitions;
255  PDG_WorkItemMap myTargetPartitionsInv;
256  PDG_AttributeMerge::Pattern myMergePattern;
257  PDG_AttributeMergeOp myOutputMergeOp;
258 
259  UT_StringHolder myWorkItemIDAttribute;
260 
261  UT_StringHolder mySplitAttribute;
262  UT_StringHolder mySplitDefault;
263  SplitMissing mySplitMissing;
264 
265  PartitionWhen myPartitionWhen;
266  PartitionFrame myPartitionFrame;
267 
268  bool mySplitEnabled;
269  bool mySplitPartial;
270  bool myHasCustomFrame;
271  bool myMergeAttributes;
272  bool myStoreWorkItemIDs;
273  bool myIgnoreFailedItems;
274 };
275 
276 #endif /* __PDG_PARTITIONER_H__ */
virtual bool cookWorkItem(PDGE_Resolutions &resolutions, PDG_WorkItem *work_item, bool did_cook)
Notifies the node that the specified work item has been cooked.
virtual bool queueWorkItem(PDG_WorkItem *work_item)
Definition: PDG_Node.h:606
virtual PDGE_Dependency::State evalPartial(PDGE_Resolutions &, const PDGE_Evaluator &, PDGE_Dependency *, const Array &)
friend class PDG_Partitioner
Definition: PDG_Node.h:576
#define PDG_API
Definition: PDG_API.h:23
virtual bool deserializeWorkItem(PDG_WorkItem *work_item)
virtual void clearAllWorkItems()
virtual void addCommonDeps()
~PDG_Partitioner() override
UT_Optional< fpreal > OptionalFrame
Definition: PDG_Types.h:86
bool isTargetedPartitioner() const
int preCookLoop()
Sets the loop depth and loop block reference on the node.
GLenum target
Definition: glcorearb.h:1667
GLuint const GLchar * name
Definition: glcorearb.h:786
PDG_AttributeMergeOp
Enumeration of different ways that attributes can be combined.
virtual void addInputDeps(PDG_Node *input_node)
virtual void commitWorkItem(PDG_WorkItem *work_item)
Called after a work item is completely deserialized.
GLuint index
Definition: glcorearb.h:786
virtual PDGE_Dependency::State evalResolve(PDGE_Resolutions &, const PDGE_Evaluator &, PDGE_Dependency *)
Called when a dependency owned by this object is resolved.
virtual bool cacheBuiltinParms(PDG_NodeSet &dirty, bool dynamic_inputs)
void resetOwner() override
Resets the owner.
virtual void clearWorkItem(PDG_WorkItem *work_item)
virtual void memoryInfo(PDG_MemoryInfo &memory_info, bool inclusive) const
Returns the memory usage as a PDG_MemoryInfo struct.
virtual bool requiresCookedInputs(bool cook) const