AGX Dynamics 2.42.3.0
Loading...
Searching...
No Matches
Job.h
Go to the documentation of this file.
1/*
2Copyright 2007-2025. Algoryx Simulation AB.
3
4All AGX source code, intellectual property, documentation, sample code,
5tutorials, scene files and technical white papers, are copyrighted, proprietary
6and confidential material of Algoryx Simulation AB. You may not download, read,
7store, distribute, publish, copy or otherwise disseminate, use or expose this
8material unless having a written signed agreement with Algoryx Simulation AB, or having been
9advised so by Algoryx Simulation AB for a time limited evaluation, or having purchased a
10valid commercial license from Algoryx Simulation AB.
11
12Algoryx Simulation AB disclaims all responsibilities for loss or damage caused
13from using this software, unless otherwise stated in written agreements with
14Algoryx Simulation AB.
15*/
16
17#ifndef AGX_JOB_H
18#define AGX_JOB_H
19
20#ifdef _MSC_VER
21# pragma warning(push)
22# pragma warning(disable:4355) // Disable warnings about passing the 'this' pointer to base class constructors.
23# pragma warning(disable: 6011) // Disable warningC6011: dereferencing nullptr pointer
24#endif
25
26#include <agx/agxCore_export.h>
27#include <agx/IndexRange.h>
28#include <agx/Callback.h>
29
30#include <agxData/Type.h>
31#include <agx/Vector.h>
32#include <agx/Timer.h>
34#include <agx/SyncTag.h>
35#include <deque>
36
37
38
39
40namespace agx
41{
42 class Device;
43 class Task;
44 class Thread;
45
46 typedef class Job* JobPtr;
47
48
50 typedef std::deque<class Job *> JobPtrQueue;
51
52 class RangeJob;
54
61 {
62 public:
63 Job();
64 Job(const Job& other);
65 Job(const Callback& callback, agx::UInt32 costEstimate = 100);
66 virtual ~Job();
67
68 Job& operator=(const Job& other);
69
71 void init(const Callback& callback = Callback(), agx::UInt32 costEstimate = 100);
72
77 void addDependency(Job *parent);
78
83 void removeDependency(Job *parent);
84
89 bool hasDependency(Job *parent);
90
95 void removeAllDependencies();
96
101 void clearChildDependencies();
102
107 void setNumDependencies(agx::UInt32 numDependencies);
108
112 agx::UInt32 getNumDependencies() const;
113
117 void incrementNumDependencies(agx::UInt32 size = 1);
118
122 void decrementNumDependencies(agx::UInt32 size = 1);
123
127 const JobPtrVector& getChildDependencies() const;
128
132 const JobPtrVector& getParentDependencies() const;
133
137 void setCallback(const Callback& callback);
138
142 const Callback& getCallback() const;
143
149 bool resolve();
150
154 void spawn();
155
159 Thread *getTargetThread();
160
164 void setTargetThread(Thread *thread);
165
169 Task *getTask();
170
174 void setTask(Task *task);
175
179 SyncTag *getSyncTag();
180
184 void setSyncTag(SyncTag *tag);
185
189 Real getExecutionTime() const;
190
194 const Timer& getTimer() const;
195
199 void setCostEstimate(agx::UInt32 cost);
200
204 agx::UInt32 getCostEstimate() const;
205
209 Thread *getAssignedThread();
210
211
215 agx::UInt32 getTag() const;
216
220 void setTag(agx::UInt32 tag);
221
225 void setName(const char *name);
226
230 const char *getName() const;
231
232
236 agx::Index& index();
237 const agx::Index& index() const;
238
239 public:
240
244 virtual void implementation();
245
246 private:
251 void execute(JobPtrVector& resolvedChildren, Thread* thread);
252
253 protected:
254 friend class Thread;
255 friend class JobGroup;
256
257 const char *m_name;
263 std::atomic<Int32> m_dependencyCounter;
267 SyncTagRef m_syncTag;
271 };
272
274
275 //---------------------------------------------------------------
276
282 {
283 public:
285
286 public:
287 RangeJob();
288 RangeJob(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement = 1);
289 RangeJob(const RangeJob& other);
290 virtual ~RangeJob();
291
292 void init(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement = 1);
293 void init(const IndexRange& range, agx::UInt32 costPerElement = 1);
294
295 RangeJob& operator= (const RangeJob& other);
296
300 IndexRange& range();
301 const IndexRange& range() const;
302
303 protected:
304 virtual void implementation() override;
305
306 private:
307 // void dispatch();
308
309 protected:
312 };
313
315
316 //---------------------------------------------------------------
317
318 template <class T>
319 class RangeJobT : public RangeJob
320 {
321 public:
322 RangeJobT();
323 RangeJobT(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement = 1);
324 RangeJobT(const RangeJobT<T>& other);
325
326 virtual ~RangeJobT();
327
328 protected:
329 virtual void implementation() override;
330 };
331
332 //---------------------------------------------------------------
333
339 {
340 public:
341 JobGroup();
342 virtual ~JobGroup();
343
344 void init();
345
346 void addJob(Job *job);
347 const JobPtrVector& getSubJobs() const;
348
349 // void execute();
350
351 protected:
352 virtual void implementation() override;
353
354 private:
355 JobPtrVector m_jobs;
356 };
357
358 //---------------------------------------------------------------
359
364 {
365 public:
367 virtual ~WaitJob();
368
372 void wait();
373
377 void release();
378
382 Job *getTarget();
383 const Job *getTarget() const;
384
385 private:
386 Job *m_target;
387 Block m_block;
388 };
389
390 //---------------------------------------------------------------
391
396 {
397 public:
398 TaskJob();
399 TaskJob(Task *task);
400 virtual ~TaskJob();
401
402 void init(Task *task);
403 void init();
404
405 void execute();
406
407 private:
408 Task *m_target;
409 };
410
411
412
413
414
415 /* Implementation */
416
419 Callback(&Job::spawn, this),
420 m_name(""),
421 m_numDependencies(0),
422 m_dependencyCounter(0),
423 m_task(nullptr),
424 m_targetThread(nullptr),
425 m_assignedThread(nullptr),
426 m_cost(0),
427 m_tag(0),
428 m_index(InvalidIndex)
429 {
430 }
431
433 Callback(&Job::spawn, this),
434 m_name(other.m_name),
435 m_children(other.m_children),
436 m_parents(other.m_parents),
437 m_callback(other.m_callback),
438 m_timer(other.m_timer),
439 m_numDependencies(other.m_numDependencies),
440 m_dependencyCounter(other.m_dependencyCounter.load()),
441 m_task(other.m_task),
442 m_targetThread(other.m_targetThread),
443 m_assignedThread(other.m_assignedThread),
444 m_syncTag(other.m_syncTag),
445 m_cost(other.m_cost),
446 m_tag(other.m_tag),
447 m_index(other.m_index)
448 {
449 }
450
451
452
453 AGX_FORCE_INLINE Job::Job(const Callback& callback, agx::UInt32 costEstimate) :
454 Callback(&Job::spawn, this),
455 m_name(""),
456 m_callback(callback),
457 m_numDependencies(0),
458 m_dependencyCounter(0),
459 m_task(nullptr),
460 m_targetThread(nullptr),
461 m_assignedThread(nullptr),
462 m_cost(costEstimate),
463 m_tag(0),
464 m_index(InvalidIndex)
465 {
466 }
467
469 {
470 m_name = other.m_name;
471 m_children = other.m_children;
472 m_parents = other.m_parents;
473 m_callback = other.m_callback;
474 m_timer = other.m_timer;
477 m_task = other.m_task;
480 m_syncTag = other.m_syncTag;
481 m_cost = other.m_cost;
482 m_tag = other.m_tag;
483 m_index = other.m_index;
484
485 return *this;
486 }
487
488 AGX_FORCE_INLINE const char *Job::getName() const { return m_name; }
489 AGX_FORCE_INLINE void Job::setName(const char *name) { m_name = name; }
490
494 AGX_FORCE_INLINE void Job::setTask(Task *task) { m_task = task; }
496 AGX_FORCE_INLINE void Job::setSyncTag(SyncTag *tag) { m_syncTag = tag; }
498
501
502
504 {
505 agxAssert(parent);
506 // agxAssert(!parent->m_children.contains(this));
507 parent->m_children.push_back(this);
509 #ifdef AGX_DEBUG
510 m_parents.push_back(parent);
511 #endif
512 }
513
514
516 {
517 agxAssert(parent);
518 // agxAssert(parent->m_children.contains(this));
519 if (parent->m_children.findAndErase(this)) {
521 #ifdef AGX_DEBUG
523 #endif
524 }
525 }
526
527
529 {
530 agxAssert(parent);
531 return parent->m_children.contains(this);
532 }
533
535
537 AGX_FORCE_INLINE void Job::setNumDependencies(agx::UInt32 numDependencies) { m_numDependencies = numDependencies; }
539 {
541 #ifdef AGX_DEBUG
543 #endif
544 }
545
549
551
552 AGX_FORCE_INLINE void Job::setCallback(const Callback& callback) { m_callback = callback; }
554
555
556 AGX_FORCE_INLINE void Job::init(const Callback& callback, agx::UInt32 costEstimate)
557 {
558 this->setNumDependencies(0);
560
561 #ifdef AGX_DEBUG
563 #endif
564
565 m_callback = callback;
566 m_cost = costEstimate;
567 m_targetThread = nullptr;
568 m_assignedThread = nullptr;
569 m_tag = 0;
570 m_index = 0;
571 }
572
574 AGX_FORCE_INLINE const Timer& Job::getTimer() const { return m_timer; }
577
580
581
583
584 AGX_FORCE_INLINE JobGroup::JobGroup() // : Job(Callback(&JobGroup::execute, this))
585 {
586 }
587
589 {
590 // Job::init(Callback(&JobGroup::execute, this));
592 m_jobs.clear();
593 m_cost = 0;
594 }
595
597 {
598 m_jobs.push_back(job);
599 m_cost += job->getCostEstimate();
600 }
601
603 {
604 return m_jobs;
605 }
606
607
608
610 AGX_FORCE_INLINE RangeJob::RangeJob() // : Job(Callback(&RangeJob::dispatch, this))
611 {}
612
613 AGX_FORCE_INLINE RangeJob::RangeJob(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement) // : Job(Callback(&RangeJob::dispatch, this))
614 {
615 this->init(callback, range, costPerElement);
616 }
617
618 AGX_FORCE_INLINE RangeJob::RangeJob(const RangeJob& other) : Job(other) // : Job(Callback(&RangeJob::dispatch, this))
619 {
620 *this = other;
621 }
622
624 {
625 this->init(other.m_rangeCallback, other.m_range);
626 return *this;
627 }
628
631
632
633 AGX_FORCE_INLINE void RangeJob::init(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement)
634 {
635 m_range = range;
636 m_rangeCallback = callback;
637
638 Job::init(Callback(), (agx::UInt32)m_range.size() * costPerElement);
639 }
640
641 AGX_FORCE_INLINE void RangeJob::init(const IndexRange& range, agx::UInt32 costPerElement)
642 {
643 m_range = range;
644 Job::init(Callback(), (agx::UInt32)m_range.size() * costPerElement);
645 }
646
648
649 template <class T>
651 {}
652
653 template <class T>
654 AGX_FORCE_INLINE RangeJobT<T>::RangeJobT(const RangeCallback& callback, const IndexRange& range, agx::UInt32 costPerElement)
655 : RangeJob(callback, range, costPerElement)
656 {}
657
658 template <class T>
660 {}
661
662 template <class T>
664 {
665 }
666
667 template <class T>
669 {
670 agxAssert(dynamic_cast<T *>(m_task));
671 static_cast<T *>(m_task)->dispatch(*this);
672 }
673
675 AGX_FORCE_INLINE TaskJob::TaskJob() : Job(Callback(&TaskJob::execute, this)), m_target(nullptr)
676 {
677 }
678
679 AGX_FORCE_INLINE TaskJob::TaskJob(Task* task) : Job(Callback(&TaskJob::execute, this)), m_target(task)
680 {
681 }
682
684 {
686 m_target = task;
687 }
688
690 {
692 }
693
695
697 AGX_FORCE_INLINE const Job *WaitJob::getTarget() const { return m_target; }
698
699}
700
702AGX_TYPE_BINDING(agx::RangeJob, "RangeJob")
703AGX_TYPE_BINDING(agx::JobGroup, "JobGroup")
704AGX_TYPE_BINDING(agx::TaskJob, "TaskJob")
705
706
707#ifdef _MSC_VER
708# pragma warning(pop)
709#endif
710
711#endif /* _AGX_JOB_H_ */
#define AGX_TYPE_BINDING(_Type, _Name)
Definition: Type.h:179
#define AGXCORE_EXPORT
Block synchronization primitive.
Templated callback with one argument.
Definition: Callback.h:101
Generalized callback, using std::function.
Definition: Callback.h:54
T size() const
Definition: IndexRange.h:167
A group of jobs to be executed.
Definition: Job.h:339
JobGroup()
Definition: Job.h:584
void init()
Definition: Job.h:588
virtual ~JobGroup()
const JobPtrVector & getSubJobs() const
Definition: Job.h:602
virtual void implementation() override
Job implementation, override in subclass.
void addJob(Job *job)
Definition: Job.h:596
An abstract job/workblock representation, which allows work threads to execute arbitrary tasks.
Definition: Job.h:61
void setTask(Task *task)
Set the task which the job belongs to.
Definition: Job.h:494
void removeDependency(Job *parent)
Remove a dependency from a job.
Definition: Job.h:515
Job()
Definition: Job.h:418
agx::UInt32 getCostEstimate() const
Definition: Job.h:575
bool hasDependency(Job *parent)
Definition: Job.h:528
void setNumDependencies(agx::UInt32 numDependencies)
Explicitly set the number of parent dependencies.
Definition: Job.h:537
Real getExecutionTime() const
Definition: Job.h:573
void spawn()
Schedule job for execution in thread pool.
Task * m_task
Definition: Job.h:264
agx::UInt32 getNumDependencies() const
Definition: Job.h:546
agx::UInt32 m_tag
Definition: Job.h:269
Timer m_timer
Definition: Job.h:261
Thread * getTargetThread()
Definition: Job.h:491
Job & operator=(const Job &other)
Definition: Job.h:468
Task * getTask()
Definition: Job.h:493
const Timer & getTimer() const
Definition: Job.h:574
void addDependency(Job *parent)
Add a dependency to a job.
Definition: Job.h:503
Callback m_callback
Definition: Job.h:260
const char * m_name
Definition: Job.h:257
SyncTag * getSyncTag()
Definition: Job.h:495
JobPtrVector m_children
Definition: Job.h:258
void setTargetThread(Thread *thread)
Set the target thread which the job will be executed on.
Definition: Job.h:492
agx::UInt32 getTag() const
Definition: Job.h:499
agx::Index m_index
Definition: Job.h:270
Thread * m_targetThread
Definition: Job.h:265
JobPtrVector m_parents
Definition: Job.h:259
const JobPtrVector & getChildDependencies() const
Definition: Job.h:550
void setTag(agx::UInt32 tag)
Set the job tag, can be used to keep track of different job classes etc.
Definition: Job.h:500
SyncTagRef m_syncTag
Definition: Job.h:267
void setCostEstimate(agx::UInt32 cost)
Specify the cost estimate for this job.
Definition: Job.h:576
std::atomic< Int32 > m_dependencyCounter
Definition: Job.h:263
void decrementNumDependencies(agx::UInt32 size=1)
Explicitly decrement the number of parent dependencies.
Definition: Job.h:548
virtual void implementation()
Job implementation, override in subclass.
const char * getName() const
Definition: Job.h:488
const Callback & getCallback() const
Return the current callback.
Definition: Job.h:553
void init(const Callback &callback=Callback(), agx::UInt32 costEstimate=100)
Initialize the job.
Definition: Job.h:556
void incrementNumDependencies(agx::UInt32 size=1)
Explicitly increment the number of parent dependencies.
Definition: Job.h:547
void clearChildDependencies()
Remove all child dependencies.
Definition: Job.h:536
void removeAllDependencies()
Remove all parent dependencies.
Definition: Job.h:538
Thread * m_assignedThread
Definition: Job.h:266
void setName(const char *name)
Set the name of the job, for debugging.
Definition: Job.h:489
agx::UInt32 m_cost
Definition: Job.h:268
bool resolve()
Increase the dependency counter for the job, and queue job for execution if all dependencies are reso...
void setSyncTag(SyncTag *tag)
Set the synchronization tag which must enter completion status before the job is executed.
Definition: Job.h:496
const JobPtrVector & getParentDependencies() const
Definition: Job.h:534
virtual ~Job()
void setCallback(const Callback &callback)
Set the callback which is called when execute() runs.
Definition: Job.h:552
agx::Index & index()
Definition: Job.h:578
Thread * getAssignedThread()
Definition: Job.h:497
agx::UInt32 m_numDependencies
Definition: Job.h:262
virtual ~RangeJobT()
Definition: Job.h:663
RangeJobT()
Definition: Job.h:650
virtual void implementation() override
Job implementation, override in subclass.
Definition: Job.h:668
A range job executes a kernel implementation on a subset of the data.
Definition: Job.h:282
void init(const RangeCallback &callback, const IndexRange &range, agx::UInt32 costPerElement=1)
Definition: Job.h:633
virtual void implementation() override
Job implementation, override in subclass.
RangeCallback m_rangeCallback
Definition: Job.h:310
virtual ~RangeJob()
IndexRange m_range
Definition: Job.h:311
RangeJob()
Definition: Job.h:610
IndexRange & range()
Definition: Job.h:629
RangeJob & operator=(const RangeJob &other)
Definition: Job.h:623
A task job is a job which executes an agx::Task.
Definition: Job.h:396
TaskJob()
Definition: Job.h:675
void init()
Definition: Job.h:689
virtual ~TaskJob()
void execute()
A representation of a generic task.
Definition: Task.h:57
agx::Thread is a representation of an OS specific implementation of a computational thread.
Definition: Thread.h:199
The Timer class permits timing execution speed with the same refinement as the built in hardware cloc...
Definition: Timer.h:62
Real64 getTime() const
Report total elapsed time since start in milliseconds, excluding intervals when the timer was suspend...
Definition: Timer.h:191
Vector containing 'raw' data.
Definition: agx/Vector.h:246
void push_back(const T &value)
Definition: agx/Vector.h:1362
bool contains(const T2 &element) const
Test if the vector contains a certain element.
Definition: agx/Vector.h:1452
bool findAndErase(const T &element, bool searchMultiple=false)
Find and erase an element.
Definition: agx/Vector.h:1478
void clear(ClearPolicy policy=SHRINK_BUFFER_AVERAGED)
Remove all elements, optionally with maintained buffer allocation.
Definition: agx/Vector.h:1149
Templated vector class.
Definition: agx/Vector.h:53
A job used as a synchronization utility when waiting for another job to complete.
Definition: Job.h:364
virtual ~WaitJob()
void release()
Release the waiting thread.
Job * getTarget()
Definition: Job.h:696
void wait()
Blocks until the targeted job is completed.
WaitJob(Job *job)
#define agxVerify(expr)
Definition: debug.h:131
#define agxAssert(expr)
Definition: debug.h:143
#define AGX_FORCE_INLINE
Definition: macros.h:58
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
uint32_t UInt32
Definition: Integer.h:32
Vector< RangeJob > RangeJobVector
Definition: Job.h:314
Vector< Job > JobVector
Definition: Job.h:273
double Real
Definition: Real.h:41
VectorPOD< class Job * > JobPtrVector
Definition: Job.h:49
std::deque< class Job * > JobPtrQueue
Definition: Job.h:50
AGXCORE_EXPORT const InvalidIndexStruct InvalidIndex
agx::Callback1< const RangeJob & > RangeCallback
Definition: Job.h:53
void AGXPHYSICS_EXPORT init()
Initialize AGX Dynamics API including thread resources and must be executed before using the AGX API.
class Job * JobPtr
Definition: Job.h:46
UInt32 Index
Definition: Integer.h:44