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(
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  bool setFrame(
555  fpreal frame,
556  fpreal frame_step,
557  bool emit);
558 
559  /// Sets the work item node
560  void setNode(PDG_Node* node, bool emit);
561 
562  /// Sets the pending dirty flag on the work item, used for regeneration
563  virtual void setPendingDirty(PendingDirty pending);
564 
565  /// Called when the work item should begin regenerating
566  void startRegenerating();
567 
568  /// Called when the work item is finished regenerating, in order to
569  /// determine if it needs to be deleted or dirtied
570  PendingDirty doneRegenerating();
571 
572  /// Sets the clone target, e.g. the item from which this item will
573  /// clone attributes
574  void setCloneTarget(
575  const PDG_WorkItem* clone_target);
576 
577  /// Sets the batch item info, e.g. the batch item pointer and the index
578  /// within the batch.
579  void setBatchInfo(PDG_BatchWorkItem* item,
580  int index,
581  int batch_index,
582  int priority);
583 
584  /// Updates the loop iteration and number, at the head of the current
585  /// loop stack
586  void setLoopInfo(
587  int iteration,
588  int number,
589  int size,
590  PDG_WorkItemID service_lock=theInvalidId);
591 
592  /// Sets the work item command directly
593  virtual bool setCommand(
594  const UT_StringHolder& command,
595  bool shell=false);
596 
597  /// Sets a per-platform work item command
598  virtual bool setPlatformCommands(
599  const UT_StringHolder& linux,
600  const UT_StringHolder& mac,
601  const UT_StringHolder& windows,
602  bool shell=false);
603 
604  /// Sets the work item label
605  void setLabel(const UT_StringHolder& label);
606 
607  /// Clears the work item label
608  void clearLabel();
609 
610  /// Sets the custom state string. Note that custom states are cleared
611  /// any time the actual work item state changes.
612  void setCustomState(const UT_StringHolder& state);
613 
614  /// Clears the custom state string
615  void clearCustomState();
616 
617  bool hasCookPercent() const;
618  fpreal cookPercent() const;
619  void setCookPercent(const fpreal &cook_percent);
620 
621  /// Appends a formatted error message to the work item's in process
622  /// log buffer
623  template <typename... Args>
625  const char* fmt,
626  Args&&... args) const
627  {
628  appendLogFmt(
629  true,
630  0,
631  "ERROR",
632  fmt,
633  std::forward<Args>(args)...);
634  }
635 
636  /// Appends a plain error message to the work item's in process
637  /// log buffer
638  void addError(
639  const UT_StringHolder& log,
640  bool timestamp=true) const
641  {
642  appendLogPrefix(
643  timestamp,
644  0,
645  "ERROR",
646  log);
647  }
648 
649  /// Appends a formatted warning message to the work item's in process
650  /// log buffer
651  template <typename... Args>
653  const char* fmt,
654  Args&&... args) const
655  {
656  appendLogFmt(
657  true,
658  0,
659  "WARNING",
660  fmt,
661  std::forward<Args>(args)...);
662  myHasWarnings = true;
663  }
664 
665  /// Appends a plain warning message to the work item's in process
666  /// log buffer
668  const UT_StringHolder& log,
669  bool timestamp=true,
670  int verbosity=0) const
671  {
672  appendLogPrefix(
673  timestamp,
674  verbosity,
675  "WARNING",
676  log);
677  myHasWarnings = true;
678  }
679 
680  /// Appends a formatted message to the work item's in process
681  /// log buffer
682  template <typename... Args>
684  const char* fmt,
685  Args&&... args) const
686  {
687  appendLogFmt(
688  true,
689  0,
691  fmt,
692  std::forward<Args>(args)...);
693  }
694 
695  /// Appends a plain message to the work item's in process log buffer
697  const UT_StringHolder& log,
698  bool timestamp=true,
699  int verbosity=0) const
700  {
701  appendLogPrefix(
702  timestamp,
703  verbosity,
705  log);
706  }
707 
708  /// Appends text data to the log with the given log type
709  void addLog(
711  const UT_StringHolder& log,
712  bool timestamp=true,
713  int verbosity=0) const;
714 
715  /// Returns the current in process log buffer
716  const UT_WorkBuffer& logMessages() const
717  { return myLogMessages; }
718 
719  /// Returns the application path to the work item, e.g. /node/workitem
720  void appPath(UT_WorkBuffer& buffer) const;
721 
722  /// Dirties the work item by initiating a dirty operation from the graph.
723  /// Probably the method you want to call to dirty the item if you aren't
724  /// working in $PDG directly
725  void dirty(bool should_delete, bool remove_outputs);
726 
727  /// Dirties the attributes of the work
728  void dirtyData();
729 
730  /// Prepares the work item for dirtying, but does not actually modify the
731  /// item or its dependencies in any way.
732  PDG_WorkItemDirty prepareDirty(bool should_delete);
733 
734  /// Cancels the work item's execution, if it's running with a scheduler
735  void cancel();
736 
737  /// Freezes the attributes of the work item and clears out all references
738  /// to upstream work items and data.
739  void freeze();
740 
741  /// Invalidates the file cache of this work item
742  void invalidateCache();
743 
744  /// Syncs work item data with its parent
745  void syncData(bool force_recursive);
746 
747  /// Getter/setter for the backing work item data object, which might be a
748  /// user defined class
749  PDG_WorkItemData* data() const;
750  void setData(PDG_WorkItemDataPtr data);
751  bool compareDataType(
752  const PDG_BaseType* other_type,
753  bool deep=true) const;
754  SYS_HashType hash() const;
755 
756  /// Does a numeric data lookup, for use with the @ operator
757  PDG_AttributeCast numericData(
758  fpreal& param,
759  exint& query_index,
760  const PDG_AttributeEvaluator& evaluator,
761  fpreal frame,
762  int thread) const;
763 
764  /// Does a string data lookup, for use with the @ operator
765  PDG_AttributeCast stringData(
767  exint& query_index,
768  const PDG_AttributeEvaluator& evaluator,
769  fpreal frame,
770  int thread) const;
771 
772  /// Serialization of underlying PDG_WorkItemData object
773  UT_StringHolder serializeData() const;
774  bool serializeDataToFile(
775  const UT_StringHolder& file) const;
776 
777  /// Compares the work item with another item
778  bool compare(PDG_WorkItem* item) const;
779 
780 
781  /// Runs selection logic from selecting a work item in TOPs
782  bool uiSelect(bool select);
783 
784 
785  /// Returns true if the work item has at least one output file
786  bool hasOutputFiles() const;
787 
788  /// Returns the output file cache state of this work item
789  virtual PDG_WorkItemCacheState
790  outputCacheState() const;
791 
792  /// Returns the raw output file array for the work item. The paths in this
793  /// array are unlocalized, i.e. they may contain __PDG_DIR__
794  bool outputFiles(
795  PDG_File::Array& files) const;
796 
797  /// Localizes output files and returns it back in the supplied array.
798  /// Returns false if the work item has no node or the node has no
799  /// scheduler.
800  bool localizedOutputFiles(
801  PDG_File::Array& files) const;
802 
803  /// Returns the local temporary file directory from the sechduler
804  /// associated with this work item.
805  UT_StringHolder tempDir() const;
806 
807  /// Returns all output files that are a substring-match for the given tag
808  bool outputFilesForTag(
809  PDG_File::Array& files,
810  const UT_StringHolder& tag,
811  bool include_expected = false) const;
812 
813  /// Localizes a file path with the scheduler associated with the work
814  /// item
815  UT_StringHolder localizePath(
816  const UT_StringHolder& path) const;
817 
818  /// Returns the first output file that is a substring-match for the given
819  /// tag
820  UT_StringHolder firstOutputFileForTag(
821  const UT_StringHolder& tag) const;
822 
823  /// Returns the list of expected output files
824  bool expectedOutputFiles(
825  PDG_File::Array& files) const;
826 
827  /// Adds an expected output file to the work item
828  void addExpectedOutputFile(
829  const UT_StringHolder& path,
830  const UT_StringHolder& tag,
831  bool own);
832 
833  /// Adds an array of expected output file paths to the work item
834  void addExpectedOutputFiles(
835  const UT_StringArray& paths,
836  const UT_StringHolder& tag,
837  bool own);
838 
839  /// Adds an expected output file to the work item
840  void addExpectedOutputFile(const PDG_File& file);
841 
842  /// Appends the given output file to the work item
843  void addOutputFile(
844  const UT_StringHolder& path,
845  const UT_StringHolder& tag,
846  PDG_File::Hash hash_code,
847  bool own);
848 
849  /// Appends the given array of output files to the work item. If the
850  /// length of the hashes array is less than the paths, a default value
851  /// of 0 will be used for paths without a corresponding hash code. I.e
852  /// an empty hash array can be passed in to use 0 for each file. Assumes
853  /// that the same tag is used for all work items
854  void addOutputFiles(
855  const UT_StringArray& paths,
856  const UT_StringHolder& tag,
857  const PDG_File::HashArray& hashes,
858  bool own);
859 
860  /// Appends the given array of output files to the work item. If the length
861  /// of the hashes or tags array is less than the paths, a default value of
862  /// 0 and "" are used respectively.
863  void addOutputFiles(
864  const UT_StringArray& paths,
865  const UT_StringArray& tags,
866  const PDG_File::HashArray& hashes,
867  bool own);
868 
869  /// Replaces the output file at the given index, if that index is valid
870  void updateOutputFile(
871  int index,
872  const UT_StringHolder& path,
873  const UT_StringHolder& tag,
874  PDG_File::Hash hash_code,
875  bool owner);
876 
877  /// Returns the input files for immediate dependencies
878  void inputFiles(
879  PDG_File::Array& files,
880  bool include_expected) const;
881 
882  /// Returns all input files that are a substring-match for the given tag
883  bool inputFilesForTag(
884  PDG_File::Array& files,
885  const UT_StringHolder& tag,
886  bool include_expected = false) const;
887 
888  /// Checks if the work items output files are valid, e.g. they exist
889  bool validateOutputFiles();
890 
891  /// Transfers all dependent files to the remote directory, using the
892  /// supplied scheduler
893  bool transferFiles(bool update_cache);
894 
895  /// Clears all output files
896  void clearOutputFiles();
897 
898  /// Clears expected outputs
899  void clearExpectedOutputFiles();
900 
901  /// Clears output files added during the cook. Note that this method is
902  /// only safe to call if the item has not yet been marked as cooked.
903  void clearRuntimeOutputFiles();
904 
905  /// Sets the clear environment flagging, effectively stopping any upstream
906  /// env vars from being considered beyond this work item
907  void clearEnvironment();
908 
909  /// Adds an environment variable and value to this work items env var map
910  bool addEnvironmentVar(
911  const UT_StringHolder& var_name,
912  const PDGT_Value& value,
913  UT_WorkBuffer& errors);
914 
915  /// Returns true if the work item has the specified env var
916  bool hasEnvironmentVar(
917  const UT_StringHolder& var_name) const;
918 
919  /// Globs the full set of environment variables for this work item by
920  /// searching through it's parents.
921  void globEnvironment(
922  PDGT_Value::Map& environment) const;
923 
924  /// Looks up a key in the environment, returns true if the key exists
925  bool envLookup(const char* key,
926  PDGT_Value& value) const;
927 
928  /// Adds a warning to the owning node
929  void addNodeWarning(
930  const UT_StringHolder& message) const;
931 
932  /// Starts cooking a sub item in a batch, and optionally waits for it to
933  /// be available. Returns false if the item cannot start due to a failure.
934  bool startSubItem(bool wait, UT_WorkBuffer& errors);
935 
936  /// Returns true if the sub item is ready
937  bool checkSubItem(UT_WorkBuffer& errors);
938 
939  /// Marks a work item is cooking, updates it cook start time, and prints
940  /// log messages.
941  bool startWorkItem();
942 
943  /// Marks the work item as cooked, if it is an in-process batch item
944  bool cookSubItem(
946  fpreal duration);
947 
948  /// Returns the scheduler associated with the work item, looked up from the
949  /// work item's node.
950  PDG_Scheduler* scheduler() const;
951 
952  /// Returns true if the work item is schduled by the specified schduler
953  bool isScheduledBy(PDG_Scheduler* scheduler) const;
954 
955  /// Reports a performance monitor event for this work item
956  void performanceEvent() const;
957 
958  /// Sets a stat to the current time
959  virtual fpreal setTimeStat(PDG_WorkItemStats::StatType stat,
960  bool batched);
961 
962  /// Returns the perf stats object for the work item
963  const PDG_WorkItemStats& stats() const
964  { return myStats; }
966  { return myStats; }
967 
968  /// Replaces env vars in the target string with respect to the environment
969  /// and properties of this work item. If py_replace is true, replaces the
970  /// env vars with a valid python token instead of
971  void varReplace(const char* input,
972  UT_WorkBuffer& output) const;
973 
974  /// Saves the work item to a .json file or string
975  bool saveJSONFile(
976  const UT_StringHolder& path,
977  bool pretty_print,
978  bool global_attributes,
979  bool skip_defaults) const;
980  UT_StringHolder saveJSONString(
981  bool pretty_print,
982  bool global_attributes,
983  bool skip_defaults) const;
984 
985  /// Saves the work item to a UT_OptionsHolder
986  UT_OptionsHolder saveDict(
987  bool global_attributes,
988  bool skip_defaults) const;
989 
990  /// Saves the array of work items to a .json file or string
991  static bool saveArrayJSONFile(
992  const UT_StringHolder& path,
993  const PDG_WorkItemArray& items,
994  bool pretty_print,
995  bool global_attributes,
996  bool skip_defaults);
997  static UT_StringHolder saveArrayJSONString(
998  const PDG_WorkItemArray& items,
999  bool pretty_print,
1000  bool global_attributes,
1001  bool skip_defaults);
1002 
1003  /// Saves the list of work items to a UT_OptionsHolder
1004  static UT_OptionsHolder saveArrayDict(
1005  const PDG_WorkItemArray& items,
1006  bool global_attributes,
1007  bool skip_defaults);
1008 
1009  /// Loads a work item from a .json file or string
1010  static PDG_WorkItem* loadJSONFile(
1011  const UT_StringHolder& path,
1012  bool make_active,
1013  UT_WorkBuffer& errors);
1014  static PDG_WorkItem* loadJSONString(
1015  const UT_StringHolder& data,
1016  bool make_active,
1017  UT_WorkBuffer& errors);
1018 
1019  /// Creates a JSON patch from the work item as a string
1020  UT_StringHolder createJSONPatch(bool pretty_print) const;
1021 
1022 protected:
1023  friend class PDG_BatchWorkItem;
1024  friend class PDG_Scheduler;
1025  friend class PDG_WorkItemHolder;
1026  friend class PDG_WorkItemDirty;
1027 
1028  /// Dirties or deletes the work item and propogates the necessary changes
1029  /// to downstream items and dependents.
1030  void prepareDirty(PDG_WorkItemDirty& dirty_state,
1031  bool is_delete,
1032  bool is_dirty_data) const;
1033 
1034  /// Applies a dirty operation that was stored to the dirty state
1035  void applyDirty(
1036  const PDG_WorkItemDirty& dirty_state,
1037  bool remove_outputs);
1038 
1039  /// Runs custom dirty handlers and deletes output files
1040  void handleDirty(
1041  const UT_ArrayStringSet& keep_set,
1042  bool should_delete,
1043  bool remove_outputs);
1044 
1045  /// Returns the list of files owned by this work item
1046  void ownedFiles(
1047  PDG_File::Set& files,
1048  bool include_expected) const;
1049 
1050  /// Updates the file cache of this work item so the ID is at least as
1051  /// large as the input ID
1052  void updateCacheId(PDG_CacheID cache_id);
1053 
1054 
1055  /// Called when one of the dependencies owned by this work item
1056  /// is resolved.
1058  PDGE_Resolutions& resolutions,
1059  const PDGE_Evaluator& evaluator,
1060  PDGE_Dependency* dependency) override;
1061 
1062  /// Called when one of the dependencies owned by this work item
1063  /// is unresolved;
1064  int evalUnresolve(
1065  PDGE_Dependency::Array& extras,
1066  PDGE_Dependency* dependency) override;
1067 
1068  /// Called when an item is about to be scheduled, to check if it has
1069  /// cached outputs on disk. Returns Uncooked if the item is not cached
1070  /// and should cook, Failure if the read files mode fails, or CookedCache
1071  /// if the item is cooked from cache.
1072  virtual PDG_WorkItemState checkCached(bool add_outputs);
1073 
1074  /// Upgrades expected outputs to runtime outputs for this work item
1075  bool upgradeExpectedOutputFiles(
1076  bool check_disk,
1077  bool clear);
1078 
1079  /// Called by the scheduler to mark out of process items as cooked
1080  void postCook(PDGE_Resolutions& resolutions,
1082  int batch_index,
1083  fpreal duration,
1084  bool notify_all,
1085  bool static_cook,
1086  bool unresolve);
1087 
1088  /// Notifies this work item that is has cooked.
1089  virtual void notifyCook(PDGE_Resolutions& resolutions,
1091  int batch_index,
1092  fpreal duration,
1093  bool notify_all,
1094  bool static_cook,
1095  bool unresolve);
1096 
1097  /// Syncs a work item's cache with its dependents
1098  virtual void syncCacheId();
1099 
1100  /// Does an inprocess cook of the work item, returning true on success
1101  bool cook();
1102 
1103  /// Internal method for setting the frame
1104  virtual bool setFrameInternal(
1105  fpreal frame,
1106  fpreal frame_step,
1107  bool check_dirty,
1108  bool emit);
1109 
1110  /// Adds a parent and copies attributes by inheriting them from the parent
1111  /// of another work item. This is used for generating dynamic sub items
1112  /// in a batch, and copying the parent information from the last batch
1113  /// item onto the new item
1114  void inheritParent(const PDG_WorkItem* work_item);
1115 
1116 private:
1117  /// Removes all dependencies from the work item, and removes them work item
1118  /// from the dependents list of all dependencies
1119  void removeAllDependencies();
1120 
1121  /// Updates the dependency state, given the incoming state
1122  void updateDependencyState(
1123  PDG_WorkItemState dep_state);
1124 
1125  /// Returns a copy of the dependencies in an array, and filters out
1126  /// work items from the target node
1127  void upstreamDependencies(
1128  PDG_WorkItemConstArray& dependency_array) const;
1129 
1130  /// Helper method to query the list of failed upstream dependencies
1131  void failedDependencies(
1132  PDG_WorkItemConstArray& dependencies,
1133  PDG_WorkItemIDSet& visited) const;
1134 
1135  /// Called before the work item is scheduled
1136  bool prepareTask();
1137 
1138  /// Called when a work item should be scheduled for execution
1139  PDG_WorkItemState schedule();
1140 
1141  /// Appends a log message with a time stamp and a new line
1142  void appendLogPrefix(
1143  bool timestamp,
1144  int verbosity,
1145  const UT_StringHolder& prefix,
1146  const UT_StringHolder& msg) const;
1147 
1148  /// Appends a format string to the work item's log
1149  template <typename... Args>
1150  void appendLogFmt(
1151  bool timestamp,
1152  int verbosity,
1153  const UT_StringHolder& prefix,
1154  const char* fmt,
1155  Args&&... args) const
1156  {
1158  message.format(
1159  fmt, std::forward<Args>(args)...);
1160  appendLogPrefix(
1161  timestamp,
1162  verbosity,
1163  prefix,
1164  message.buffer());
1165  }
1166 
1167  /// Processes this work item as a priority boost dep
1168  void processBoostDependency(PDG_WorkItemSet& deps);
1169 
1170  /// Gathers the input dependencies from priority boosting
1171  void gatherBoostDependencies(PDG_WorkItemSet& deps);
1172 
1173 protected:
1176 
1178 
1182 
1184 
1186 
1189 
1192 
1194 
1197 
1199  int myIndex;
1204 
1211 
1213 
1214  bool myHasFrame:1;
1215  mutable bool myHasWarnings:1;
1216 
1217  bool myAttributesDirty:1;
1218  bool myWasModified:1;
1219  bool myDidCook:1;
1220 
1221  bool myIsPostCook:1;
1222  bool myIsStatic:1;
1223  bool myIsNoGenerate:1;
1224  bool myIsCloneOutputFiles:1;
1225  bool myIsFrozen:1;
1226  bool myIsBatchReady:1;
1227 };
1228 
1229 #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:683
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:696
GLboolean * data
Definition: glcorearb.h:131
void addErrorFmt(const char *fmt, Args &&...args) const
Definition: PDG_WorkItem.h:624
GLsizei const GLfloat * value
Definition: glcorearb.h:824
int index() const
Returns the work item index.
Definition: PDG_WorkItem.h:231
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: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:622
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
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:667
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.
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:132
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: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:716
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.
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: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:638
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:278
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:652
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:618
PDG_WorkItemStats & stats()
Definition: PDG_WorkItem.h:965
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
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:963
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:7905
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
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
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
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