HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PDG_WorkItem.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_WORKITEM_H__
10 #define __PDG_WORKITEM_H__
11 
12 #include "PDG_API.h"
13 
14 #include "PDG_AttributeOwner.h"
15 #include "PDG_AttributeTypes.h"
16 #include "PDG_EventEmitter.h"
17 #include "PDG_EventTypes.h"
18 #include "PDG_File.h"
19 #include "PDG_LoopInfo.h"
20 #include "PDG_RegisteredType.h"
21 #include "PDG_SchedulerTypes.h"
22 #include "PDG_WorkItemDirty.h"
23 #include "PDG_WorkItemStats.h"
24 #include "PDG_WorkItemTypes.h"
25 
26 #include <PDGE/PDGE_Dependency.h>
28 #include <PDGE/PDGE_Resolutions.h>
29 #include <PDGT/PDGT_Value.h>
30 
31 #include <UT/UT_ArrayStringSet.h>
32 #include <UT/UT_Options.h>
33 #include <UT/UT_StringHolder.h>
34 #include <UT/UT_TBBSpinLock.h>
35 #include <UT/UT_WorkBuffer.h>
36 
38 class PDG_BatchWorkItem;
39 class PDG_Graph;
40 class PDG_GraphContext;
41 struct PDG_MemoryInfo;
42 class PDG_Node;
43 class PDG_Scheduler;
44 class PDG_WorkItemData;
45 
47  public PDG_AttributeOwner,
49 {
50 public:
51  /// Constructs and initialize a new work item. This method will get a
52  /// unique id for the item from the PDG_Graph, unless a valid id is
53  /// passed in
55  PDG_GraphContext* context,
56  bool is_static = true,
59  PDG_WorkItemID id =
60  PDG_WorkItemInvalidID);
61 
62  /// Deletes this work item. Does not delete any dependencies or remove
63  /// references in other items or node. The appropriate dirty method must
64  /// be called first.
65  ~PDG_WorkItem() override;
66 
67  /// Returns the list of supported event types
68  const PDG_EventFilter& supportedEventTypes() const override;
69 
70  /// Returns memory usage for this work item
71  int64 getMemoryUsage(bool inclusive) const override;
72 
73  /// Returns a break down of the memory used by the work item
74  virtual void memoryInfo(PDG_MemoryInfo& memory_info,
75  bool inclusive) const;
76 
77  /// Returns the owning node's attribute lock
78  UT_RWLock* attribGlobalLock() const override;
79 
80  /// Returns true if the work item's attributes are writeable
81  bool attribCanWrite(
82  const PDG_EvaluationContext* ctx) const override;
83 
84  /// Called when the attributes have been unlocked
85  void attribUnlock(bool modified) const override;
86 
87  /// Called when an attributed owned by the work item is modified
88  void attribModify(
89  PDG_AttributeType attrib_type,
90  const UT_StringHolder& attrib_name) const override;
91 
92  /// Called when an attribute operation produces a non-fatal warning
93  void attribWarn(
94  const UT_StringHolder& message) const override;
95 
96  /// Returns a descriptive name of the attribute owner
97  UT_StringHolder attribOwnerName() const override;
98 
99  /// Resets the work item's dependency objects
100  void resetOwner() override;
101 
102  /// Returns the debug name for this work item, used by PDGE for
103  /// logging and debuggin features
104  UT_StringHolder debugName() const override
105  { return name(); }
106 
107  /// Returns the debug group for this work item, used by PDGE for
108  /// outputting a DOT graph.
109  UT_StringHolder debugGroup() const override;
110 
111 
112  /// Returns the can cook dependency object for this work item
114  { return &myCanCookDep; }
115 
116  /// Returns the is cooked dependency object for this work item
118  { return &myIsCookedDep; }
119 
120  /// Returns the work item type
122  { return myType; }
123 
124  /// Returns the work item execution type
126  { return myExecutionType; }
127 
128  /// Returns the work item cook type
130  { return myCookType; }
131 
132  /// Returns the id of the work item, guaranteed to be unique
134  { return myId; }
135 
136 
137  /// Returns the name of the work item, guaranteed to be unique
138  UT_StringHolder name() const;
139 
140  /// Returns true if the work item has a command line string set, for
141  /// any platform
142  bool hasCommand() const;
143 
144  /// Returns true if the work item has platform-specific command line
145  /// strings
146  bool hasPlatformCommand() const;
147 
148  /// Returns the generic command associated with the work item
149  const UT_StringHolder& command() const;
150 
151  /// Returns the platform specific command associated with the work item,
152  /// or the command for the current platform if no platform is specified
153  const UT_StringHolder& platformCommand(
154  PDG_Platform platform=
156 
157  /// Returns true if the command should run in the shell
158  bool shouldRunInShell() const;
159 
160  /// Returns the label assocaited with the work item
161  UT_StringHolder label() const;
162 
163  /// Returns true if the work item has a custom label
164  bool hasLabel() const;
165 
166  /// Returns the custom state string associated with the work item, if
167  /// one has be set.
168  const UT_StringHolder& customState() const;
169 
170  /// Returns true if the work item has a custom state string
171  bool hasCustomState() const;
172 
173 
174  /// Returns the node that owns the work item
175  PDG_Node* node() const
176  { return myNode; }
177 
178  /// Returns the context that owns the work item
180  { return myContext; }
181 
182  /// Returns the graph that the work item belongs to
183  PDG_Graph* graph() const;
184 
185 
186  /// Returns the log URI for the work item using the scheduler associated
187  /// with the node that contains it, or empty string if the work item isn't
188  /// associated with any particular node or scheduler
189  UT_StringHolder logURI() const;
190 
191  /// Returns the status URI for the work item using the scheduler associated
192  /// with the node that contains it, or empty string if the work item isn't
193  /// ascociated with any particular node or scheduler
194  UT_StringHolder statusURI() const;
195 
196 
197  /// Returns the batch item that owns the work item, or nullptr if
198  /// the item is not in a batch
200  { return myBatchParent; }
201 
202  /// Returns the clone target for the work item, or nullptr if a specific
203  /// target was not set
204  const PDG_WorkItem* cloneTarget() const
205  { return myCloneTarget; }
206 
207  /// Const acessor to the work item's parent
208  const PDG_WorkItem* parent() const;
209 
210  /// Returns the work item that this work item copied its attributes
211  /// from. If the work item is a partition, this method returns nullptr.
212  const PDG_WorkItem* attributeSource() const;
213 
214 
215  /// Returns the work item index
216  int index() const
217  { return myIndex; }
218 
219  /// Returns the work item's internal index
220  int internalIndex() const
221  { return myInternalIndex; }
222 
223  /// Returns the work items index within its batch, or -1 if the work item
224  /// is not in a batch
225  int batchIndex() const
226  { return myBatchIndex; }
227 
228  /// Returns the work item priority
229  int priority() const
230  { return myPriority; }
231 
232 
233  /// Returns the cache id of the work item
235  { return myCacheId; }
236 
237  /// Returns the work item frame
238  fpreal frame() const
239  { return myFrame; }
240 
241  /// Returns true if the frame has been set
242  bool hasFrame() const
243  { return myHasFrame; }
244 
245  /// Returns the work item step size, primarily used with batch items
247  { return myFrameStep; }
248 
249  /// Returns true if the work item has any warning log messages
250  bool hasWarnings() const
251  { return myHasWarnings; }
252 
253  /// Returns true if the item is a static work item
254  bool isStatic() const
255  { return myIsStatic; }
256 
257  /// Returns true if the work item is a regular item or batch item
258  bool isRegular() const;
259 
260  /// Returns true if the work item is a partition type
261  bool isPartition() const;
262 
263  /// Returns true if the work item is a dynamic, regular work item
264  bool isDynamic() const;
265 
266  /// Returns true if the work tiem is a batch
267  bool isBatch() const;
268 
269  /// Returns true if the work item is frozen
270  bool isFrozen() const
271  { return myIsFrozen; }
272 
273  /// Returns true if the work item is in process
274  bool isInProcess() const
275  { return (myCookType ==
277 
278  /// Returns true if the work item is marked as a service task
279  bool isServiceMode() const
280  { return (myCookType ==
282 
283  /// Returns true if the work item is scheduled out of process
284  bool isOutOfProcess() const
285  { return (myCookType ==
287 
288  /// Returns true if the work item is scheduled (either service, in, or out
289  /// of process).
290  bool isScheduled() const
291  {
292  if (myCookType ==
294  {
295  return false;
296  }
297 
298  if (myCookType ==
300  {
301  return false;
302  }
303 
304  return true;
305  }
306 
307  /// Returns true if the work item has post-cook logic
308  bool isPostCook() const
309  { return myIsPostCook; }
310 
311  /// Returns true if the work item is flagged as not being allowed to
312  /// generate child items.
313  bool isNoGenerate() const
314  { return myIsNoGenerate; }
315 
316  /// Returns true if the work item is marked as needing to clone output
317  /// files from its parent
318  bool isCloneOutputFiles() const
319  { return myIsCloneOutputFiles; }
320 
321  /// Returns true if the work item has to cook on the main thread, when
322  /// it cooks in process. This is determined by the script info from
323  /// the owning node
324  bool isMainThread() const;
325 
326  /// Returns the work item cook state
328  { return myState; }
329 
330  /// Returns the worst dependency state, e.g. if any of the deps have failed
331  /// or canceled.
333  { return myDepState; }
334 
335  /// Returns true if the work item is in a cooked state
336  bool isCooked() const;
337 
338  /// Returns true if the work item is in a successful cooked state
339  bool isSuccessful() const;
340 
341  /// Returns true if the work item is in a unsucessful cooked state
342  bool isUnsuccessful() const;
343 
344  /// Returns true if the work item is uncooked
345  bool isUncooked() const;
346 
347  /// Returns true if the work item has an unsucessful dependency
348  bool isUnsuccessfulDep() const;
349 
350  /// Returns true if the work item is an cooking/scheduled state
351  bool isProcessing() const;
352 
353  /// Returns true if the work item is long running
354  bool isLongRunning() const;
355 
356  /// Returns an enum indicating if work item is ready to cook, blocked, or
357  /// has failed dependencies
358  PDG_WorkItemEvalState evaluationState() const;
359 
360 
361  /// Returns the edge lock for the work item
363  { return myEdgeLock; }
364 
365  /// Returns the dependencies, e.g. work items that this item depends on. Not
366  /// thread safe.
367  const PDG_WorkItemIDMap& dependenciesUnsafe() const;
368 
369  /// Returns the dependents, e.g. work items that depend on this item. Not
370  /// thread safe.
371  const PDG_WorkItemIDMap& dependentsUnsafe() const;
372 
373  /// Returns a copy of the dependencies in an array
374  void dependencies(
375  PDG_WorkItemConstArray& dependency_array) const;
376 
377  /// Returns the dependency ids in a set
378  void dependencyIds(
379  PDG_WorkItemIDSet& dependency_ids) const;
380 
381  /// Returns the number of dependencies
382  int dependencySize() const;
383 
384  /// Returns a copy of the dependents in an array
385  void dependents(
386  PDG_WorkItemConstArray& dependent_array) const;
387 
388  /// Returns the dependent ids in a set
389  void dependentIds(
390  PDG_WorkItemIDSet& dependent_ids) const;
391 
392  /// Returns the root failed dependencies for this work item. This doesn't
393  /// include intermediate tasks in the dep chain that also failed because of
394  /// the same upstream failure
395  void failedDependencies(
396  PDG_WorkItemConstArray& dependecies) const;
397 
398  /// Returns a copy of the "visual" dependencies, e.g. the ones the user
399  /// would see if they used TOPs or wanted to print out the DAG itself. This
400  /// strips out any intenal items/dependencies used by TOPs
401  void visualDependencies(
402  PDG_WorkItemSet& deps,
403  bool expand,
404  PDG_Scheduler* filter) const;
405 
406  /// Inverse of the above
407  void visualDependents(
408  PDG_WorkItemSet& deps,
409  bool expand,
410  PDG_Scheduler* filter) const;
411 
412  /// Returns the require dependencies, e.g. deps that own this item. This is
413  /// used with partitioning to force the partition to by delete when one of
414  /// it's required dependencies is deleted
415  const PDG_WorkItemIDBoolMap&
416  requiredDependencies() const;
417 
418  /// Returns true if the item is a partition, and stores the partition
419  /// components into the array passed in as a parameter
420  bool partitionItems(
421  PDG_WorkItemConstArray& components) const;
422 
423  /// Flattens dependencies by query all dependencies of the work item,
424  /// and if the the dependency is a wrapper expands it into real items that
425  /// the wrapper depends on.
426  void sortedDependencies(
427  PDG_WorkItemConstArray& sorted_depencies,
428  bool only_upstream=false) const;
429 
430  /// Adds a dependency to the work item, and a corresponding dependent
431  /// back pointer to the incoming item.
432  ///
433  /// Returns false if the dependency already exists, and returns true if the
434  /// dependency does not
435  bool addDependency(
436  PDG_WorkItem* work_item,
437  bool required = false,
438  bool user_defined = false);
439 
440  /// Marks an existing dependency as a required dep. The work item passed in
441  /// *must* already be a dependency
442  void addRequiredDependency(
443  const PDG_WorkItem* work_item,
444  bool user_defined);
445 
446  /// Checks if the work item has a given item as a dependency
447  bool hasDependency(
448  const PDG_WorkItem* work_item) const;
449 
450  /// Removes a dependency and the corresponding back pointer from the target
451  /// work item.
452  bool removeDependency(PDG_WorkItem* work_item);
453 
454  /// Updates the loop stack, with the specified parent
455  void pushLoopInfoStack(
456  const PDG_WorkItem* parent_item);
457 
458  /// Sets the loop stack contents
459  void setLoopInfoStack(
460  const PDG_LoopInfo::Stack& loop_stack);
461 
462  /// Returns the loop stack entry at the specified index;
463  PDG_WorkItem* loopInfoStackEntry(int index) const;
464 
465  /// Returns the loop iteration of the work item
466  int loopInfoIteration() const;
467 
468  /// Returns the loop number of the work item
469  int loopInfoNumber() const;
470 
471  /// Returns the size of the loop that contains the work item
472  int loopInfoSize() const;
473 
474  /// Returns the loop depth of the work item
475  int loopInfoDepth() const;
476 
477  /// Returns the loop service lock ID of the work item
478  PDG_WorkItemID loopInfoLock() const;
479 
480  /// Returns the loop stack for this work item
482  { return myLoopInfoStack; }
483 
484  /// Compares the loop info stack of another work item with this one,
485  /// returning true if they put in the same partition or false if they're
486  /// from independent loops.
487  bool compareLoopInfoStack(
488  const PDG_WorkItem* other) const;
489 
490  /// Sets the is post cook flag
491  void setIsPostCook(bool postcook);
492 
493  /// Sets the work item no generate flag
494  void setIsNoGenerate(bool no_gen);
495 
496  /// Sets the work item's clone output files flag
497  void setIsCloneOutputFiles(bool clone);
498 
499  /// Sets the work item state
500  bool setState(
502  bool emit=true,
503  bool update_node=true);
504 
505  /// Sets the frozen flag on the work item
506  void setIsFrozen(bool is_frozen);
507 
508  /// Sets the execution type of the work item
509  void setExecutionType(
510  PDG_WorkItemExecutionType execution_type);
511 
512  /// Sets the cook type for the work item
513  void setCookType(PDG_WorkItemCookType cook_type);
514 
515  /// Returns the work item's modified flag
516  bool wasModified() const
517  { return myWasModified; }
518 
519  /// Sets the work item index
520  void setIndex(int index);
521 
522  /// Sets the work items internal index, used for dirtying
524  { myInternalIndex = index; }
525 
526  /// Sets the work item priority
527  void setPriority(int priority, bool emit=true);
528 
529  /// Boosts the priority of the work item and its dependencies, if they
530  /// have not yet started to cook
531  void boostPriority();
532 
533  /// Sets the work item frame. This methods takes a step size since it gets
534  /// overridden by batch work items to initialize the frame of each sub item
535  /// as frame + index*step_size;
536  bool clearFrame();
537  bool setFrame(fpreal frame);
538  bool setFrame(fpreal frame, fpreal frame_step);
539  bool setFrame(
540  fpreal frame,
541  fpreal frame_step,
542  bool emit);
543 
544  /// Sets the work item node
545  void setNode(PDG_Node* node, bool emit);
546 
547  /// Sets the pending dirty flag on the work item, used for regeneration
548  virtual void setPendingDirty(
549  PDG_WorkItemPendingDirty pending);
550 
551  /// Called when the work item should begin regenerating
552  void startRegenerating();
553 
554  /// Called when the work item is finished regenerating, in order to
555  /// determine if it needs to be deleted or dirtied
556  PDG_WorkItemPendingDirty doneRegenerating();
557 
558  /// Sets the clone target, e.g. the item from which this item will
559  /// clone attributes
560  void setCloneTarget(
561  const PDG_WorkItem* clone_target);
562 
563  /// Sets the batch item info, e.g. the batch item pointer and the index
564  /// within the batch.
565  void setBatchInfo(PDG_BatchWorkItem* item,
566  int index,
567  int batch_index,
568  int priority);
569 
570  /// Updates the loop iteration and number, at the head of the current
571  /// loop stack
572  void setLoopInfo(
573  int iteration,
574  int number,
575  int size,
576  PDG_WorkItemID service_lock =
577  PDG_WorkItemInvalidID);
578 
579  /// Sets the work item command directly
580  virtual bool setCommand(
581  const UT_StringHolder& command,
582  bool shell=false);
583 
584  /// Sets a per-platform work item command
585  virtual bool setPlatformCommands(
586  const UT_StringHolder& linux,
587  const UT_StringHolder& mac,
588  const UT_StringHolder& windows,
589  bool shell=false);
590 
591  /// Sets the work item label
592  void setLabel(const UT_StringHolder& label);
593 
594  /// Clears the work item label
595  void clearLabel();
596 
597  /// Sets the custom state string. Note that custom states are cleared
598  /// any time the actual work item state changes.
599  void setCustomState(const UT_StringHolder& state);
600 
601  /// Clears the custom state string
602  void clearCustomState();
603 
604  bool hasCookPercent() const;
605  fpreal cookPercent() const;
606  void setCookPercent(const fpreal &cook_percent);
607 
608  /// Appends a formatted error message to the work item's in process
609  /// log buffer
610  template <typename... Args>
612  const char* fmt,
613  Args&&... args) const
614  {
615  appendLogFmt(
616  true,
617  0,
618  "ERROR",
619  fmt,
620  std::forward<Args>(args)...);
621  }
622 
623  /// Appends a plain error message to the work item's in process
624  /// log buffer
625  void addError(
626  const UT_StringHolder& log,
627  bool timestamp=true) const
628  {
629  appendLogPrefix(
630  timestamp,
631  0,
632  "ERROR",
633  log);
634  }
635 
636  /// Appends a formatted warning message to the work item's in process
637  /// log buffer
638  template <typename... Args>
640  const char* fmt,
641  Args&&... args) const
642  {
643  appendLogFmt(
644  true,
645  0,
646  "WARNING",
647  fmt,
648  std::forward<Args>(args)...);
649  myHasWarnings = true;
650  }
651 
652  /// Appends a plain warning message to the work item's in process
653  /// log buffer
655  const UT_StringHolder& log,
656  bool timestamp=true,
657  int verbosity=0) const
658  {
659  appendLogPrefix(
660  timestamp,
661  verbosity,
662  "WARNING",
663  log);
664  myHasWarnings = true;
665  }
666 
667  /// Appends a formatted message to the work item's in process
668  /// log buffer
669  template <typename... Args>
671  const char* fmt,
672  Args&&... args) const
673  {
674  appendLogFmt(
675  true,
676  0,
678  fmt,
679  std::forward<Args>(args)...);
680  }
681 
682  /// Appends a plain message to the work item's in process log buffer
684  const UT_StringHolder& log,
685  bool timestamp=true,
686  int verbosity=0) const
687  {
688  appendLogPrefix(
689  timestamp,
690  verbosity,
692  log);
693  }
694 
695  /// Appends text data to the log with the given log type
696  void addLog(
698  const UT_StringHolder& log,
699  bool timestamp=true,
700  int verbosity=0) const;
701 
702  /// Returns the current in process log buffer
703  const UT_WorkBuffer& logMessages() const
704  { return myLogMessages; }
705 
706  /// Returns the application path to the work item, e.g. /node/workitem
707  void appPath(UT_WorkBuffer& buffer) const;
708 
709  /// Dirties the work item by initiating a dirty operation from the graph.
710  /// Probably the method you want to call to dirty the item if you aren't
711  /// working in $PDG directly
712  void dirty(bool should_delete, bool remove_outputs);
713 
714  /// Dirties the attributes of the work
715  void dirtyData();
716 
717  /// Prepares the work item for dirtying, but does not actually modify the
718  /// item or its dependencies in any way.
719  PDG_WorkItemDirty prepareDirty(bool should_delete);
720 
721  /// Cancels the work item's execution, if it's running with a scheduler
722  void cancel();
723 
724  /// Freezes the attributes of the work item and clears out all references
725  /// to upstream work items and data.
726  void freeze();
727 
728  /// Invalidates the file cache of this work item
729  void invalidateCache();
730 
731  /// Syncs work item data with its parent
732  void syncData(bool force_recursive);
733 
734  /// Getter/setter for the backing work item data object, which might be a
735  /// user defined class
736  PDG_WorkItemData* data() const;
737  void setData(PDG_WorkItemDataPtr data);
738  bool compareDataType(
739  const PDG_BaseType* other_type,
740  bool deep=true) const;
741  SYS_HashType hash() const;
742 
743  /// Does a numeric data lookup, for use with the @ operator
744  PDG_AttributeCast numericData(
745  fpreal& param,
746  exint& query_index,
747  const PDG_AttributeEvaluator& evaluator,
748  fpreal frame,
749  int thread) const;
750 
751  /// Does a string data lookup, for use with the @ operator
752  PDG_AttributeCast stringData(
754  exint& query_index,
755  const PDG_AttributeEvaluator& evaluator,
756  fpreal frame,
757  int thread) const;
758 
759  /// Serialization of underlying PDG_WorkItemData object
760  UT_StringHolder serializeData() const;
761  bool serializeDataToFile(
762  const UT_StringHolder& file) const;
763 
764  /// Compares the work item with another item
765  bool compare(PDG_WorkItem* item) const;
766 
767 
768  /// Runs selection logic from selecting a work item in TOPs
769  bool uiSelect(bool select);
770 
771 
772  /// Returns true if the work item has at least one output file
773  bool hasOutputFiles() const;
774 
775  /// Returns the output file cache state of this work item
776  virtual PDG_WorkItemCacheState
777  outputCacheState() const;
778 
779  /// Returns the raw output file array for the work item. The paths in this
780  /// array are unlocalized, i.e. they may contain __PDG_DIR__
781  bool outputFiles(
782  PDG_File::Array& files) const;
783 
784  /// Localizes output files and returns it back in the supplied array.
785  /// Returns false if the work item has no node or the node has no
786  /// scheduler.
787  bool localizedOutputFiles(
788  PDG_File::Array& files) const;
789 
790  /// Returns the local temporary file directory from the scheduler
791  /// associated with this work item.
792  UT_StringHolder tempDir() const;
793 
794  /// Returns the local working directory from the scheduler associated
795  /// with this work item
796  UT_StringHolder workingDir() const;
797 
798  /// Returns the local script directory from the scheduler associated
799  /// with this work item
800  UT_StringHolder scriptDir() const;
801 
802  /// Returns all output files that are a substring-match for the given tag
803  bool outputFilesForTag(
804  PDG_File::Array& files,
805  const UT_StringHolder& tag,
806  bool include_expected = false) const;
807 
808  /// Localizes a file path with the scheduler associated with the work
809  /// item
810  UT_StringHolder localizePath(
811  const UT_StringHolder& path) const;
812 
813  /// Returns the first output file that is a substring-match for the given
814  /// tag
815  UT_StringHolder firstOutputFileForTag(
816  const UT_StringHolder& tag) const;
817 
818  /// Returns the list of expected output files
819  bool expectedOutputFiles(
820  PDG_File::Array& files) const;
821 
822  /// Adds an expected output file to the work item
823  void addExpectedOutputFile(
824  const UT_StringHolder& path,
825  const UT_StringHolder& tag,
826  bool own);
827 
828  /// Adds an array of expected output file paths to the work item
829  void addExpectedOutputFiles(
830  const UT_StringArray& paths,
831  const UT_StringHolder& tag,
832  bool own);
833 
834  /// Adds an expected output file to the work item
835  void addExpectedOutputFile(const PDG_File& file);
836 
837  /// Appends the given output file to the work item
838  void addOutputFile(
839  const UT_StringHolder& path,
840  const UT_StringHolder& tag,
841  PDG_File::Hash hash_code,
842  bool own);
843 
844  /// Appends the given array of output files to the work item. If the
845  /// length of the hashes array is less than the paths, a default value
846  /// of 0 will be used for paths without a corresponding hash code. I.e
847  /// an empty hash array can be passed in to use 0 for each file. Assumes
848  /// that the same tag is used for all work items
849  void addOutputFiles(
850  const UT_StringArray& paths,
851  const UT_StringHolder& tag,
852  const PDG_File::HashArray& hashes,
853  bool own);
854 
855  /// Appends the given array of output files to the work item. If the length
856  /// of the hashes or tags array is less than the paths, a default value of
857  /// 0 and "" are used respectively.
858  void addOutputFiles(
859  const UT_StringArray& paths,
860  const UT_StringArray& tags,
861  const PDG_File::HashArray& hashes,
862  bool own);
863 
864  /// Replaces the output file at the given index, if that index is valid
865  void updateOutputFile(
866  int index,
867  const UT_StringHolder& path,
868  const UT_StringHolder& tag,
869  PDG_File::Hash hash_code,
870  bool owner);
871 
872  /// Returns the input files for immediate dependencies
873  void inputFiles(
874  PDG_File::Array& files,
875  bool include_expected) const;
876 
877  /// Returns all input files that are a substring-match for the given tag
878  bool inputFilesForTag(
879  PDG_File::Array& files,
880  const UT_StringHolder& tag,
881  bool include_expected = false) const;
882 
883  /// Checks if the work items output files are valid, e.g. they exist
884  bool validateOutputFiles();
885 
886  /// Transfers all dependent files to the remote directory, using the
887  /// supplied scheduler
888  bool transferFiles(bool update_cache);
889 
890  /// Clears all output files
891  void clearOutputFiles();
892 
893  /// Clears expected outputs
894  void clearExpectedOutputFiles();
895 
896  /// Clears output files added during the cook. Note that this method is
897  /// only safe to call if the item has not yet been marked as cooked.
898  void clearRuntimeOutputFiles();
899 
900  /// Sets the clear environment flagging, effectively stopping any upstream
901  /// env vars from being considered beyond this work item
902  void clearEnvironment();
903 
904  /// Adds an environment variable and value to this work items env var map
905  bool addEnvironmentVar(
906  const UT_StringHolder& var_name,
907  const PDGT_Value& value,
908  UT_WorkBuffer& errors);
909 
910  /// Returns true if the work item has the specified env var
911  bool hasEnvironmentVar(
912  const UT_StringHolder& var_name) const;
913 
914  /// Globs the full set of environment variables for this work item by
915  /// searching through it's parents.
916  void globEnvironment(
917  PDGT_Value::Map& environment) const;
918 
919  /// Looks up a key in the environment, returns true if the key exists
920  bool envLookup(const char* key,
921  PDGT_Value& value) const;
922 
923  /// Adds a warning to the owning node
924  void addNodeWarning(
925  const UT_StringHolder& message) const;
926 
927  /// Starts cooking a sub item in a batch, and optionally waits for it to
928  /// be available. Returns false if the item cannot start due to a failure.
929  bool startSubItem(bool wait, UT_WorkBuffer& errors);
930 
931  /// Returns true if the sub item is ready
932  bool checkSubItem(UT_WorkBuffer& errors);
933 
934  /// Marks a work item is cooking, updates it cook start time, and prints
935  /// log messages.
936  bool startWorkItem();
937 
938  /// Marks the work item as cooked, if it is an in-process batch item
939  bool cookSubItem(
941  fpreal duration);
942 
943  /// Returns the scheduler associated with the work item, looked up from the
944  /// work item's node.
945  PDG_Scheduler* scheduler() const;
946 
947  /// Returns true if the work item is schduled by the specified schduler
948  bool isScheduledBy(PDG_Scheduler* scheduler) const;
949 
950  /// Reports a performance monitor event for this work item
951  void performanceEvent() const;
952 
953  /// Sets a stat to the current time
954  virtual fpreal setTimeStat(PDG_WorkItemStats::StatType stat,
955  bool batched);
956 
957  /// Returns the perf stats object for the work item
958  const PDG_WorkItemStats& stats() const
959  { return myStats; }
961  { return myStats; }
962 
963  /// Replaces env vars in the target string with respect to the environment
964  /// and properties of this work item. If py_replace is true, replaces the
965  /// env vars with a valid python token instead of
966  void varReplace(const char* input,
967  UT_WorkBuffer& output) const;
968 
969  /// Saves the work item to a .json file or string
970  bool saveJSONFile(
971  const UT_StringHolder& path,
972  bool pretty_print,
973  bool global_attributes,
974  bool skip_defaults) const;
975  UT_StringHolder saveJSONString(
976  bool pretty_print,
977  bool global_attributes,
978  bool skip_defaults) const;
979 
980  /// Saves the work item to a UT_OptionsHolder
981  UT_OptionsHolder saveDict(
982  bool global_attributes,
983  bool skip_defaults) const;
984 
985  /// Saves the array of work items to a .json file or string
986  static bool saveArrayJSONFile(
987  const UT_StringHolder& path,
988  const PDG_WorkItemArray& items,
989  bool pretty_print,
990  bool global_attributes,
991  bool skip_defaults);
992  static UT_StringHolder saveArrayJSONString(
993  const PDG_WorkItemArray& items,
994  bool pretty_print,
995  bool global_attributes,
996  bool skip_defaults);
997 
998  /// Saves the list of work items to a UT_OptionsHolder
999  static UT_OptionsHolder saveArrayDict(
1000  const PDG_WorkItemArray& items,
1001  bool global_attributes,
1002  bool skip_defaults);
1003 
1004  /// Loads a work item from a .json file or string
1005  static PDG_WorkItem* loadJSONFile(
1006  const UT_StringHolder& path,
1007  bool make_active,
1008  UT_WorkBuffer& errors);
1009  static PDG_WorkItem* loadJSONString(
1010  const UT_StringHolder& data,
1011  bool make_active,
1012  UT_WorkBuffer& errors);
1013 
1014  /// Creates a JSON patch from the work item as a string
1015  UT_StringHolder createJSONPatch(bool pretty_print) const;
1016 
1017 protected:
1018  friend class PDG_BatchWorkItem;
1019  friend class PDG_Scheduler;
1020  friend class PDG_WorkItemHolder;
1021  friend class PDG_WorkItemDirty;
1022 
1023  /// Dirties or deletes the work item and propogates the necessary changes
1024  /// to downstream items and dependents.
1025  void prepareDirty(PDG_WorkItemDirty& dirty_state,
1026  bool is_delete,
1027  bool is_dirty_data) const;
1028 
1029  /// Applies a dirty operation that was stored to the dirty state
1030  void applyDirty(
1031  const PDG_WorkItemDirty& dirty_state,
1032  bool remove_outputs);
1033 
1034  /// Runs custom dirty handlers and deletes output files
1035  void handleDirty(
1036  const UT_ArrayStringSet& keep_set,
1037  bool should_delete,
1038  bool remove_outputs);
1039 
1040  /// Returns the list of files owned by this work item
1041  void ownedFiles(
1042  PDG_File::Set& files,
1043  bool include_expected) const;
1044 
1045  /// Updates the file cache of this work item so the ID is at least as
1046  /// large as the input ID
1047  void updateCacheId(PDG_CacheID cache_id);
1048 
1049 
1050  /// Called when one of the dependencies owned by this work item
1051  /// is resolved.
1053  PDGE_Resolutions& resolutions,
1054  const PDGE_Evaluator& evaluator,
1055  PDGE_Dependency* dependency) override;
1056 
1057  /// Called when one of the dependencies owned by this work item
1058  /// is unresolved;
1059  int evalUnresolve(
1060  PDGE_Dependency::Array& extras,
1061  PDGE_Dependency* dependency) override;
1062 
1063  /// Called when an item is about to be scheduled, to check if it has
1064  /// cached outputs on disk. Returns Uncooked if the item is not cached
1065  /// and should cook, Failure if the read files mode fails, or CookedCache
1066  /// if the item is cooked from cache.
1067  virtual PDG_WorkItemState checkCached(bool add_outputs);
1068 
1069  /// Upgrades expected outputs to runtime outputs for this work item
1070  bool upgradeExpectedOutputFiles(
1071  bool check_disk,
1072  bool clear);
1073 
1074  /// Called by the scheduler to mark out of process items as cooked
1075  void postCook(PDGE_Resolutions& resolutions,
1077  int batch_index,
1078  fpreal duration,
1079  bool notify_all,
1080  bool static_cook,
1081  bool unresolve);
1082 
1083  /// Notifies this work item that is has cooked.
1084  virtual void notifyCook(PDGE_Resolutions& resolutions,
1086  int batch_index,
1087  fpreal duration,
1088  bool notify_all,
1089  bool static_cook,
1090  bool unresolve);
1091 
1092  /// Syncs a work item's cache with its dependents
1093  virtual void syncCacheId();
1094 
1095  /// Does an inprocess cook of the work item, returning true on success
1096  bool cook();
1097 
1098  /// Internal method for setting the frame
1099  virtual bool setFrameInternal(
1100  fpreal frame,
1101  fpreal frame_step,
1102  bool check_dirty,
1103  bool emit);
1104 
1105  /// Adds a parent and copies attributes by inheriting them from the parent
1106  /// of another work item. This is used for generating dynamic sub items
1107  /// in a batch, and copying the parent information from the last batch
1108  /// item onto the new item
1109  void inheritParent(const PDG_WorkItem* work_item);
1110 
1111 private:
1112  /// Removes all dependencies from the work item, and removes them work item
1113  /// from the dependents list of all dependencies
1114  void removeAllDependencies();
1115 
1116  /// Updates the dependency state, given the incoming state
1117  void updateDependencyState(
1118  PDG_WorkItemState dep_state);
1119 
1120  /// Returns a copy of the dependencies in an array, and filters out
1121  /// work items from the target node
1122  void upstreamDependencies(
1123  PDG_WorkItemConstArray& dependency_array) const;
1124 
1125  /// Helper method to query the list of failed upstream dependencies
1126  void failedDependencies(
1127  PDG_WorkItemConstArray& dependencies,
1128  PDG_WorkItemIDSet& visited) const;
1129 
1130  /// Called before the work item is scheduled
1131  bool prepareTask();
1132 
1133  /// Called when a work item should be scheduled for execution
1134  PDG_WorkItemState schedule();
1135 
1136  /// Appends a log message with a time stamp and a new line
1137  void appendLogPrefix(
1138  bool timestamp,
1139  int verbosity,
1140  const UT_StringHolder& prefix,
1141  const UT_StringHolder& msg) const;
1142 
1143  /// Appends a format string to the work item's log
1144  template <typename... Args>
1145  void appendLogFmt(
1146  bool timestamp,
1147  int verbosity,
1148  const UT_StringHolder& prefix,
1149  const char* fmt,
1150  Args&&... args) const
1151  {
1153  message.format(
1154  fmt, std::forward<Args>(args)...);
1155  appendLogPrefix(
1156  timestamp,
1157  verbosity,
1158  prefix,
1159  message.buffer());
1160  }
1161 
1162  /// Processes this work item as a priority boost dep
1163  void processBoostDependency(PDG_WorkItemSet& deps);
1164 
1165  /// Gathers the input dependencies from priority boosting
1166  void gatherBoostDependencies(PDG_WorkItemSet& deps);
1167 
1168 protected:
1171 
1173 
1177 
1179 
1181 
1184 
1187 
1189 
1192 
1194  int myIndex;
1199 
1206 
1208 
1209  bool myHasFrame:1;
1210  mutable bool myHasWarnings:1;
1211 
1212  bool myAttributesDirty:1;
1213  bool myWasModified:1;
1214  bool myDidCook:1;
1215 
1216  bool myIsPostCook:1;
1217  bool myIsStatic:1;
1218  bool myIsNoGenerate:1;
1219  bool myIsCloneOutputFiles:1;
1220  bool myIsFrozen:1;
1221  bool myIsBatchReady:1;
1222 };
1223 
1224 #endif /* __PDG_WORKITEM_H__ */
exint PDG_WorkItemID
Type defs for unique work item IDs.
bool isNoGenerate() const
Definition: PDG_WorkItem.h:313
const PDG_LoopInfo::Stack & loopInfoStack() const
Returns the loop stack for this work item.
Definition: PDG_WorkItem.h:481
bool isScheduled() const
Definition: PDG_WorkItem.h:290
GLuint GLsizei const GLchar * message
Definition: glcorearb.h:2543
bool isPostCook() const
Returns true if the work item has post-cook logic.
Definition: PDG_WorkItem.h:308
PDG_WorkItemIDBoolMap myRequiredDependencies
bool isServiceMode() const
Returns true if the work item is marked as a service task.
Definition: PDG_WorkItem.h:279
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
void addMessageFmt(const char *fmt, Args &&...args) const
Definition: PDG_WorkItem.h:670
PDG_Node * node() const
Returns the node that owns the work item.
Definition: PDG_WorkItem.h:175
bool hasFrame() const
Returns true if the frame has been set.
Definition: PDG_WorkItem.h:242
void addMessage(const UT_StringHolder &log, bool timestamp=true, int verbosity=0) const
Appends a plain message to the work item's in process log buffer.
Definition: PDG_WorkItem.h:683
GLboolean * data
Definition: glcorearb.h:131
void addErrorFmt(const char *fmt, Args &&...args) const
Definition: PDG_WorkItem.h:611
GLsizei const GLfloat * value
Definition: glcorearb.h:824
int index() const
Returns the work item index.
Definition: PDG_WorkItem.h:216
CompareResults OIIO_API compare(const ImageBuf &A, const ImageBuf &B, float failthresh, float warnthresh, float failrelative, float warnrelative, ROI roi={}, int nthreads=0)
virtual UT_RWLock * attribGlobalLock() const
UT_StringHolder debugName() const override
Definition: PDG_WorkItem.h:104
#define PDG_API
Definition: PDG_API.h:23
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
int64 exint
Definition: SYS_Types.h:125
virtual void attribUnlock(bool modified) const
virtual UT_StringHolder attribOwnerName() const
SYS_FORCE_INLINE const char * buffer() const
std::size_t SYS_HashType
Define the type for hash values.
Definition: SYS_Hash.h:19
int batchIndex() const
Definition: PDG_WorkItem.h:225
**But if you need a result
Definition: thread.h:622
bool isOutOfProcess() const
Returns true if the work item is scheduled out of process.
Definition: PDG_WorkItem.h:284
PDG_CacheID myCacheId
PDG_WorkItemType myType
PDG_WorkItemEvalState
bool isCloneOutputFiles() const
Definition: PDG_WorkItem.h:318
GLuint buffer
Definition: glcorearb.h:660
PDG_WorkItemStats myStats
void addWarning(const UT_StringHolder &log, bool timestamp=true, int verbosity=0) const
Definition: PDG_WorkItem.h:654
PDG_WorkItemPendingDirty
Enumeration of pending work item dirty states.
bool wasModified() const
Returns the work item's modified flag.
Definition: PDG_WorkItem.h:516
Unspecified/automatic cook type.
PDG_WorkItemType
Enum of work item types.
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
PDG_Node * myNode
virtual bool attribCanWrite(const PDG_EvaluationContext *context) const
int64 Hash
The file hash/modtime type.
Definition: PDG_File.h:39
PDGE_Dependency myIsCookedDep
PDG_WorkItemState myState
PDGE_Dependency * isCookedDep()
Returns the is cooked dependency object for this work item.
Definition: PDG_WorkItem.h:117
vint4 select(const vbool4 &mask, const vint4 &a, const vint4 &b)
Definition: simd.h:4983
PDG_GraphContext * context() const
Returns the context that owns the work item.
Definition: PDG_WorkItem.h:179
PDG_WorkItemState
Enum of possible work item states.
fpreal frame() const
Returns the work item frame.
Definition: PDG_WorkItem.h:238
PDG_WorkItemPendingDirty myPendingDirty
static const UT_StringHolder theEmptyString
virtual void attribModify(PDG_AttributeType attrib_type, const UT_StringHolder &attrib_name) const
PDG_AttributeCast
Enumeration of attribute cast results.
The work item cooks as a service.
The work item cooks out of process.
const UT_WorkBuffer & logMessages() const
Returns the current in process log buffer.
Definition: PDG_WorkItem.h:703
PDG_BatchWorkItem * batchParent() const
Definition: PDG_WorkItem.h:199
long long int64
Definition: SYS_Types.h:116
PDG_AttributeType
Enumeration of possible attribute types.
void applyDirty(bool remove_outputs)
Applies the stored dirty operation.
bool isFrozen() const
Returns true if the work item is frozen.
Definition: PDG_WorkItem.h:270
virtual int64 getMemoryUsage(bool inclusive) const
Returns the memory usage of this owner instance.
PDG_WorkItemCookType
Enumeration of work item cook types.
The work item cooks in process.
GLuint const GLchar * name
Definition: glcorearb.h:786
fpreal frameStep() const
Returns the work item step size, primarily used with batch items.
Definition: PDG_WorkItem.h:246
bool isInProcess() const
Returns true if the work item is in process.
Definition: PDG_WorkItem.h:274
PDG_WorkItemType type() const
Returns the work item type.
Definition: PDG_WorkItem.h:121
PDG_Platform
Enumeration of supported platforms, for work item command line array.
PDG_WorkItemID myId
PDG_WorkItemIDMap myDependencies
void addError(const UT_StringHolder &log, bool timestamp=true) const
Definition: PDG_WorkItem.h:625
PDG_WorkItemLogType
Enumeration of work item log message types.
PDG_WorkItemCacheState
fpreal myFrameStep
StatType
Enumeration of stats stored in this object.
*tasks wait()
UT_TBBSpinLock myEdgeLock
No specified platform.
GLsizeiptr size
Definition: glcorearb.h:664
**Note that the tasks the is the thread number *for the or if it s being executed by a non pool thread(this *can happen in cases where the whole pool is occupied and the calling *thread contributes to running the work load).**Thread pool.Have fun
PDG_BatchWorkItem * myBatchParent
UT_SharedPtr< PDG_WorkItemData > PDG_WorkItemDataPtr
Type def for registered type objects.
GLenum GLfloat param
Definition: glcorearb.h:104
size_t format(const char *fmt, const Args &...args)
PDG_CacheID cacheId() const
Returns the cache id of the work item.
Definition: PDG_WorkItem.h:234
PDG_WorkItemExecutionType myExecutionType
fpreal64 fpreal
Definition: SYS_Types.h:283
UT_TBBSpinLock & edgeLock() const
Returns the edge lock for the work item.
Definition: PDG_WorkItem.h:362
PDG_WorkItemDataPtr myData
PDG_LoopInfo::Stack myLoopInfoStack
PDG_WorkItemID id() const
Returns the id of the work item, guaranteed to be unique.
Definition: PDG_WorkItem.h:133
GLuint index
Definition: glcorearb.h:786
PDG_WorkItemIDMap myDependents
PDGE_Dependency * canCookDep()
Returns the can cook dependency object for this work item.
Definition: PDG_WorkItem.h:113
PDG_WorkItemState dependencyState() const
Definition: PDG_WorkItem.h:332
PDGE_Dependency myCanCookDep
void addWarningFmt(const char *fmt, Args &&...args) const
Definition: PDG_WorkItem.h:639
virtual PDGE_Dependency::State evalResolve(PDGE_Resolutions &, const PDGE_Evaluator &, PDGE_Dependency *)
Called when a dependency owned by this object is resolved.
void setInternalIndex(int index)
Sets the work items internal index, used for dirtying.
Definition: PDG_WorkItem.h:523
PDG_WorkItemState myDepState
virtual UT_StringHolder debugGroup() const
bool hasWarnings() const
Returns true if the work item has any warning log messages.
Definition: PDG_WorkItem.h:250
**If you just want to fire and args
Definition: thread.h:618
PDG_WorkItemStats & stats()
Definition: PDG_WorkItem.h:960
PDG_WorkItemExecutionType
Enum of work item runtime types.
void updateCacheId(const PDG_WorkItem *dependent, const PDG_WorkItem *dependency)
Updates the cache ID of the work item for a dependency.
PDG_WorkItemCookType myCookType
virtual void attribWarn(const UT_StringHolder &msg) const
UT_WorkBuffer myLogMessages
const PDG_WorkItemStats & stats() const
Returns the perf stats object for the work item.
Definition: PDG_WorkItem.h:958
PDG_WorkItemState state() const
Returns the work item cook state.
Definition: PDG_WorkItem.h:327
PDG_GraphContext * myContext
int priority() const
Returns the work item priority.
Definition: PDG_WorkItem.h:229
PDG_WorkItemCookType cookType() const
Returns the work item cook type.
Definition: PDG_WorkItem.h:129
virtual int evalUnresolve(PDGE_Dependency::Array &, PDGE_Dependency *)
OIIO_FORCEINLINE T log(const T &v)
Definition: simd.h:7905
bool isStatic() const
Returns true if the item is a static work item.
Definition: PDG_WorkItem.h:254
Reader/Writer mutex class.
Definition: UT_RWLock.h:48
virtual void resetOwner()
Resets the owner.
PDG_WorkItemExecutionType executionType() const
Returns the work item execution type.
Definition: PDG_WorkItem.h:125
const PDG_WorkItem * myCloneTarget
state
Definition: core.h:2289
void prepareDirty(PDG_WorkItem *work_item)
Adds a work item and its dependencies to the dirty sets.
Definition: format.h:1821
const PDG_WorkItem * cloneTarget() const
Definition: PDG_WorkItem.h:204
virtual const PDG_EventFilter & supportedEventTypes() const =0
Returns the list of supported event types for this emitter.
int internalIndex() const
Returns the work item's internal index.
Definition: PDG_WorkItem.h:220
int PDG_CacheID
Definition: PDG_NodeTypes.h:30
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297