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