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_WorkItemTypes.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 protected:
59  /// Returns true if this partitioner generates when the target node is
60  /// generated rather than the input nodes
61  inline bool isTargetedPartitioner() const
62  { return (myPartitionWhen > eAllInputsCooked); }
63 
64  /// Sets the loop depth and loop block reference on the node
65  int preCookLoop(
66  const UT_Array<LoopInfo>& begin_info) override;
67 
68  /// Called when this node should clear all work items. Management of the
69  /// main work item array is handled by the parent class, but partitioners
70  /// need to clear their myPartitionMap contents.
71  void clearAllWorkItems() override;
72 
73  /// Called when this node should clear a specific work item. Partitioner
74  /// nodes need to update the myPartitionMap accordingly.
75  void clearWorkItem(
76  const PDG_WorkItem* work_item) override;
77 
78  /// Called when a work item in this node is building depenendcies
79  bool queueWorkItem(
80  PDG_WorkItem* work_item) override;
81 
82  /// Called when a work in this node cook. The partitioner uses this to
83  /// control the data merging process
84  bool cookWorkItem(
85  PDGE_Resolutions& resolutions,
86  PDG_WorkItem* work_item,
87  bool did_cook) override;
88 
89  /// Resets any dependencies owned by this node
90  void resetOwner() override;
91 
92  /// Called when a dependency on this node is resolved
95  PDGE_Resolutions& resolutions,
96  const PDGE_Evaluator& evaluator,
97  PDGE_Dependency* dependency) override;
98 
99  /// Called when a dependency on this node is partially resolved
101  evalPartial(
102  PDGE_Resolutions& resolutions,
103  const PDGE_Evaluator& evaluator,
104  PDGE_Dependency* dependency,
105  const PDGE_DependencyOwner::Array& owners)
106  override;
107 
108  /// Caches any built in parm state for the current cook
109  bool cacheBuiltinParms(
110  PDG_NodeSet& dirty,
111  bool dynamic_inputs) override;
112 
113  /// Adds node dependencies based on the current partitioner settings
114  void addInputDeps(PDG_Node* input_node) override;
115 
116  /// Adds depenencies are that not input specific
117  void addCommonDeps() override;
118 
119 
120  /// Returns true if this node needs to cook its inputs
121  bool requiresCookedInputs(bool cook) const override;
122 
123 private:
124  /// Enumeration of conditions for partitioning work item with missing
125  /// split attributes
126  enum SplitMissing
127  {
128  /// Work items missing the split attribute are ignored
129  eSplitIgnore,
130 
131  /// Work items missing the split attribute are added to the holder
132  /// and the node itself figures out what to do with them.
133  eSplitDefer,
134 
135  /// Work items missing the attribute are added to all partitions.
136  eSplitAll,
137 
138  /// Work items missing the attribute will use a default value
139  eSplitDefault
140  };
141 
142  /// Enumeration of partitioning conditions
143  enum PartitionWhen
144  {
145  /// Partition when all input work items are generated
146  eAllInputsGenerated,
147 
148  /// Partition when all input work items are cooked
149  eAllInputsCooked,
150 
151  /// Partition when all target items are generated
152  eAllTargetsGenerated,
153 
154  /// Partition when each target item group is generated
155  eEachTargetGenerated,
156  };
157 
158  /// Enumeration of frame configuration options
159  enum PartitionFrame
160  {
161  /// The partition will not have its frame set
162  eFrameNone,
163 
164  /// The partition will set its frame from the first work item with
165  /// a frame value
166  eFrameFirst,
167 
168  /// The partition will set its frame from the last work item with
169  /// a frame value
170  eFrameLast,
171 
172  /// The partition will set its frame to the largest frame value
173  /// from all work items
174  eFrameLargest,
175 
176  /// The partition will set its frame to the smallest frame value
177  /// from all work items
178  eFrameSmallest
179  };
180 
181 private:
182 
183  /// Validates and configures targeted nodes
184  bool cacheTargets();
185 
186  /// Loads merge options from pattern parms into our merge pattern object.
187  /// Returns true if the pattern has changed.
188  bool cacheMergePatterns();
189 
190  /// Merges partition data on a specified work item
191  void mergePartitionData(
192  PDG_WorkItem* work_item,
193  bool update);
194 
195  /// Constructs a new partition work item
196  PDG_WorkItem* createPartition(
197  int index,
198  int priority,
199  PDG_OptionalFrame frame);
200 
201  /// Partitions a list of work items that came from a target node
202  bool partitionFromTarget(
203  PDG_WorkItemArray& partitions,
204  PDG_WorkItemArray& new_partitions,
205  PDGE_Resolutions& resolutions,
206  const PDG_WorkItemArray& work_items);
207 
208  /// Constructs partitions from the input work items and target item, and
209  /// returns them back in the output array
210  bool partitionWorkItems(
211  PDG_WorkItemArray& partitions,
212  PDG_WorkItemArray& new_partitions,
213  const PDG_WorkItemArray& work_items,
214  const PDG_WorkItem* target);
215 
216  /// Standard parh for creating partitions
217  bool partitionStandard(
218  PDG_WorkItemArray& partitions,
219  PDG_WorkItemArray& new_partitions,
220  const PDG_WorkItemArray& work_items,
221  const PDG_WorkItem* target,
222  const PDG_PartitionHolder& holder);
223 
224  /// Optimized path for creating a single partition with all work items.
225  bool partitionAll(
226  PDG_WorkItemArray& partitions,
227  PDG_WorkItemArray& new_partitions,
228  const PDG_WorkItemArray& work_items,
229  const PDG_WorkItem* target,
230  const PDG_PartitionHolder& holder,
231  bool add_all);
232 
233  /// Adds a loop dependency for a specified work item
234  void addLoopDependency(
235  PDG_WorkItem* work_item);
236 
237  /// Adds loop dependencies for the specified partitions and input work
238  /// items
239  void addLoopDependencies(
240  const PDG_WorkItemArray& work_items);
241 
242  /// Removes stale partitions from the node.
243  void removeStalePartitions();
244 
245 
246 private:
247  using PartitionMap = UT_ArrayMap<int, PDG_WorkItem*>;
248  using LoopDependencies = UT_Array<UT_UniquePtr<PDGE_Dependency>>;
249 
252 
253  PartitionMap myPartitionMap;
254  PDG_NodeSet myPartitionTargets;
255  PDG_FeedbackBegin* myFeedbackBegin;
256 
257  LoopDependencies myLoopDependencies;
258  TargetMap myTargetPartitions;
259  TargetMapInv myTargetPartitionsInv;
260  PDG_AttributeMerge::Pattern myMergePattern;
261  PDG_AttributeMergeOp myOutputMergeOp;
262 
263  UT_StringHolder myWorkItemIDAttribute;
264 
265  UT_StringHolder mySplitAttribute;
266  UT_StringHolder mySplitDefault;
267  SplitMissing mySplitMissing;
268 
269  PartitionWhen myPartitionWhen;
270  PartitionFrame myPartitionFrame;
271 
272  bool mySplitEnabled;
273  bool mySplitPartial;
274  bool myHasCustomFrame;
275  bool myMergeAttributes;
276  bool myStoreWorkItemIDs;
277  bool myIgnoreFailedItems;
278 };
279 
280 #endif /* __PDG_PARTITIONER_H__ */
virtual bool cookWorkItem(PDGE_Resolutions &resolutions, PDG_WorkItem *work_item, bool did_cook)
virtual bool queueWorkItem(PDG_WorkItem *work_item)
Definition: PDG_Node.h:646
virtual PDGE_Dependency::State evalPartial(PDGE_Resolutions &, const PDGE_Evaluator &, PDGE_Dependency *, const Array &)
friend class PDG_Partitioner
Definition: PDG_Node.h:616
#define PDG_API
Definition: PDG_API.h:23
virtual bool deserializeWorkItem(PDG_WorkItem *work_item)
virtual void clearAllWorkItems()
virtual void addCommonDeps()
UT_Optional< fpreal > PDG_OptionalFrame
Optional frame value, used when constructing work items and partitions.
~PDG_Partitioner() override
virtual void clearWorkItem(const PDG_WorkItem *work_item)
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 memoryInfo(PDG_MemoryInfo &memory_info, bool inclusive) const
Returns the memory usage as a PDG_MemoryInfo struct.
virtual bool requiresCookedInputs(bool cook) const